You are on page 1of 142

Curso práctico de

actualización a

Enero 2018

Copyright  GeneXus S.A. 1988-2018.


All rights reserved. This document may not be reproduced by any means without the express permission of GeneXus S.A.The information contained herein
is intended for personal use only.

Registered Trademarks:
GeneXus is trademark or registered trademark of GeneXus S.A. All other trademarks mentioned herein are the property of their respective owners.
CONTENIDO

CONTENIDO............................................................................................................................................................. 2

OBJETIVO................................................................................................................................................................. 5

COMENCEMOS ........................................................................................................................................................ 5

MÓDULOS EN GENEXUS 15 .................................................................................................................................. 5

BUSINESS COMPONENTS ................................................................................................................................... 19

POBLADO DE TRANSACCIONES ......................................................................................................................... 25

TRANSACCIONES DINÁMICAS ............................................................................................................................ 26

WEB – USANDO LAS TRANSACCIONES DINÁMICAS ....................................................................................... 30

WEB - CARMINE Y NUEVO DISEÑO DEL WORK WITH FOR WEB .................................................................... 32

WEB - CALLOPTIONS TARGET ............................................................................................................................ 35

WEB - NAVIGATION BAR ...................................................................................................................................... 39

WEB - GLOBAL EVENTS ....................................................................................................................................... 44

WEB - CONTROL HORIZONTAL GRID ................................................................................................................ 47

WEB - TAB CONTROL Y COMPONENTES .......................................................................................................... 49

WEB - INFINITE SCROLLING ................................................................................................................................ 54

SD - APLICACIÓN ANDROID ................................................................................................................................ 56

2
SD - LIVE EDITING ................................................................................................................................................. 58

AGREGANDO DISEÑO CON LIVE EDITING ......................................................................................................... 64

SD - CONTROL HORIZONTAL GRID ................................................................................................................... 67

SD COMPONENTS Y GLOBAL EVENTS .............................................................................................................. 69

SD – COMPARTIR INFO MEDIANTE ALGUNA DE LAS APPS INSTALADAS EN EL DISPOSITIVO (SHARE


EO)........................................................................................................................................................................... 72

SD - AUDIO CONTROLLER Y COLAS DE REPRODUCCIÓN .............................................................................. 73

SD – DESPLEGAR PANTALLA A LA DERECHA: CALLOPTIONS Y NAVIGATION EO ...................................... 80

SD – PULL TO REFRESH ...................................................................................................................................... 81

REPORTING (OPCIONAL)..................................................................................................................................... 82

Card: Qry Conferences.............................................................................................................. 82

Card: QryLikes .......................................................................................................................... 83

Chart: QryLikesChart ................................................................................................................ 85

Pivot: QryLikesPivot ................................................................................................................. 87

TimeLine: QryLikesTimeline ...................................................................................................... 87

WEB Y SD - DEPLOYMENT DE EVENTDAY ......................................................................................................... 89

CLOUD DEPLOY .................................................................................................................................................... 91

Parte 1 - GeneXus Cloud en el IDE de GeneXus 15. .................................................................... 91

Parte 2 - Consola de GeneXus Cloud. ........................................................................................ 96

Parte 3 (Opcional) - Restore de binarios de una aplicación. ....................................................... 99

En la consola de GeneXus Cloud:.................................................................................................. 100

TRABAJANDO EN EQUIPO CON GENEXUS SERVER 15 (OPCIONAL) .......................................................... 101

3
¿QUÉ ES GENEXUS SERVER? ................................................................................................... 101

PRÁCTICO .............................................................................................................................. 102

Paso 1: Publicación Inicial (Mary) ........................................................................................... 103

Paso 2: Crear KB desde GeneXus Server (Diego) ...................................................................... 106

Paso 3: Creación de objetos y primer Commit (Mary) .............................................................. 110

Paso 4: Update desde GeneXus Server (Diego) ........................................................................ 112

Paso 5: Manejo de conflictos (Mary) ....................................................................................... 116

Paso 6: Update desde GeneXus Server y modificación de objetos (Diego) ............................... 122

Paso 7: Blame (Mary) ............................................................................................................. 124

Paso 8: Commit Parcial y ChangeSet (Diego) ........................................................................... 126

Paso 9: Interacción con la Consola y Activity Tab (Mary) ......................................................... 137

4
OBJETIVO

Conocer las principales nuevas funcionalidades de GeneXus 15 para desarrollar aplicaciones Web y
Smart Devices (SD). Opcionalmente se verá lo nuevo en Reporting. Luego, cómo resolver el deploy
de la aplicación desarrollada, tanto en servidores locales como en la nube en producción. Dejamos
un práctico al final, que por razones de tiempo no podrá realizarse dentro de este curso pero que
podrá probar cuando lo desee para conocer las nuevas funcionalidades para el trabajo en un
equipo de desarrollo con GeneXus Server.

La aplicación sobre la que trabajaremos es EventDay, utilizada para el seguimiento de las charlas
(sessions) y oradores (speakers) de un evento (tal como el encuentro GeneXus). Se partirá de una
KB en GeneXus Server, ya inicializada con objetos que implementan app Web y SD.

COMENCEMOS

Utilizaremos la versión GeneXus 15, en su último upgrade liberado, el browser Chrome y el


Emulador de Android SDK. Opcionalmente usted puede contar con otro emulador, como el
genymotion, o incluso podrá probar directamente en su dispositivo.

Este práctico se elaboró con el upgrade 8.

MÓDULOS EN GENEXUS 15

Comience por crear una KB desde cero. La intención es observar todo lo que viene inicializado por
defecto.

5
Observar el IDE. Existe una nueva sección KB Explorer (sustituyendo a Folder View). La primera cosa
que podemos ver es un módulo Root, y a continuación un nodo References:

Si expandimos ambos nodos:

6
Podemos ver que el módulo Root viene con un folder GeneXus, y el nodo References con un
módulo GeneXus, que contiene submódulos y Domains. ¿Qué es este módulo GeneXus? Para
descubrirlo, acceda a la propiedad Module Description de este módulo. Dice: “GeneXus Core
Module is a basic set of interfaces and implementations of data structures and algorithms to solve
common programming use cases.”

¿Por qué todos los objetos y submódulos contenidos son read-only?

Observe que dentro de la propiedad Module Manager Information del módulo se le muestra la
versión.

7
Abra alguno de los procedimientos del módulo (por ejemplo el de nombre AddDeviceGroups del
módulo Notifications). Puede hacerlo a través del buscador de objetos en el KB Explorer, “Open:”.
¿Por qué no puede ver el Source del procedimiento?

Si quisiera instalarse otra versión de este módulo, ¿cómo lo hace?

Cree un módulo Lib donde desarrollará funciones utilitarias para la aplicación, como un
procedimiento para acortar un string y uno para formatear un DateTime.

Cree ambos procedimientos dentro del módulo, con las siguientes Rules, Variables y Source:

Procedure TruncateString:

parm( in:&LongString, in:&CharCount, out:&ShorterString );

Variables:

&LongString: Varchar(1024)
&CharCount: SmallInt = Numeric(4.0) /*con la asignación se definirá el nuevo dominio
SmallInt. Observe que en la definición del tipo de datos aparecerá “SmallInt, Lib” */
&ShorterString: Varchar(256)

Source:

&Diff = &LongString.Length() - &CharCount


if &Diff > 0
&TextLen = &CharCount - 3
&ShorterString = substr(&LongString,1,&TextLen) + !"..."
else
&ShorterString = &LongString.Trim()
endif

8
Procedure: FormatDateTime

parm(in:&DateTime, in:&FormatName, out:&DateString);

Variables:

&DateTime: DateTime
&FormatName: Character(100)
&DateString: String = VarChar(255) /*con la asignación se definirá el nuevo dominio String.
Observe que en la definición del tipo de datos aparecerá “String, Lib” */
&Date: Date

Source:

do case
case &FormatName = !'ddd hh:mm'
&DateString = &DateTime.DayOfWeekName() + ' ' +
padl(&DateTime.Hour().ToString().Trim(), 2,'0') + ':' +
padl(&DateTime.Minute().ToString().Trim(), 2,'0')
case &FormatName = !'hh:mm'
&DateString = padl(&DateTime.Hour().ToString().Trim(), 2,'0') + ':' +
padl(&DateTime.Minute().ToString().Trim(), 2,'0')
otherwise
&DateString = &DateTime.ToFormattedString()
endcase

Observe que al definir los dominios se creó un nodo Domains dentro del módulo Lib.

9
La ventana Domains permite visualizar los dominios de otro módulo, así como de todos los
módulos (elija *ALL en el combo). Observe que hasta el momento los únicos dominios editables
son los que acaba de crear.

Posiciónese en el nodo del módulo Lib, botón derecho, Open:

Pruebe cambiarle la propiedad Object Visibility a FormatDateTime, por Private. Grabe, vuelva a
abrir la Interface del módulo Lib y observe cómo ya no aparece como servicio. Vuelva a dejar la
propiedad como estaba (con Object Visibility Public).

Creemos un web panel “Test” para testear los procedimientos:

10
Pruébelo (consulte al instructor sobre si utilizar la opción Deploy to Cloud o prototipar local). Si lo
creó dentro del módulo, entonces deberá lograr que su visibilidad no sea “Public”. Querremos
empaquetar el módulo para distribuirlo a otras KBs. Como ese web panel tiene master page,
quítesela para poder empaquetarlo. De lo contrario, tendrá que colocar también la Master Page
dentro del módulo.

Ahora querremos empaquetar el módulo para poder instalarlo en otras KBs sin que los
desarrolladores de esas KBs puedan modificar los objetos. Lo ideal sería probar las funcionalidades
en todos los environments para los que desee que el módulo pueda utilizarse. Nosotros hemos
probado únicamente con un environment .Net. Pero debería definir todos los environments para
los que quiera obtener binarios y marcarlos (con los check boxes) para distribuirlos. No lo haremos
en este práctico.

11
Al presionar OK, se hará un rebuild de todos los objetos para cada environment seleccionado, y
luego creará un paquete que contendrá los binarios. Observe que quedará en:

"<Knowledge Base Directory>\modules\Lib_1.0.opc"

opc: Open Packaging Convention. Es un archivo zip. Si lo extrae, podrá ver que dentro del folder
Platforms/CSharpWeb contiene Lib.dll.

CREATE KNOWLEDGE BASE FROM GENEXUS SERVER

Ahora cree desde GeneXus Server una Knowledge Base a partir de la KB de nombre EventDay15 del
server de samples (samples.genexusserver.com/v15/main.aspx).

Observe en las Preferences que tiene dos environments. Setee como activo el CloudNet. Consulte al
instructor acerca de si prototipará en la nube o en forma local. Configure lo que el instructor le
indique y realice un Rebuild all para que se actualice el módulo GeneXus en caso de ser necesario
(en la KB del Server está el del upgrade 8 de GeneXus 15). Mientras se realiza, siga leyendo este
documento.

12
En esta KB se crearon folders y objetos para el desarrollo de la app web, incluyendo queries para
reporting, así como folders y objetos para el desarrollo de la app móvil nativa.

Empezaremos con la aplicación web. Esta consiste


tanto en el desarrollo de un backend, como de un
frontend.

Observe que bajo el Root Module se organizaron los


objetos en folders.

 En el DataModel encontrará las transacciones,


los objetos resultantes de la aplicación del pattern Work
with (tanto para Web como para Smart Devices), Data
Providers asociados a las transacciones y algunos
procedimientos.

 En el folder Backend encontrará la master page


default, y otros objetos, pero no el principal, pues éste
será el Home que viene por defecto en el folder Web
(cuando se le aplica el patrón Work With for Web a las
transacciones). Lo hemos personalizado, como
apreciará si lo abre.

 En el folder FrontEnd encontrará una master


page diferente, creada para los objetos de la app para
los usuarios finales. El objeto principal de la app del
FrontEnd será el panel Sessions.

13
Antes de seguir, asegúrese de tener el environment .Net correctamente configurado como
environment activo. Observe que tiene creado también el generador de Smart Devices. Deshabilite
la generación iOS, pues solo prototiparemos para Android, haciendo uso del emulador. Realice un
Ctrl+F5 cuando el Rebuild all haya concluido.

Observe que se ha mejorado la ventana Output de GeneXus con nueva font y un nuevo “find”
incorporado, que muestra los resultados de la búsqueda resaltados.

Como no hemos configurado a nivel de la versión un Startup Object, la ventana de Output mostrará
un error para la ejecución de Android.

No le prestaremos atención mientras desarrollemos la parte web. Como vamos a estar alternando
entre backend y frontend, no configuraremos Startup Object.

Se abrirá el DeveloperMenu:

14
Backend: Ejecute el panel Home para acceder al backend. Observe todos los “trabajar con”
(sessions, speakers, tracks, favorites, countries, rooms, companies, eventpreferences –settings-).
Además aparecen invocaciones a otras pantallas (bajo “Other functionalities”) que veremos luego.

15
Frontend: Luego ejecute el main del Frontend (el panel Sessions).

16
Navegue un poco por la app para familiarizarse con lo implementado.

Vuelva a GeneXus y observe el folder Lib bajo Root Module. No tiene nada que ver con el módulo
que usted ha creado y empaquetado. Es un folder que los desarrolladores de esta KB han creado
por su cuenta. Pero si busca en el KB Explorer a través del campo Open un objeto de nombre
“TruncateString”, lo encontrará. ¡Los desarrolladores de esta KB lo habían implementado! Ábralo.
Está programado casi idéntico al que usted creó en el módulo que empaquetó.

Ubíquelo en el árbol del KB Explorer. Para ello recuerde hacer botón derecho sobre el objeto
abierto / Locate in KB Explorer:

Luego, haciendo botón derecho / References, observe qué objetos están utilizando la función. Será
el web component SessionsComponent, que a su vez es parte del objeto Sessions y además el
objeto de Smart Devices WorkWithDevicesSession.

Ubique el componente web SessionsComponent dentro de la app del frontend en ejecución.

Abra en GeneXus SessionsComponent y encuentre entre los eventos la invocación al procedimiento


TruncateString.

17
Antes de seguir, observe que bajo el nodo References sólo se encuentra el módulo GeneXus:

Ahora importe el módulo que empaquetó hace un rato en la otra KB.

¿Dónde debe quedar ubicado en el KB Explorer?

Abra el procedimiento TruncateString de este módulo y observe que es read-only y que no aparece
la sección Source, ni Layout, ni Conditions.

Nota: los binarios del módulo serán copiados al directorio del target environment en tiempo de
build.

18
Recuerde que no habrá conflicto con las funciones del mismo nombre de esta KB, pues los objetos
de los módulos tienen un qualified name.

Si ahora usted quiere pasar a utilizar las funciones de este módulo y no las que se definieron
especialmente en esta KB, ¿cómo debe modificar las invocaciones?

Respuesta: en SessionsComponent cambie:

TextDesc.Caption = TruncateString(SessionDescription, 145)

Por:

TextDesc.Caption = Lib.TruncateString(SessionDescription, 145)

Ejecute (haciendo Run sobre el web panel Sessions). Puede cambiar la cantidad de caracteres para
truncar el string, para que pueda apreciar cómo efectivamente se está utilizando la función del
módulo Lib.

Nota: Podría hacer lo mismo con el otro objeto que utilizaba la función TruncateString, el
WorkWithDevicesSession, nodo List. Pero todavía no ejecutaremos la app SD, así que por el
momento no lo haremos.

BUSINESS COMPONENTS

Se desea implementar un web panel para el backend que permita modificar todas las conferencias
(sessions) que iban a realizarse en una sala, de modo que se realicen en otra.

Observe que ya se ha creado con el nombre ReplaceRoomInSessions, y es invocado desde el web


panel Home:

Se ha diseñado su Web Form con dos combos dinámicos para las variables &RoomFrom y
&RoomTo, based on RoomId. Usted deberá programar el evento asociado al botón. Observe que

19
además se ha agregado un componente que muestra todas las sessions por room de acuerdo a los
datos actuales. Dentro del evento deberá refrescar ese componente.

Una posible solución:

Definir un Data Provider ChangeSessionsRoom en el folder Backend, que devuelva una colección de
Business Component Session con RoomId cambiado por el nuevo. Pruebe no definirlo desde el principio,
sino hacerlo desde el código del evento ‘ReplaceInSessions’:

20
Event 'ReplaceInSessions'
&sessions = ChangeSessionsRoom( &RoomFrom, &RoomTo )
if &sessions.Count > 0
if &sessions.Update()
Commit
msg( 'The replacement has been successfully completed' )
Component1.Refresh()
else
Rollback
for &session in &sessions
if not &session.Success()
for &message in &session.GetMessages()
msg( &message.Description )
endfor
endif
endfor
endif
else
msg("There wasn't sessions in " + find( RoomName, RoomId = &RoomFrom) +
"room. No changes were made.")
endif
Endevent

21
Observar que el Data Provider ChangeSessionsRoom sólo devuelve cargados SessionId y RoomId. El resto de
los campos vacíos, dado que utilizaremos el método Update, que únicamente necesita el Id (para
internamente hacer un Load en variable auxiliar) y los campos a ser modificados. Los demás quedarán como
estaban.

Pruebe su solución en ejecución. Hay más soluciones. Si usted pensó otra, discuta en qué se
diferencia con la aquí presentada. ¿Utilizó el método Update o el Save? ¿Utilizó el método Load?

También puede brindar la alternativa de, si la nueva sala no estaba ingresada al sistema, ingresarla
antes. Para ello se ha creado el web panel ReplaceRoomInSessions2.

En el Form se insertaron, además de los combos, una variable &Room de tipo de datos el Business
Component Room.

Programe el código asociado al botón y desde Home invoque a este web panel en lugar de al
anterior.

22
Observe que la transacción Room tiene regla de error para que no pueda quedar una sala sin
nombre en el sistema. Testee en ejecución intentando dejar vacíos los campos &RoomTo y
&Room.RoomName.

Una posible solución:

Event 'ChangeSessions'
&continue = True
if &RoomTo.IsEmpty()
&continue = &Room.Insert()
If &continue
&RoomTo = &Room.RoomId
&RoomFrom.Refresh()
else
msg( &Room.GetMessages().ToJson())
endif
endif
If &continue
&sessions = ChangeSessionsRoom( &RoomFrom, &RoomTo )
if &sessions.Count > 0
if &sessions.Update()
Commit
msg( 'The update has been successfully completed' )
Component1.Refresh()
else //some update for a session has failed
for &session in &sessions
if not &session.Success()
msg( &session.GetMessages().ToJson())
endif
endfor
Rollback
endif
else
msg("There wasn't sessions in " + find( RoomName, RoomId = &RoomFrom) + "room. No
changes were made")
endif
endif
Endevent

¿Y si ahora lo que queremos es sustituir a un orador por otro en todas las conferencias que el
primero tuviera asignadas?

Observe que el Home permite invocar a un panel ReplaceSpeakerInSessions, para cambiar un


orador.

23
Deberá, como antes, programar el evento asociado al botón.

Una posible solución:

Event 'Replace in Sessions'


&ok = True
for each Session.Speaker
where SpeakerId = &SpeakerOld
&Session.Load(SessionId)
&Session.Speaker.RemoveByKey(&SpeakerOld)
&SessionSpeaker = new()
&SessionSpeaker.SpeakerId = &SpeakerNew
&Session.Speaker.Add(&SessionSpeaker)
If not &Session.Update()
for &message in &Session.GetMessages()
msg( &message.Description)
endfor
&Ok = False
endif
when none

24
msg( 'The Speaker to be replaced was not in any Session')
&ok = False
endfor
if &ok
msg( 'The replacement has been successfully completed' )
commit
Component1.Refresh()
else
rollback
endif
Endevent

Observaciones: Como SpeakerId es parte de la clave primaria del segundo nivel del Session, no puede
cambiarse. Hay que eliminar ese speaker para la session e ingresar el nuevo. Observe que para eliminar
líneas no tenemos más alternativa que utilizar el método Load para cargar la Session y luego el método de
las líneas RemoveByKey. En este caso da lo mismo utilizar el método Save o el Update, porque el Update de
todos modos hará un Save, y no creará una variable auxiliar, dado que ya sabe que la variable &session está
en update, por el uso del método Load.

POBLADO DE TRANSACCIONES

Observe que bajo el folder DataModel se encuentran las transacciones que se están utilizando. Si
observa cualquiera de ellas, por ejemplo, Country, verá entre sus propiedades que las del grupo
Data se modificaron prendiendo la propiedad Data Provider:

Y que esto hizo que bajo el nodo Country en el KB Explorer apareciera un Data Provider:

Si lo abre verá que allí se especificaron los datos con los que se quiso inicializar la tabla asociada.
Esto fue todo lo que tuvo que hacer el desarrollador.

Gracias a estos Data Providers es que usted ya vio la app con datos desde el principio.

25
TRANSACCIONES DINÁMICAS

La particularidad de las Transacciones Dinámicas es que no provocarán la creación de tablas


físicas sino vistas para recuperar los datos en tiempo de ejecución a partir de lo que definamos en
un Data Provider. Esto nos permite resolver muchos y muy variados escenarios de consultas.

Veámoslo en un ejemplo práctico. Tenemos la transacción FavoriteSessions que registra por


dispositivo las conferencias marcadas como favoritas:

El usuario marca en la app del frontend las conferencias favoritas cuando desde las sessions hace
clic sobre el ícono de corazón. Allí se invoca al procedimiento ToggleFavorite que es el que
efectivamente inserta esa conferencia en la tabla de FavoriteSessions:

Ábralo y observe cómo lo hace. Observe que se utiliza el objeto externo ClientInformation (read
only) del módulo GeneXus para obtener el dispositivo web (navegador) o SD que está ejecutando.
Por más información: https://wiki.genexus.com/commwiki/servlet/wiki?20198

26
Bien, una vez comprendido esto, lo que ahora se desea es consultar el ranking de conferencias que
más han sido seleccionadas como favoritas (desde los distintos dispositivos).

La información que necesitamos está en la tabla asociada a la transacción FavoriteSessions. Aquí


queremos contar por cada session marcada como favorita, cuántos dispositivos la seleccionaron.

¿Por qué no tener una transacción dinámica que corresponda a esta información?

Para ello creamos la transacción FavoritesStatistics, que registrará las conferencias marcadas
como favoritas, registrando cuántas veces cada una ha sido favoriteada:

Para indicar que la transacción es dinámica, debemos configurar las siguientes propiedades:

27
Como no queremos actualizar información a través de la transacción, dejamos la propiedad
Update Policy con su valor default para Retrieve data que es “Read Only”.

Al grabar el objeto, si lo observamos en el KB Explorer (podemos hacer botón derecho  Locate in


KB Explorer, y mover la transacción para el folder DataModel si ya no la habíamos creado allí),
vemos que se ha creado automáticamente un data provider asociado a la transacción dinámica:

Modifiquemos el data provider para personalizar cómo deseamos cargar nuestra transacción
dinámica. Descomentemos el código. Ahora, ¿cómo programa lo deseado?

Aquí una solución.

El Source quedaría:

FavoritesStatisticsCollection
{
FavoritesStatistics from FavoriteSessions unique SessionId
{
FavoritesSessionId = SessionId
FavoritesSessionName = SessionName
FavoritesSessionDate = SessionInitialDate
FavoritesSessionCount = count(EventDeviceID)
}
}

Grabemos el data provider, y hagamos un impacto (Build  Impact Database Tables):

28
Observemos el diagrama de impacto, donde se indica que la transacción es dinámica, y la
sentencia para crear la vista en el SQL Server en vez de crear una tabla:

Nota: en el upgrade 8 en el que se probó este práctico y se capturó la pantalla están apareciendo
las demás tablas porque informa que debe ejecutar los data providers para poblar las tablas. No
debería hacerlo, pues esas tablas no se han tocado, pero internamente GeneXus entiende que sí.

Haga clic en “Reorganize” para que la vista sea creada en la base de datos.

29
WEB – USANDO LAS TRANSACCIONES DINÁMICAS

Ahora, para completar el requerimiento pedido –consultar el ranking de conferencias más


favoriteadas–, simplemente utilizaremos los atributos de la transacción como lo solemos hacer.
Crearemos en el folder Backend un web panel FavoriteSessionsRanking, con un grid que contenga
los atributos de nuestra transacción dinámica:

Asignaremos el valor “(FavoritesSessionCount)” a la propiedad Order del grid, para indicar que
queremos ver primero las conferencias con más votos:

30
Desde el botón “Work With Favorite Sessions” invocamos al WWFavoriteSessions() que muestra los
favoritos de cada dispositivo. Y desde el Home del backend cambiamos la invocación de Favorites,
para que ahora invoque al web panel que acabamos de crear, FavoriteSessionsRanking, en lugar de
invocar al Work with.

Ejecutemos el Home y accedamos a Favorites:

31
En el Panel for Smart Devices PopulateSessions se utiliza de manera similar la transacción
dinámica para mostrar las sessions más favoriteadas. Ábralo y descomente el código del Load,
pues ahora ya existen los atributos FavoritesSessionId y FavoritesSessionName. Más adelante
probará este panel en ejecución.

WEB - CARMINE Y NUEVO DISEÑO DEL WORK WITH FOR WEB

Carmine es el nuevo theme utilizado por defecto en las KBs creadas con la versión 15 de GeneXus
para aplicaciones Responsive (RWD). Con el uso de Carmine, además de utilizar nuevos colores en
tonos de rojos, se cuenta con un nuevo y más moderno diseño de los objetos generados por el
pattern Work With for Web.

Observaremos estas novedades en ejecución. Pero antes acceda a las propiedades de la versión
(en Preferences) y observe bajo el grupo User interface / Web interface los defaults:

32
Ejecute el Home de la aplicación del backend (que como verá tiene configurado como theme
Carmine), opción “Sessions”.

Pruebe achicar el tamaño de la ventana del browser.

33
Observar cómo automáticamente se van
‘eliminando’ columnas a medida que se va haciendo
menos ancha la ventana. Y vuelven a aparecer a
medida que se agranda.

Observar cómo desaparece el caption “Insert” del


botón al cambiar el tamaño de la pantalla. Y aparece

sólo el

Observar cómo se genera un nuevo botón para

acceder a los filtros

Responsive sizes:

El Carmine por defecto viene sólo configurado para tres tamaños (no considera el Medium) por
tanto si quisiéramos considerar el Medium, es necesario agregar la regla y configurar los tamaños
respectivos. Así lo hemos hecho en el theme. Obsérvelo. Así quedaron las reglas:

Min Width Max Width

Extra Small 767

Small 768 991

Medium 992 1199

(Large queda automático) 1200 & up

34
Con estos tamaños, si queremos ver rápidamente en el browser los diferentes tipos de pantalla
podemos usar la ‘Device Toolbar’ de chrome (o equivalente en otros browsers) y elegir Iphone 5
(Extra Small), Ipad Portrait (Small), Ipad Landscape (Medium) y volviendo al desktop normal (Large)

WEB - CALLOPTIONS TARGET

No vamos a hacerlo en el práctico, pero usted puede verlo en la KB.

El panel que muestra las conferencias más populares está hecho de esta forma –cuando estamos
en una visualización small, el panel de favoritos aparece como una barra flotante, mientras que
cuando estamos en pantalla grande (desktop) el panel está fijo a la derecha.

Smaill:

35
36
Large:

37
Esto se logra con la configuración de la sub clase ResponsiveSlide de la clase NavigationStyle en el
Theme (observe que para los objetos del FrontEnd creamos otro theme, a partir del Carmine. Se
llama CarmineFrontEnd).

Y en el evento Start de la Master Page del FrontEnd se hizo:

38
WEB - NAVIGATION BAR

En la versión 15, los Action Groups permiten crear fácilmente una “navigation bar” en Web. Para
verlo en ejecución, ejecute el web panel Sessions (botón derecho sobre él  Run).

Abra la master page de este objeto (RWDMPEventDay). Y observe el menú:

Observe en el evento Start cómo se programaron los links de cada opción.

39
Veamos ahora cómo crear un menú como ese, pero para la página Home del Backend, que
permitirá invocar al Work With de Sessions, Speakers y Tracks.

Abrir la master page del backend (RwdMasterPage) y hacer clic en la barra gris, en la flechita a la
izquieda y seleccionar “Add Action Group”:

Configuremos las propiedades Control Name = Menu, Caption = <vacío> y Control Type = Menu:

Insertemos un Textblock en el action group, haciendo botón derecho:

40
Configuremos las siguientes propiedades del Textblock:

Repitamos la operación para los Textblocks Speakers y Tracks, de forma que el action group quede
de la siguiente forma:

Grabemos el objeto, y hagamos clic en el form, en, por ejemplo, el <ContentPlaceHolder>. Luego
desde la Toolbox (donde vemos que aparece ahora un grupo Action Groups), arrastremos el action
group Menu a nuestro form, ubicándolo en la misma tabla que el <ContentPlaceHolder>:

41
En el evento Start de la master page, agregaremos los links de cada text block:

Sessions.Link = WWSession.Link()
Speakers.Link = WWSpeaker.Link()
Tracks.Link = WWTrack.Link()

Ejecutemos el web panel Home y observemos cómo aparece una barra de navegación con los
ítems que agregamos:

42
Cambiemos las dimensiones del browser, y observemos cómo cuando la pantalla del dispositivo es
pequeña, la barra de navegación aparece colapsada, y cómo al hacer clic sobre ella aparecen las
opciones en forma vertical:

43
Como el menú se configuró a nivel de la Master Page, entonces lo verá en todas las páginas del
backend, que tienen a ésta como su Master Page. Obsérvelo invocando a Sessions. Verá que
aparece el mismo menú.

WEB - GLOBAL EVENTS

Global Events es una nueva funcionalidad muy potente, que permite que una acción en un Web
Component (también valdrá para componentes SD, como veremos luego) dispare una acción en
cualquier otro Web Component de nuestro formulario.

Supongamos que queremos tener en la Master Page del FrontEnd un Web Component donde
mostremos la cantidad de conferencias que el usuario ha seleccionado como favoritas.

44
Lo ideal sería que el componente se actualizara a medida que el usuario marca o desmarca una
conferencia como favorita, sin necesidad de refrescar todo el formulario. Esto es posible utilizando
Global Events. Veamos cómo.

Abra el external object Global Events (observe que no se encuentra dentro del módulo GeneXus,
dado que deberá poder ser modificado por el desarrollador) y agregue un evento
UpdateFavoritesQuantity:

Y grabe el objeto. Ahora llamaremos al evento global recién creado desde el objeto donde el
usuario selecciona o deselecciona una conferencia como favorita.

Abra el web component SessionsComponent, y en el evento imgToggleFavorite.Click, agregue la


línea marcada en negrita:

Event imgToggleFavorite.Click
&IsFavorite = ToggleFavorite(&SessionId)
if &IsFavorite
imgToggleFavorite.FromImage(BtnFavSelec)
else
imgToggleFavorite.FromImage(FavNo)
endif
GlobalEvents.UpdateFavoritesQuantity()
Endevent

De esta manera, cada vez que el usuario marque/desmarque una session como favorita se estará
disparando el evento, que será escuchado por todo objeto que lo maneje (es decir, que lo tenga
definido entre sus eventos).

Observemos que a la master page RWDMPEventDay le hemos agregado en el layout un control


component de nombre FavoritesQty:

45
Nos hace falta solamente cargarlo con el web component FavoriteCount (abrirlo y observar que
cuenta y muestra la cantidad de sessions favoritas), para lo que en el evento Refresh de la master
page agregamos la línea en negrita:

Event Refresh
WCRecentLinks.Object = RwdRecentLinks.Create(Form.Caption, ContentHolder.Pgmname)
FavoritesQty.Object = FavoriteCount.Create()
EndEvent

Lo que queremos es que cuando un panel o componente dispara el evento global


UpdateFavoritesQuantity, este web component FavoriteCount actualice la cuenta.

Para ello alcanza con que programemos en su sección de eventos el evento global:

Event GlobalEvents.UpdateFavoritesQuantity()
do 'GetCount'
EndEvent

Ejecute el web panel Sessions, y observe cómo se muestra en la parte superior derecha de la
master page el componente, y cómo se actualiza al seleccionar o deseleccionar conferencias como
favoritas:

46
WEB - CONTROL HORIZONTAL GRID

El control Horizontal Grid nos permite visualizar los elementos de una lista de forma horizontal en
vez del clásico grid con filas.

Actualmente los Speakers se visualizan en una grilla vertical, pero queremos lograr que se
visualicen de la siguiente manera:

Para ello abra el web panel SpeakersPanel, y seleccione el grid GridSpeakers:

47
Cambie el valor de la propiedad “Custom Render” a “HorizontalGrid”:

Grabe el objeto, y vuelva a ejecutar el web panel Sessions

Veremos que en ejecución ahora la lista de oradores es mostrada de forma horizontal, y vamos
cambiando la información desplegada utilizando el controlador de página, ubicado en la parte
inferior

48
WEB - TAB CONTROL Y COMPONENTES

Veremos a continuación un nuevo control para aplicaciones Web, que permite desplegar un
conjunto de controles agrupados en diferentes tabs.
Actualmente estamos mostrando las conferencias por día, con una grilla que carga los diferentes
días:

Pero queremos lograr que los días se visualicen de la siguiente forma, sabiendo que el evento
siempre se desarrollará en tres días, más allá de sus fechas: lunes, martes y miércoles:

49
¿Cómo lo implementa?

Abra el web panel Sessions, elimine la grilla y arrastre un control Tab desde la Toolbox al Web
Form:

50
Observe el control que aparece ahora por debajo del Componente:

51
Arrastre ahora el control Component sobre la página TabPage1 del control Tab:

Seleccione la página TabPage2 del control, y arrastre desde la Toolbox un control Web Component
sobre el control Tab. Verifique que la propiedad Control Name del Web Component quede con el
valor Component2. Repita la operación para página TabPage3, verificando que el Web Component
quede con nombre Component3.

Seleccione la página TabPage1 y asigne el valor Monday a la propiedad Caption:

52
Repita la operación para las otras dos páginas con los valores Tuesday y Wednesday.

¿Cómo modifica los eventos para que cada tab page cargue el componente con la fecha deseada?

Una posible implementación es eliminar los eventos que teníamos definidos y definir tres variables &date1,
&date2 y &date3 para obtener las fechas correspondientes a lunes, martes y miércoles del evento, y una
variable &i Numeric(1,0), y hacer:

Event Start
&i = 1
for each Session order SessionInitialDate
unique SessionInitialDate
do case
case &i = 1
&date1 = SessionInitialDate
case &i = 2
&date2 = SessionInitialDate
case &i = 3
&date3 = SessionInitialDate
endcase
&i+=1
endfor
Component1.Object = SessionsComponent.Create(&date1)
EndEvent

53
Event Tab1.TabChanged
do case
case Tab1.ActivePage = 1
Component1.Object = SessionsComponent.Create(&date1)
case Tab1.ActivePage = 2
Component2.Object = SessionsComponent.Create(&date2)
case Tab1.ActivePage = 3
Component3.Object = SessionsComponent.Create(&date3)
endcase
endevent

Ejecute el web panel Sessions, y observe cómo se visualiza el control Tab, y cómo es posible ver las
conferencias de cada día seleccionando cada una de las páginas:

WEB - INFINITE SCROLLING

Cuando se tienen varios registros en un grid, una opción a la paginación es el “Infinite Scrolling”.
Esto es que a medida que el usuario va haciendo scroll van apareciendo nuevos registros en la
grilla.

Veámoslo en el objeto WWSpeaker (backend). En ejecución actualmente se están viendo 10 filas


por páginas para la grilla:

54
Abrirlo y observar que el valor de la propiedad Rows es 0. Al cambiarlo a 5 se habilita la propiedad
Paging y allí podemos cambiarla de “One page at a time” a:

Observar en ejecución que aparece una barra de scroll vertical en la grilla de los oradores, y que a
medida que se va haciendo scroll hacia abajo, van apareciendo más registros en la grilla:

55
SD - APLICACIÓN ANDROID

Ahora nos dedicaremos a familiarizarnos y ampliar las funcionalidades de la app SD que ya está
parcialmente desarrollada en esta KB.

Observar que se hemos agregado a la KB un theme específico para Android: EventGXAndroid. Si va


a SD Platforms / Any Android verá que se tiene configurado este theme. Cambie el tipo de
navegación por Slide.

56
Nota: A partir del upgrade 6 de GeneXus 15 se ha creado un nuevo theme default para aplicaciones
móviles: el CarmineSD, en dos variantes: CarmineAndroid y CarmineiOS, con variantes de rojo.
Pero, como siempre, usted deberá utilizar el theme que responda a los colores y demás
especificidades de la app que está desarrollando.

En las Preferences / SmartDevices, deshabilite, si no lo hizo antes, la generación para iOS.

Observe en el KB Explorer el folder SD. Allí aparecerá un Menu for Smart Devices (antiguo
Dashboard) de nombre EventDay. Haga botón derecho/Rebuild sobre él (si no hizo rebuild all al
comenzar el práctico; en caso contrario solamente haga botón derecho/Run). Luego Botón
derecho/ Run without building. Se le abrirá el emulador de Android, donde verá:

Navegue por la app. ¿Dónde se han configurado los colores de la application bar, de los íconos en
ella, de las acciones, del background de la app?

Respuesta: en la clase Application del theme. Observe sus propiedades.

En lo que sigue probaremos algunas de las nuevas features de la versión 15 realizando


modificaciones sobre los objetos que implementan esta app Android.

Los Work with se encuentran bajo las transacciones, en el folder DataModel.

57
SD - LIVE EDITING

¿Qué tal si pudiéramos cambiar el diseño de nuestras pantallas y -SIN generar- ver los cambios
directamente en nuestra aplicación SD?

Se implementó el “Live editing” y “Live Inspector” para lograr este objetivo y agilizar ampliamente el
diseño de la aplicación.

Veamos cómo se activa y cómo funciona.

Seleccionar el valor Live Editing en el combo en la barra de GeneXus. De esta manera nuestra
aplicación se mantendrá conectada con nuestro IDE.

Para activarlo, hay que cambiar el valor de este combo, configurando el valor “Live Editing”:

Hecho esto, ya podemos ejecutar nuestra aplicación. Dado que ahora vamos a estar desarrollando
y probando la app móvil, le convendrá configurar al Menu for Smart Devices EventDay como
Startup object, así el F5 hace un Run de él.

Se abrirá la app en el Emulador Android. Además, se abrirán dos ventanas:

 “Live Editing” mostrando el nombre del dispositivo que está ejecutando actualmente la app
–en este caso la instancia del emulador– y con el que se está conectado (vea el punto verde
que lo indica).
 “Live inspector” (activada gracias al check box de la ventana anterior) que permite analizar
en runtime la configuración de propiedades de cada ítem en un objeto con UI y modificarlas
para ver el resultado in-line, mejorando enormemente la productividad del desarrollador
comparando con GeneXus XEv3 (donde el desarrollador, para poder ver sus cambios,
necesariamente debía re-compilar la aplicación cada vez).

58
En el inspector se muestra la pantalla que está ejecutándose en ese momento dentro de la
aplicación (emulador) y podemos visualizar cómo se reflejan los cambios realizados en tiempo real.

Pruebe hacer clic, dejar presionado y mover el mouse. Verá que se le mostrarán las distintas capas
que conforman la pantalla del objeto que se está ejecutando:

59
Observar que lo que se haga en la app en el emulador, se reflejará en esta pantalla
automáticamente. Observe también que pasando el mouse sobre los distintos elementos, se le
informa de qué control se trata. Y si hace clic, se le muestra la info ampliada (objeto, control, clase y
subclases del theme, tamaño, posición):

60
Con el botón Reset puede volver a la visualización plana.

Ahora vaya a la app en el emulador, y cambie la pantalla. Por ejemplo, haga tap sobre la segunda
conferencia. Verá que automáticamente la ventana de Live Inspector le muestra esta pantalla
también.

61
Ahora veamos su utilidad.

Vuelva a visualizar el List de Sessions. (Si perdió la conexión haga Ctrl+F5 –Run without building–).
Dentro del Live Inspector haga clic en el tab posicionado debajo de la application bar:

Luego haga clic en el link donde aparece el nombre de la clase asociada al control, TabSessionList.
Observe la ventana de propiedades:

62
Se cargarán automáticamente las propiedades de la clase seleccionada.

Modifique la propiedad Tab Strip Background Color = #9E219E y visualizará los cambios tanto en el
emulador como en el Live Inspector:

El color del font del tab cuando está seleccionado y cuando no lo está hace que casi no se vean los
textos. Pruebe cambiar los colores por unos más contrastantes.

Solución: vuelva a hacer clic en el Live Inspector sobre el tab y ahora haga clic en la subclase
TabPageSelectedSession y luego en la TabPageUnselectedSession.

Por ejemplo, dejarlo en negro cuando está seleccionado el tab y en blanco cuando no lo está:

63
De esa forma, se pueden seguir modificando propiedades tanto del control como de la clase
asociada al control hasta lograr el diseño deseado y, recién en ese momento, grabar los cambios
realizados.

Antes de continuar, abra el objeto PopularSessions y descomente, si no lo hizo antes, el código del
evento Load (siempre y cuando haya definido en su KB la transacción dinámica FavoritesStatistics
que se le pedía mucho antes en este práctico). Ese panel es invocado desde la Action Bar del List de
Sessions, al hacer tap sobre la imagen de la estrella.

AGREGANDO DISEÑO CON LIVE EDITING

Si hacemos tap sobre una charla del List de Sessions se despliega su información. Al hacer tap en el
nombre del orador, se despliegan los datos del orador sin ningún tipo de diseño.

Vamos a modificar ese layout:

64
En el IDE, abra el objeto WorkWithDevicesSpeaker, Section (General), layout View.

Comenzamos colocando un Canvas al principio de la Tabla. Y al atributo SpeakerImage (que está


más abajo) lo arrastramos dentro del Canvas.

65
Ir observando en el emulador cómo van viéndose los cambios a medida que se hacen.

Intente que el layout le quede más o menos así (aunque la idea es que pruebe Live editing. Puede
intentar otro diseño de layout que le guste más):

Para que el resultado sea más o menos el que ve en pantalla: a la tabla canvas configúrele el Row
span en 3 y el Height en 100%.

66
A la imagen la clase ImageSpeakerMain, Auto Grow False y Absolute position:

 Top: 5dip
 Left: 50%
 Bottom: 100%
 Right: 50%
 Width: 100dip
 Height: 100dip
 Z-Order: 0

Para dejarle un margen izquierdo a los atributos, cuenta con la clase AttributeAttributeLeftMargin5.

Nota: si hubiera tenido que agregar un atributo que no se encontraba ya cargado, Live editing no lo
iba a ayudar e iba a tener que hacer un build. ¿Por qué?

SD - CONTROL HORIZONTAL GRID

El control Horizontal Grid nos permite visualizar los elementos de una lista de forma horizontal en
vez del clásico grid con filas.

Si ejecutamos el Menu for Smart Devices EventDay en el emulador, y vamos a SPEAKERS, veremos
la lista de oradores de la forma habitual:

67
Pero queremos verlos de esta otra forma:

Para ello:

68
Abra el objeto WorkWithDevicesSpeaker, y en el nodo List, seleccione el grid. Configure la propiedad
“Control Type” con el valor “SD Horizontal Grid”, así como las propiedades mostradas en la siguiente
imagen, que permiten controlar la cantidad de filas y columnas por página:

Pruébelo en ejecución.

SD COMPONENTS Y GLOBAL EVENTS

Deseamos modificar la forma en que se muestra el List de Sessions, de manera tal que cuando se
favoritea una conferencia en cualquiera de los tres días, se observe arriba el número total de
conferencias marcadas como favoritas por ese dispositivo (recuerde que habíamos implementado
esto mismo para el frontend web):

69
Una solución para no tener que modificar el layout del WorkWithDevicesSession ni el del panel
FavoritesCountSD (que cuenta y muestra los favoritos) es crear un panel nuevo y utilizar
componentes:

70
Recomendamos que la propiedad Rows Style de MainTable sea 35dip; 100%.

Con esta implementación conseguimos que se disparen los eventos ClientStart, Start, Refresh y
Load de este panel, e inmediatamente esos mismos eventos del componente 1 y luego los del
componente 2. Con eso quedará cargada la página como vimos antes.

Pero ahora queremos que si el usuario hace tap sobre la imagen de favoritos del List de Sessions
esto dispare el evento global que ya habíamos definido para Web:

Y que el panel for Smart Devices “escuche” este evento, para poder calcular nuevamente la
cantidad de favoritos y mostrarla.

Para lo primero, en el evento &Fav_Image.Tap del List de WorkWithDevicesSession habrá que


agregar la línea en negrita:

71
Event &Fav_Image.Tap
Composite
InOutFavoriteSession( SessionId )
GlobalEvents.UpdateFavoritesQuantity()
Refresh
endcomposite
Endevent

Y en el panel FavoritesCountSD agregar el evento:

Event GlobalEvents.UpdateFavoritesQuantity()
Do 'GetCount'
endevent

Modifique en el Menú EventDay la primera acción para que en lugar de invocar al List de sessions,
invoque a este nuevo panel:

Ejecute y pruebe.

Observe cómo la application bar se compone de la unión de ambas application bars (las de ambos
componentes. En nuestro caso, el primero está vacío, por lo que sólo se ven las acciones del
Workwith).

SD – COMPARTIR INFO MEDIANTE ALGUNA DE LAS APPS INSTALADAS EN EL DISPOSITIVO


(SHARE EO)

Si observa la información detallada de una conferencia, verá que se ha agregado a la action bar un
botón Share:

72
Si lo observa en GeneXus, verá que se ha programado el evento asociado a ese botón:

Event 'Share'
GeneXus.Social.Share.ShareText(SessionName, !"http://www.genexus.com",
SessionInitialDate.ToString())
Endevent

SD - AUDIO CONTROLLER Y COLAS DE REPRODUCCIÓN

En la versión GeneXus 15 se agregaron nuevos métodos, eventos y SDTs dentro de la api Audio que
nos ayudan a manejar las colas de reproducción. También se agregó un control Audio Controller
para brindar la posibilidad de personalizar el reproductor.

En nuestro ejemplo, los nuevos SDTs que utilizaremos son: el SDT MediaItem, que contiene la
información para cada audio y el SDT MediaQueue, que mantiene una lista de MediaItems, es decir,
la propia cola de reproducción.

Cada conferencia tiene ingresada en el atributo SessionAudio la url de un archivo mp3 con el audio
de esa conferencia. Observe que en la pantalla de Detail de la conferencia aparecerá un texto que,

73
dependiendo de si la conferencia está o no ingresada en su playlist, le permite agregarla o
eliminarla.

Nota al margen: observe que se debería cargar también un video en la pantalla. Si no se carga es que le faltó
agregar al objeto main (en nuestro caso el menú EventDay) la clave de Android Google Services API Key.

La Playlist es por dispositivo. Observe la transacción que almacena esa información:

El atributo PlayListId corresponderá al ClientInformation.Id.

74
Agregue algunas conferencias a la playlist del dispositivo marcándolas desde el Detail de cada una.

Luego acceda a la opción PlayList del menú:

Presione el botón Play de alguna de ellas y verá cómo comienza a reproducirse el audio. Esta
implementación corresponde a la versión anterior de GeneXus, cuando la api Audio no contaba
con las funcionalidades específicas para soportar colas de reproducción.

Abra el panel ShowPlayList donde se ha implementado lo anterior a través de un grid de tabla base
PlayList que carga todas las sessions que corresponden a PlayListId = ClientInformation.Id.

Nota: si el Build arroja un error indicando que se ha excedido en la cantidad de métodos, modifique la
propiedad Multidex Build del objeto main (en nuestro caso el menú EventDay) pasándola a True.

Observe cómo se implementó la reproducción y el stop utilizando la api Audio. Ábrala. Y note que
ahora se encuentran los nuevos métodos para colas, junto con SDTs:

75
El MediaQueue será una colección de MediaItem. Esos dos SDTs son los que le permitirán cargar los
datos de la cola de reproducción.

Querremos implementar lo mismo que hacíamos a mano en este panel, ahora a través de una cola
de audios.

Para ello:

Cree un panel AutomaticPlayList y en su layout arrastre el nuevo control AudioController desde la toolbox.

Y luego haga:

Event ClientStart
Composite
&mediaQueue = GetPlayQueue()
Audio.SetQueue(&mediaQueue)
endcomposite
Endevent

El procedimiento GetPlayQueue ya se le ofrece implementado en la KB. Observe que lo que hace es recorrer
la tabla PlayList y cargar un item en la cola por session de ese ClientInformation.Id:

76
Puede sustituir la invocación a ShowPlayList en el Menú EventDay por una invocación a este panel
AutomaticPlayList, o también podría agregar un componente en ShowPlayList al final del Layout:

77
Y que se cargue con el objeto AutomaticPlaylist.

Ejecute y pruebe. Presione play y verá cómo se le muestra la cola en modo “mini”, e incluso puede
manejarla desde otra app pues se le muestra entre las notificaciones. Y si maximiza la cola de
reproducción se le abrirá a pantalla completa el audio que se está reproduciendo y se le ofrecen los
botones para ir al anterior o siguiente.

78
¿Dónde se configuran los colores, tamaños, etc., de título, subtítulo, imagen, botones para el modo
“mini” y para el modo “full”?

Abra el theme (EventGXAndroid) y observe la propiedad AudioController:

Luego observe las propiedades de esas subclases.

79
SD – DESPLEGAR PANTALLA A LA DERECHA: CALLOPTIONS Y NAVIGATION EO

Si ahora deseamos que al presionar la imagen con la estrella en la application bar del List de
Sessions, en lugar de abrirse el panel con las sessions más populares en una pantalla
independiente, se abra a la derecha, ¿cómo lo realiza?

Respuesta:

Entre los eventos del WorkWithDevicesSession nodo List, agregar el ClientStart que se ejecutará una sóla vez,
cuando el objeto se abra, y luego, mientras se mantenga abierto no volverá a ejecutarse. Allí invocamos al
panel PopularSessions en la ventana de la derecha, que al principio permanecerá oculta.

Event ClientStart
Composite
PopularSessions.CallOptions.Target = !"Right"
PopularSessions()
endcomposite
Endevent

80
Y luego modificamos el envento ‘Fav’ asociado al botón con la estrella, para que al presionarlo se muestre
esa pantalla.

Event 'Fav'
Navigation.ShowTarget(!"right")
Endevent

SD – PULL TO REFRESH

Si elige ver los tweets en el menú, encontrará la funcionalidad de Pull to refresh en acción.

Abra el panel EventTweets y posicionándose en el grid. Vea la propiedad Pull To Refresh en True.
Observe también la propiedad Inverse Loading.

81
REPORTING (OPCIONAL)

En esta parte del práctico vamos a hacer un recorrido por los reportes que ya están implementados
en la KB. Consulte al instructor sobre si realizar este recorrido o pasar directamente al punto
siguiente, por razones de tiempo.

Todos los queries implementados tienen como objetivo formar parte de un dashboard de controles
con indicadores de análisis de los “likes” que los diferentes usuarios van dando a las conferencias
del evento.

CARD: QRY CONFERENCES

La consulta ‘Conferencias’ muestra en una tarjeta la cantidad de conferencias definidas en el


evento.

Este es un dato que –en nuestro caso– no varía con el tiempo por lo cual no se incluye la tendencia
(Include Trend=False) ni la información de variabilidad (sparkline, max and min).

Es la consulta más básica que sirve para mostrar información sumarizada (podría ser total de likes,
etc).

82
CARD: QRYLIKES

Muestra una tarjeta con la cantidad de likes en total que ha habido para todas las conferencias, y
como es un dato que puede ir variando con el tiempo muestra la tendencia de la última semana,
incluyendo información de variabilidad (sparkline, max, min).

83
Si vamos al tab Preview podemos ver cómo se va a ver la tarjeta en nuestra aplicación. La
visualización puede cambiarse vía los Themes, aunque en este caso estamos usando la
visualización por defecto

En la pestaña SQL Statement se puede ver la consulta que se va a ejecutar para obtener los datos.
En caso de tener temas de performance, es importante analizar la consulta para asegurarse que
esté haciendo un acceso razonable a la base.

84
CHART: QRYLIKESCHART

Muestra una tabla con los likes por conferencia en un periodo de tiempo:

85
En la vista previa, los valores de los parámetros se pueden especificar al definir los mismos, por
ejemplo, al realizar el ‘preview’ vamos a ver likes que sucedieron después del ‘2017-11-01’

86
PIVOT: QRYLIKESPIVOT

Es una consulta que muestra una tabla dinámica de likes por periodo de tiempo.

TIMELINE: QRYLIKESTIMELINE

Muestra la evolución de cantidad de likes a lo largo del tiempo. El timeline tiene funcionalidades
pre-definidas para comparar una tendencia con otro periodo de tiempo (i.e evento 2017 vs evento
2016, etc.), agrupar:

87
Poder visualizar la información en varios niveles: días, semanas, meses:

88
Y también se puede achicar/agrandar el periodo haciendo clic en la barra inferior.

La funcionalidad del preview es la misma que la que tendrán los controles en la aplicación web.

WEB Y SD - DEPLOYMENT DE EVENTDAY

Nota: en lo que sigue cuando se habla del main object SD “MainEventDay” en verdad se refiere a
“EventDay”

Si deseamos publicar EventDay, consta de los siguientes componentes a publicar

● Aplicación nativa en Smart Devices (Android o iOS), con servicios y metadatos


○ A partir de Main Object ‘MainEventDay’
● Backoffice Web
○ A partir de Main Object ‘Home’
● Página Web
○ A partir de Main Object ‘Sessions’

Armaremos un paquete de distribución con todos los componentes server-side, es decir los que se
instalarán en un IIS (Internet Information Services).

Para esto haremos lo siguiente

1. Ir a Build / Deploy Application


2. Clic en botón “Add...” y agregar los objetos MainEventDay, Home y Sessions
3. Clic en botón ‘Deploy’
(Notar que en forma predeterminada ya está seleccionado Local / IIS 8 or higher)
4. Ver resultado en consola de Output

89
Como resultado, quedó armado un paquete en \Deploy del directorio del modelo, que puede ser
distribuido a un IIS.

90
CLOUD DEPLOY

PARTE 1 - GENEXUS CLOUD EN EL IDE DE GENEXUS 15.

En esta parte veremos cómo trabajar con GeneXus Cloud desde el IDE de GeneXus. Inicialmente
haremos “F6” para publicar nuestra aplicación.

Luego veremos cómo GeneXus Cloud calcula la reorganización de la base de datos a ejecutarse en
el deploy.

1. Ir a GeneXus 15 y hacer “F6”:

● Ingresar credenciales de su GeneXus Account

● Es necesario indicarle a GeneXus Cloud dónde quiere usted publicar la aplicación y


con qué nombre. Ya tiene que haber sido previamente configurado el ambiente para

91
el deploy e ingresado en GeneXus Cloud. Para este laboratorio usaremos la cloud
Sandbox y el target NetSQL. El nombre de la aplicación debe ser único en el cloud ya
que ese va a ser el nombre de la webapp.
○ Name: CursoGX15<nombre>
○ Cloud: Sandbox
○ Target: NetSQL

● Revisar el output del deploy:

El deploy hacia producción tiene 5 pasos:

1. Validación. Se valida que el ambiente destino tenga configuraciones


compatibles con el origen.
2. Transferencia. Se sube un .zip con: los binarios de la aplicación, archivos
necesarios para correr la reorganización de la base de datos, paquete del
GAM (si fuera necesario), etc.

92
3. Salvado en sistema de control de versiones.
Se procesan los binarios, se suben al git y se modifican los archivos de
configuración.

4. Reorganización e inicialización de datos: Se ejecuta la reorganización de


datos y, de corresponder, la inicialización de datos de GAM y la de GXflow.

5. Publicación: Se publican los binarios en el o los ambientes de producción


correspondientes.

93
● Si el deploy es exitoso se muestran varios enlaces:

Por ahora utilizaremos solo el enlace “Startup Object”. Hacer clic en “Startup Object”. Se
abrirá el Web Panel Home en un navegador. Navegue por la aplicación recién publicada y
verifique si todo funciona correctamente.

2. Reorganizaciones.

Veremos cómo GeneXus Cloud se encarga de calcular correctamente la reorganización.

● Vaya a la transacción Speaker (Ctrl + O y buscar “Speaker”)


● Agregue el atributo: SpeakerEmail, type: Email,Genexus
● Haga F5, clic en “Reorganize” cuando lo pida y verifique que se haga correctamente
la reorganización de la base de datos y que haya agregado correctamente el
atributo en Speakers:

● Vaya a la transacción Company (Ctrl + O y buscar “Company”)


● Agregue el atributo: CompanyPhone, type: Phone,GeneXus
● Haga F5, clic en “Reorganize” cuando lo pida y verifique que se haga correctamente la
reorganización de la base de datos y que haya agregado correctamente el atributo en
Companies:

94
● Haga F6, con opción de Backup Database habilitado, ya que en caso de que por algún
motivo el deploy falle se puede hacer un rollback de la base de datos en producción.
● Verifica que el análisis de impacto sea correcto, que se modifican las tablas Speaker y
Company:

● Y en el output:

95
Entonces vemos cómo con GeneXus Cloud no necesitamos preocuparnos por la reorganización. Ya
que lo calcula automáticamente con respecto al último deploy activo. Esto nos garantiza estabilidad
y seguridad al momento de publicar nuestras aplicaciones en producción. Incluso si llega a fallar esa
reorganización, GeneXus Cloud tiene la capacidad de hacer el rollback para asegurarte que su
aplicación esté siempre funcionando correctamente.

PARTE 2 - CONSOLA DE GENEXUS CLOUD.

En esta parte del práctico veremos las funcionalidades de la consola de GeneXus Cloud.
Empezaremos con un vistazo general, veremos el versionado de una aplicación, y terminaremos
viendo los backups de la base de datos.

1. Vistazo general de la consola


● Acceda a la consola de GeneXus Cloud (cloudmanager.genexus.com) y loguéese con
su GeneXus Account.

96
● Vemos que se abre el dashboard de la Consola.

● En el panel de la izquierda va a encontrar un combo con las clouds activas para hacer
deploy.

● En los tabs centrales puede ver:


○ Applications: Aquí se muestran las aplicaciones ya publicadas.
○ Databases: Muestra las distintas bases de datos e indica qué aplicación tiene
asociada. También puede hacer backup o restore de cada base de datos.
○ Activity Details: Muestra los logs de los últimos deploys.

● También si usted tuviera una nube contratada vería:

97
○ Targets: Se puede ver sobre qué unit se puede hacer deploy, ingresar una
nueva y editarlas.
○ Users: Muestra los usuarios activos para hacer deploy en determinada cloud.

2. Historia de una aplicación


● Ir al tab Applications.
● En la aplicación deployada en Parte 1, seleccionar la fila de Main (no hacer clic sobre
el link de “Main”) e ir a History.
● Seleccionar Deployment # 2.
● Al hacer clic en Log, puede verse el log del Deploy. Presionamos Close y volvemos a
seleccionar Deployment # 2.
● Al hacer clic en Diff, pueden verse los binarios que se modificaron en dicho deploy (por
ejemplo el Company_DataProvider.xml y el Speaker_DataProvider.xml).
● Presionamos Close y volvemos a seleccionar Deployment # 2. La opción Restore se
verá más adelante.

3. Backups de bases de datos.

GeneXus Cloud da el servicio de backups de las bases de datos de las aplicaciones


publicadas. Al contratar este servicio se puede indicar la frecuencia de los backups y a qué
cuenta de AWS se suben los backups. En la consola se pueden visualizar los backups y hacer
restore. Para esto seleccionamos DataBases (Ir al tab Databases):

98
Aquí encontrará: El nombre de la Base de datos (con un GUID al final), la lista con los
últimos backups y las aplicaciones activas usando dicha base de datos.

● Buscar la base de datos que comience con el nombre de aplicación que publicaste en
parte 1.
● En Active in, seleccionar el branch Main y hacer clic en Backup.
● Verificar que el backup se haya creado exitosamente (a veces es necesario refrescar la
página).

4. Restore de bases de datos


● Ir al tab Data Bases.
● Buscar la base de datos que empiece con el nombre de aplicación que publicó en
parte 1.
● En Backups, hacer clic en el último backup y hacer clic en restore.
● Verificar que se haya hecho correctamente.

PARTE 3 (OPCIONAL) - RESTORE DE BINARIOS DE UNA APLICACIÓN.

Como no siempre lo que colocamos en producción le gusta a nuestros clientes tanto como a
nosotros, a veces rápidamente debemos ir atrás en una versión.

Para eso GeneXus Cloud ofrece una opción Restore –disponible hoy por hoy solamente cuando la
última versión desplegada no incluye una reorganización.

La opción Restore se ejecuta con el botón correspondiente que aparece disponible si se selecciona
en el Cloud Manager una versión desplegada (y entre la versión desplegada y la actual no hay
reorganización hecha.)

Para probarlo:

En el IDE de GeneXus:

1. Abrir WorkWithSession
2. Borrar la condition en el Work With Sessions:

99
3. Hacer F5 y probar que el buscador de Sessions no funciona:

4. Hacer F6, ir a la aplicación publicada por GeneXus Cloud y verificar que se realizó el cambio.

Entonces, para revertir este cambio podemos realizarlo desde la consola sin necesidad de hacerlo
en GeneXus.

EN LA CONSOLA DE GENEXUS CLOUD:


1. Ir a la consola (cloudmanager.genexus.com)
2. Seleccionar la aplicación que publicó y hacer clic en History.
3. Seleccionar el penúltimo deploy y hacer clic en Restore.
4. Ir a la URL de la aplicación deployada y verificar que funcione nuevamente.

100
Además, claro está, siempre está la opción de realizar los cambios en el propio GeneXus, y volver a
realizar un F6.

TRABAJANDO EN EQUIPO CON GENEXUS SERVER 15 (OPCIONAL)

El siguiente práctico está dirigido a quien no conoce GeneXus Server o a quien lo conoce pero no
las nuevas funcionalidades de la versión 15. Por razones de tiempo, no podrá realizarse este
práctico dentro de las horas de curso. Lo dejamos aquí como documentación, para que pueda
usted llevarlo a cabo en otro momento.

¿QUÉ ES GENEXUS SERVER?

GeneXus Server es una herramienta que facilita el trabajo en equipo.

El desarrollo de software es una actividad que generalmente se realiza en equipo, y por lo tanto
implica la necesidad de cierta interacción entre los desarrolladores. Sin embargo esta interacción no
se realiza en forma continua, pues cada desarrollador necesita de cierto tiempo, por ejemplo, para
implementar una nueva característica o para reparar algún error en el código. A su vez, es importante
poder realizar estas tareas en un ambiente aislado para no verse afectado por los constantes
cambios que pueden estar introduciendo los otros miembros del equipo.

Una vez que el desarrollador termina de hacer la tarea que tenía asignada, deberá integrar su trabajo
con el resto del equipo, tanto para añadir los cambios que haya realizado, como para recibir los
cambios que hayan introducido los otros desarrolladores.

Este ciclo se repite en forma constante para todos los miembros del equipo, y por tanto es necesaria
una herramienta que provea un ambiente aislado para cada desarrollador y que también brinde un
servicio de comunicación para integrar su trabajo con los demás.

GeneXus Server provee ambas funcionalidades, permitiendo que cada desarrollador trabaje en su
propia copia local de la base de conocimiento, que a su vez está asociada a una copia central de la
misma base de conocimiento en la cual se integra el trabajo de todos los desarrolladores.

101
PRÁCTICO

A lo largo de este práctico veremos cómo GeneXus Server facilita el trabajo en equipo.

Para esto, simularemos un equipo de desarrollo compuesto por dos integrantes: Diego y Mary.

En este documento se captura el trabajo de Diego en el IDE azul, y el de Mary en el IDE rosado.

Es ideal hacer este práctico de a dos, de forma que uno haga el trabajo de Mary y el otro el de Diego.
En caso que se encuentre realizando solo este práctico, debe hacer el trabajo de ambos, pero es
importante hacerlo desde diferentes instancias de GeneXus y con diferentes usuarios en GeneXus
Server para poder realizar el trabajo de los dos desarrolladores en paralelo y poder generar/resolver
conflictos.

102
Comenzando

Veremos las operaciones básicas de GeneXus Server: Send Knowledge Base to Server, Create
Knowledge Base from Server, Commit y Update.

Además, veremos cómo GeneXus Server resuelve ciertos problemas con los cuales nos
podemos encontrar a la hora de consolidar nuestro trabajo con el resto del equipo.

También se mostrará el versionado en GeneXus Server: creación de versiones congeladas,


creación de versiones de desarrollo a partir de una versión congelada, pasaje de cambios
entre versiones, etc.

PASO 1: PUBLICACIÓN INICIAL (MARY)

Lo primero a hacer es crear un nuevo proyecto llamado Lab2016_<NumeroMaquina> (Si se


encuentra en un laboratorio presencial, el número de maquina será proporcionado por el
instructor, en caso contrario puede llamarlos 1 y 2 para Diego y Mary respectivamente.).

Para esto Mary debe crear una nueva base de conocimiento llamada
Lab2016_<NumeroMaquina>.

103
1. CREE UNA NUEVA BASE DE CONOCIMIENTO. CAMBIE EL NOMBRE A
Lab2016_<NumeroMaquina>.

Una vez creada la base de conocimiento, ésta podrá ser editada por Mary, pero todavía no
estará disponible para el resto del equipo de desarrollo.

Ahora Mary debe publicar la base de conocimiento para que quede disponible para los otros
desarrolladores y así puedan comenzar a trabajar en equipo.

Para esto, simplemente alcanza con que Mary haga la operación Send KB to GeneXus Server.

2. ABRA EL MENÚ File  Send Knowledge Base to GeneXus Server

104
GeneXus desplegará el diálogo para enviar una Knowledge Base a GeneXus Server.

Mediante este proceso será posible crear una base de conocimiento centralizada (a la que
llamaremos Knowledge Base de GeneXus Server) que es una copia de la base de
conocimiento local (a la que llamaremos Knowledge Base local) en la que estaba trabajando
Mary.

La Knowledge Base local de Mary quedará automáticamente enganchada a la Knowledge


Base de GeneXus Server, de tal forma que cuando Mary lo disponga pueda impactar los
cambios realizados en su Knowledge Base local, en la Knowledge Base de GeneXus Server.

Además podrá recibir los cambios que otros desarrolladores hagan en la Knowledge Base de
GeneXus Server, en su Knowledge Base local.

3. INGRESE LA URL A LA QUE DEBE ENVIAR LA KNOWLEDGE BASE MARY:

http://open.genexusserver.com/v15

4. SELECCIONE LA VERSIÓN Lab2016_<NumeroMaquina>.

5. EN LA SECCIÓN Security SELECCIONE EL TIPO DE AUTENTICACIÓN E INGRESE EL


USERNAME. (Si se encuentra en un laboratorio presencial, solicite las credenciales
a su instructor, en caso contrario necesitará las credenciales de dos cuentas
“GeneXus Account” o utilizar un servidor al cual tenga acceso y diferentes cuentas)

6. HAGA CLICK EN Send Y SIMPLEMENTE ESPERE A QUE FINALICE LA OPERACIÓN.

105
Como podrá ver se agregó en GeneXus la opción Team Development al menú Knowledge
Manager. Esta será la opción que utilizaremos para interactuar con GeneXus Server.

Además, si vamos a las Preferences podemos ver que se agregó un nuevo nodo al árbol
llamado Team Development el cual guarda la información de la conexión con GeneXus
Server, como se puede ver en la siguiente imagen:

PASO 2: CREAR KB DESDE GENEXUS SERVER (DIEGO)

En este paso lo que haremos será integrar a Diego al equipo de desarrolladores que
trabajarán con la base de conocimiento Lab2016_<NumeroMaquina>.

Para esto simplemente alcanza con hacer la operación llamada Create Knowledge Base
from GeneXus Server.

106
¿Qué hace esta operación? Lo que hace es, a partir de la Knowledge Base de GeneXus Server
que se creó cuando Mary publicó su Knowledge Base local, crearle a Diego su propia copia
local. La misma también queda automáticamente enganchada a la Knowledge Base de
GeneXus Server, de forma que también pueda integrar sus cambios con el resto del equipo.

1. VAYA AL IDE AZUL Y ELIJA LA OPCIÓN DE MENÚ FileNewKnowledge Base from


GeneXus server.

2. SE DESPLEGARÁ EL SIGUIENTE DIÁLOGO:

COMO Server KB URL INGRESAMOS LA MISMA EN LA QUE MARY PUBLICÓ SU BASE DE


CONOCIMIENTO: por ejemplo http://open.genexusserver.com/v15

107
3. DESPUÉS HACEMOS CLIC EN Select Server KB…, LO QUE LISTARÁ TODAS LAS BASES
DE CONOCIMIENTO QUE SE HAYAN PUBLICADO EN ESE GENEXUS SERVER.
BUSCAMOS Lab2016_<NumeroMaquina>.

4. EN ESTE CASO COMO QUEREMOS REALIZAR LA OPERACIÓN DE Create KB From


GeneXus Server CON UN USUARIO DIFERENTE, SELECCIONAMOS EL SERVIDOR
evento DE LA LISTA Servers, HACEMOS CLIC DERECHO Y LUEGO Edit.

5. LO QUE ABRIRÁ EL SIGUIENTE DIÁLOGO:

108
6. INGRESAMOS LAS CREDENCIALES PARA EL USUARIO QUE HARA EL TRABAJO DE
DIEGO Y MARCAMOS EL CHECKBOX DE Save Password.

7. SELECCIONAMOS LA KNOWLEDGE BASE Lab2016_<NumeroMaquina> PRESIONANDO


Select.

Luego de presionar Select se abrirá nuevamente el diálogo original donde debemos


seleccionar la versión Trunk e ingresamos el nombre de la nueva Knowledge Base, que
crearemos como Lab2016_<NumeroMaquina>_Diego.

8. HACEMOS CLIC EN CREATE, Y AGUARDAMOS A QUE FINALICE LA OPERACIÓN.

En este momento tenemos a dos desarrolladores, Mary y Diego, los cuales tienen cada
uno una copia local de la base de conocimiento, y a su vez se creó una Knowledge Base
de GeneXus Server que será sobre la cual se impactarán los cambios de ambos
desarrolladores.

Ahora vamos a comenzar a trabajar con cada uno de los desarrolladores.

109
PASO 3: CREACIÓN DE OBJETOS Y PRIMER COMMIT (MARY)

1. CREE LA TRANSACCIÓN Real Estate Agency:

2. AGREGUE LOS SIGUIENTES ATRIBUTOS Y GUARDE LOS CAMBIOS:

Ahora supongamos que Mary quiere integrar su transacción Real Estate Agency a la
Knowledge Base de GeneXus Server para que los demás desarrolladores puedan recibir
este cambio.

110
3. SELECCIONE EL MENÚ Knowledge Manager  Team Development.

En el diálogo de Team Development puede observar cinco pestañas: Commit, Update,


History, Activity y Versions. A lo largo del práctico veremos qué funcionalidades ofrecen
algunas de estas pestañas.

Al momento de ingresar, en la pestaña de Commit GeneXus presentará automáticamente


todos los objetos que han sido modificados localmente y que por lo tanto están
pendientes para Commit. Es decir, son cambios a los cuales los demás desarrolladores
todavía no tienen acceso (porque no están consolidados).

La columna Action indica si es un objeto nuevo que no está en la Knowledge Base de


GeneXus Server (Inserted), un objeto modificado (Modified), o si es un objeto que se borró
(Deleted). En este caso como la transacción es nueva se puede ver que la Action es Inserted.

Lo único que resta antes de consolidar los cambios locales con los de la Knowledge Base
de GeneXus Server es añadir un comentario.

En GeneXus Server los comentarios son obligatorios ya que son considerados una buena
práctica que ayuda a entender mejor la razón de por qué se realizan los cambios.

4. EN ESTE CASO PONGA EN EL COMENTARIO ”Transaction Real Estate Agency added” Y


LUEGO HAGA CLIC EN EL BOTÓN Commit.

111
Con esto, los cambios locales de Mary quedan consolidados en la Knowledge Base de
GeneXus Server y por lo tanto estarán disponibles para los demás usuarios.

De igual forma, Diego podría crear todos los objetos que desee y siguiendo los mismos
pasos que Mary, podría integrarlos a la Knowledge Base de GeneXus Server para que
queden disponibles para los demás desarrolladores.

PASO 4: UPDATE DESDE GENEXUS SERVER (DIEGO)

Ahora supongamos que Diego quiere recibir todos los cambios que hayan introducido los
otros desarrolladores.

1. PARA ESTO, EN EL IDE DE DIEGO VAYA AL MENÚ Knowledge Manager Team


Development Y SELECCIONE LA PESTAÑA Update.

112
En el diálogo de Update se muestra una grilla con los cambios que están en el server y que
aún no hemos recibido. Si quisiéramos hacer una actualización parcial, podemos
seleccionar solo algunos de los objetos de la lista.

2. EN ESTE CASO DEJE SELECCIONADOS TODOS LOS OBJETOS Y HAGA CLIC EN


Update.

Al finalizar la operación se mostrará una lista de los objetos modificados en la pestaña


Results.

113
Con estos sencillos pasos Diego obtuvo los cambios de los demás desarrolladores en su
Knowledge Base local.

De esta forma Diego y Mary podrían repetir este ciclo todas las veces que sea necesario y
estarían consolidando sus cambios de una forma muy simple.

Lógicamente, mientras Mary y Diego editen objetos distintos no habrá ningún problema,
pero uno podría preguntarse ¿qué pasa si ambos modifican el mismo objeto?

En este paso ambos desarrolladores modificarán la transacción RealEstateAgency y


veremos cómo GeneXus Server integra los cambios.

Primero Diego le añadirá a la transacción el atributo RealEstateAgencyImage, por lo tanto:

114
3. ABRA LA TRANSACCIÓN Y AGREGUE EL ATRIBUTO RealEstateAgencyImage,
GUARDANDO LOS CAMBIOS AL FINALIZAR:

Luego vamos a publicar los cambios de Diego.

4. IR A LA VENTANA DE Team Development, PESTAÑA Commit Y ESCRIBIR COMO


COMENTARIO “Attribute RealEstateAgencyImage added to transaction
RealEstateAgency”. POR ÚLTIMO HACER CLIC EN Commit1.

1
Si ya tenía abierto el diálogo de TeamDevelopment y al ir a la pestaña Commit no le
aparecen objetos pendientes, asegúrese de haber guardado los cambios y presione el
botón de Refresh que aparece en arriba de la grilla.

115
Ahora hagamos que Mary le agregue a la transacción RealEstateAgency el atributo
RealEstateAgencyPhone.

PASO 5: MANEJO DE CONFLICTOS (MARY)

1. MODIFIQUE LA TRANSACCIÓN AGREGANDO EL ATRIBUTO RealEstateAgencyPhone Y


LUEGO GUARDE LOS CAMBIOS.

A continuación integraremos los cambios locales de Mary con la Knowledge Base de


GeneXus Server.

2. VAYA A LA VENTANA DE Team Development, EN LA PESTAÑA DE Commit, Y HAGA


CLIC EN EL BOTÓN DE REFRESH.

3. ESCRIBA COMO COMENTARIO “Attribute RealEstateAgencyPhone added to


transaction RealEstateAgency” Y HAGA CLIC EN Commit.

116
Usted debería recibir el siguiente mensaje de error en el Output:

Esta es una situación normal. GeneXus Server simplemente le está indicando que algún
otro desarrollador ya modificó la transacción, y por lo tanto no puede recibir los nuevos
cambios2. Estos cambios deberán ser primero integrados en una nueva versión local para
luego ser enviados a GeneXus Server.

2
Si GeneXus Server aceptara recibir el objeto en este momento, se perderían los cambios que
hicieron los demás miembros del equipo.

117
Esta integración se logra muy fácilmente haciendo un Update para actualizar la
transacción. Para esto:

4. SELECCIONE LA PESTAÑA Update.

Como se puede ver, GeneXus lista la transacción Real Estate Agency ya que fue modificada
por Diego.

Si hacemos clic derecho sobre la transacción y seleccionamos la opción Compare With


Current Revision, nos mostrará las diferencias entre el objeto local y el objeto en el server.

118
En este caso las líneas modificadas son distintas y por lo tanto cuando realicemos la
operación de Update, GeneXus hará una integración automática (merge) entre la versión
de GeneXus Server y la versión local de los objetos involucrados en el conflicto, quedando
el objeto pendiente para Commit, y permitiendo publicar los cambios que realizó Mary. El
estado del objeto en este momento es exactamente equivalente a que Mary hubiera hecho
sus cambios partiendo de la versión ya modificada por Diego.

5. CIERRE LA VENTANA DEL Comparer Y EN LA VENTANA DE Team Development HAGA


CLIC EN Update.

119
En el output podrá ver el siguiente mensaje que le indicará que GeneXus Server hizo el
merge del objeto.

Y también en la grilla de la pestaña Update:

6. LUEGO VAYA A LA PESTAÑA Commit Y HAGA CLIC EN EL BOTÓN Commit.

120
La operación ahora sí finalizará con éxito y quedarán consolidados tanto los cambios de
Mary como los de Diego sobre la transacción RealEstateAgency.

Es importante notar que se destacará con color verde el objeto RealEstateAgency afectado
por la operación de merge.

Muchas veces al trabajar en equipo se hacen varias modificaciones sobre el mismo objeto, lo que
imposibilita el hecho de poder preguntar a un desarrollador concreto sobre los cambios realizados
al mismo.

GeneXus Server permite saber qué desarrollador modificó cada elemento de un objeto de
una manera extremadamente sencilla.

121
Para probar esto, imaginemos ahora que Diego quiere modificar la transacción
RealEstateAgency para declarar el atributo RealEstateAgencyId como autonumerado y la
regla NoAccept(RealEstateAgencyId) en la transacción.

PASO 6: UPDATE DESDE GENEXUS SERVER Y MODIFICACIÓN DE OBJETOS (DIEGO)

1. HAGA Update DE LOS OBJETOS AGREGADOS POR MARY.

2. MODIFIQUE EL ATRIBUTO RealEstateAgencyId DE LA TRANSACCION


RealEstateAgency PARA QUE SEA AUTONUMERADO. SELECCIONE EL ATRIBUTO,
PRESIONE LA TECLA F4 PARA VER SUS PROPIEDADES Y BAJO EL NODO Type
Definition ASIGNE EL VALOR True A LA PROPIEDAD Autonumber:

122
3. VAYA A LA PESTAÑA DE Rules Y AGREGUE LA REGLA COMO SE MUESTRA A
CONTINUACIÓN:

4. HAGA Commit DE LOS CAMBIOS AGREGANDO EL COMENTARIO “RealEstateAgencyId


changed to autonumber and NoAccept(RealEstateAgencyId) rule added”

123
Ahora Mary tiene que realizar un Update para recibir los cambios hechos por Diego.

PASO 7: BLAME (MARY)

1. HAGA Update DE LAS MODIFICACIONES REALIZADAS POR DIEGO.

124
2. SELECCIONE LA OPCIÓN Blame (BOTÓN DERECHO EN LA TRANSACCIÓN
RealEstateAgency Y LUEGO Team DevelopmentBlame):

3. Y SE ABRIRÁ LA SIGUIENTE PESTAÑA MOSTRANDO EXACTAMENTE QUÉ USUARIO


MODIFICÓ CADA UNA DE LAS PARTES DE LA TRANSACCIÓN Y EL NÚMERO DEL Commit
EN EL CUAL FUE REALIZADA LA MODIFICACIÓN.

EN LA PESTAÑA DE Structure SE MOSTRARÁ:

125
Y EN LA PESTAÑA DE Rules SE MOSTRARÁ:

Con esta sencilla operación pudimos ver todas las modificaciones que tuvo un objeto sin
importar quién las hizo, en qué momento o revisión, algo muy valioso a la hora de trabajar
en equipo.

PASO 8: COMMIT PARCIAL Y CHANGESET (DIEGO)

Al trabajar en un equipo de desarrollo se modifican objetos por distintos motivos: arreglos


de errores, implementación de nuevas funcionalidades, etc.

Cuando un objeto tiene varias modificaciones pero realizadas por diferentes motivos, se
necesita hacer Commit de determinadas modificaciones de un objeto y no del objeto
completo para mantener en el server solamente aquellos cambios que están prontos para
Commit.

GeneXus Server habilita a los integrantes del equipo a realizar un Commit solamente de algunas
líneas/bloques de determinado objeto, evitando tener que hacer Commit del objeto en su
totalidad.

126
Imaginemos ahora que uno de los requerimientos de nuestra aplicación es que desde un
panel se puedan ingresar datos para actualizar el nombre y la imagen de una agencia en
particular. En este caso nos centraremos solamente en el procedimiento que actualizará la
base de datos.

1. CREE EL PROCEDIMIENTO ModifyRealEstateAgency

CON EL SIGUIENTE CÓDIGO:

Y LA SIGUIENTE REGLA DECLARADA:

127
2. HAGA Commit DEL PROCEDIMIENTO AGREGANDO EL COMENTARIO
”ModifyRealEstateAgency procedure added”

Una vez que el procedimiento está terminado, Diego recibe la noticia de que hay un nuevo
requerimiento.

En esta ocasión se necesita conocer la ciudad donde se encuentra cada Real Estate Agency, por lo
que Diego debe crear nuevas estructuras y modificar el procedimiento que creó para que también
permita actualizar la ciudad de las agencias.

Además también interesa que el procedimiento permita actualizar la dirección y el teléfono de la


agencia.

3. CREE LA TRANSACCIÓN Country CON LA SIGUIENTE ESTRUCTURA Y GUARDE LOS


CAMBIOS:

4. CREE LA TRANSACCIÓN City CON LA SIGUIENTE ESTRUCTURA Y GUARDE LOS CAMBIOS:

128
5. AGREGUE EL ATRIBUTO CityId A LA TRANSACCIÓN RealEstateAgency

6. MODIFIQUE EL PROCEDIMIENTO ModifyRealEstateAgency PARA AGREGAR LA LÍNEA


CORRESPONDIENTE A LA MODIFICACIÓN DE LA CIUDAD, TELÉFONO Y DIRECCIÓN DE
LA AGENCIA:

Una vez que las modificaciones necesarias para soportar los nuevos requerimientos
están en proceso, Diego recibe la noticia de que se necesita saber la superficie total
de cada ciudad para poder calcular la cantidad de locales necesarios de cada
agencia. Para esto, Diego debe modificar la transacción City.

Además, el procedimiento ModifyRealEstateAgency, que permite modificar la información


de cada RealEstateAgency, debe ser puesto en producción inmediatamente, por lo que es
necesario que Diego haga Commit del procedimiento. Para esto, Diego debe hacer Commit
del procedimiento pero sin incluir la línea referente a la ciudad de la RealEstateAgency
porque la transacción City debe ser modificada y todavía no está lista para Commit.

129
7. IR AL DIÁLOGO DE Commit DE Team Development DONDE ESTARÁN TODOS LOS
OBJETOS NUEVOS Y LOS MODIFICADOS:

Como podemos apreciar, todos los objetos se muestran juntos en la grilla de Commit,
lo que nos puede perjudicar al momento de querer marcar solamente ciertos objetos
para hacer Commit.

Para esto, organizaremos los objetos en ChangeSets. Esta funcionalidad permite


mantener los objetos agrupados por el criterio que el desarrollador crea más
conveniente: arreglos, modificaciones, mejoras de performance, nueva funcionalidad,
estado, etc.

En esta ocasión, los organizaremos dependiendo de si los objetos son parte de la


nueva funcionalidad de agregar la ciudad a las agencias o parte de la modificación de
información de una agencia dada.

8. SELECCIONAR DE LA GRILLA DE Commit AQUELLOS OBJETOS DE LA TRANSACCIÓN


City QUE SON ALGUNOS DE LOS QUE FORMARÁN PARTE DEL ChangeSet
CORRESPONDIENTE A LA NUEVA FUNCIONALIDAD DE LAS CIUDADES DE LAS
AGENCIAS.

130
HACER CLIC DERECHO EN LOS OBJETOS Y SELECCIONAR LA OPCIÓN Move to
Changeset New ChangeSet.

EL SIGUIENTE DIÁLOGO SE DESPLEGARÁ PARA INGRESAR EL NOMBRE DEL ChangeSet QUE


LLAMAREMOS City Feature:

COMO RESULTADO PODEMOS APRECIAR QUE LOS OBJETOS SE AGRUPARON EN UNA


PARTE DE LA GRILLA, SEPARADOS DEL RESTO DE LOS OBJETOS QUE NO PERTENECEN A
NINGÚN ChangeSet

131
9. DEL MISMO MODO, SELECCIONE EL RESTO DE LOS OBJETOS QUE FORMAN PARTE
DE A LA NUEVA FUNCIONALIDAD DE LAS CIUDADES DE LAS AGENCIAS Y AGRÉGUELOS
AL ChangeSet YA CREADO:

132
Ahora solamente nos queda asignar el procedimiento que modifica la información de
una inmobiliaria dada, para esto:

10. CREE EL ChangeSet LLAMADO Change Information DE LA MISMA FORMA QUE EL


ChangeSet ANTERIOR:

133
Como resultado final podemos ver que la grilla está totalmente organizada según los
commits que tendrá que realizar Diego:

134
Ahora que Diego ya tiene su trabajo mejor organizado, tiene que realizar el Commit del
procedimiento ModifyRealEstateAgency pero excluyendo la línea correspondiente a la
asignación de la ciudad ya que la misma implica hacer Commit de objetos que todavía no
están terminados.

11. SELECCIONE EL PROCEDIMIENTO DE LA GRILLA DEL DIÁLOGO DE Commit, HAGA


CLIC DERECHO SOBRE ÉL Y SELECCIONE LA OPCIÓN Show Differences

135
A CONTINUACIÓN SE ABRIRÁ EL SIGUIENTE COMPARADOR MOSTRANDO LAS DIFERENCIAS
DEL OBJETO QUE SE ENCUENTRA EN EL SERVER Y EL OBJETO LOCAL.

12. HAGA CLICK DERECHO SOBRE LA LÍNEA CityId = &NewCity Y SELECCIONE LA OPCIÓN
Exclude line for Commit

ESTO PROVOCARÁ QUE LA LÍNEA SE MUESTRE EN ROJO, LO QUE SIGNIFICA QUE NO


FORMARÁ PARTE DEL PRÓXIMO Commit

13. SALVAR EL OBJETO HACIENDO CLIC SOBRE EL BOTÓN

136
14. DE NUEVO EN EL DIÁLOGO DE Commit, AGREGUE EL COMENTARIO ”Modifications
added to procedure ModifyRealEstateAgency”, desmarque todos los objetos del
ChangeSet City Feature Y REALICE EL Commit SOLO DEL PROCEDIMIENTO
ModifyRealEstateAgency.

PASO 9: INTERACCIÓN CON LA CONSOLA Y ACTIVITY TAB (MARY)

Después de todos los cambios realizados por Diego, Mary quiere hacer dos cosas: ver la
actividad local de su Knowledge Base para saber qué objetos fueron parte del último Update
que realizó y ver los estados de todos los objetos del server sin tener que realizar una
operación de Update.

Primero veamos cómo hace Mary para ver la actividad local de su Knowledge Base.

1. ABRA EL DIÁLOGO DE Team Development Y POSICIÓNESE EN LA PESTAÑA DE Activity

137
2. MODIFICANDO EL VALOR DEL COMBO Operation, MARY PUEDE VER QUÉ OBJETOS
FUERON PARTE DE LOS Updates, Commits Y Bring Changes.

Ahora veamos cómo hace Mary para ver el estado de los objetos en el server, más en
particular, le interesa ver qué estado tiene el procedimiento ModifyRealEstateAgency.

Para esto, GeneXus Server brinda una consola de Administración la cual le ofrece diversas
funcionalidades.

3. ABRA EL NAVEGADOR E INGRESE LA SIGUIENTE URL:


http://open.genexusserver.com/v15

La siguiente página se abrirá:

138
4. ASEGÚRESE QUE Authentication Type, Username y Password TIENE EL VALOR QUE
UTILIZÓ PARA TRABAJAR COMO MARY

Lo primero que nos muestra es el Dashboard con variada información, como por ejemplo
la actividad más reciente, las distintas Knowledge Bases hosteadas en GeneXus Server,
etc. En este caso sólo está la base de conocimiento anteriormente publicada por Mary,
Lab2016_<NumeroMaquina> y las operaciones realizadas sobre ella.

Ahora vamos a abrir una Knowledge Base en la consola. Para esto:

5. SIMPLEMENTE DEBE HACER CLIC SOBRE EL NOMBRE DE LA KNOWLEDGE BASE, EN LA


GRILLA DE Knowledge Bases.

Al momento de abrir la base de conocimiento, se mostrará el contenido de la página KB


Dashboard.

Esta página muestra información relevante a la Knowledge Base abierta, como por ejemplo
nombre de la versión activa (abierta), cantidad de objetos de cada tipo y los últimos
Commits entre otros datos. Como se puede ver en la siguiente imagen:

139
6. VAYA A LA PESTAÑA Knowledge Base QUE SE ENCUENTRA EN LA VENTANA KB
Dashboard

Y ABRA EL OBJETO ModifyRealEstateAgency HACIENDO DOBLE CLIC EN EL NOMBRE


DEL MISMO QUE SE ENCUENTRA EN LA GRILLA DE Latest Changes

Como podemos apreciar en la imagen, la línea que Diego excluyó del Commit no se
encuentra en el objeto del server.

140
7. A CONTINUACIÓN CIERRE SESIÓN. PARA HACERLO LOCALICE EL NOMBRE DEL USUARIO
MARY EN LA PARTE SUPERIOR DERECHA DE LA PANTALLA Y SELECCIONE Sign out.

141
Con esto finalizamos este práctico de GeneXus Server, esperando que hayan quedado
claros los conceptos vistos: publicar una base de conocimiento, crear una base de
conocimiento a partir de una publicada anteriormente, publicar cambios locales, obtener
los cambios publicados por los demás desarrolladores, resolución de conflictos en las
operaciones básicas, ignorar objetos, líneas o bloques que no quiero publicar, saber quién
modificó cada línea de un objeto.

Por más información acerca del producto visite www.GXserver.com.

Por documentación detallada sobre el producto visitar la categoría de GeneXus Server en el


Community Wiki
http://wiki.genexus.com/commwiki/servlet/wiki?31337,Toc%3AGeneXus+Server+15

142

You might also like