diff --git a/.gitignore b/.gitignore index b357106ec6b1..8438685c9770 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ library/src/webapp/skin/morpheus-default/ **/src/main/frontend/node/ scormplayer/scorm-tool/contentPackages .vscode/ +.java-version diff --git a/announcement/announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementService.java b/announcement/announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementService.java index 9fbb9913278c..0f52ffbf5308 100644 --- a/announcement/announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementService.java +++ b/announcement/announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementService.java @@ -22,7 +22,6 @@ package org.sakaiproject.announcement.api; import java.util.List; -import java.util.Map; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.Reference; @@ -101,12 +100,6 @@ public interface AnnouncementService extends MessageService /** Security function giving the user permission to all groups, if granted to at the channel or site level. */ public static final String SECURE_ANNC_ALL_GROUPS = SECURE_ANNC_ROOT + SECURE_ALL_GROUPS; - /** release date property names for announcements */ - public static final String RELEASE_DATE = "releaseDate"; - - /** retract date property names for announcements */ - public static final String RETRACT_DATE = "retractDate"; - /** modified date property names for announcements */ public static final String MOD_DATE = "modDate"; @@ -176,13 +169,6 @@ public AnnouncementChannelEdit addAnnouncementChannel(String ref) throws IdUsedE */ public String getRssUrl(Reference ref); - /** - * Determine if message viewable based on release/retract dates (if set) - * @param AnnouncementMessage - * @return boolean - */ - public boolean isMessageViewable(AnnouncementMessage message); - /** * clears the message cache for this channel * @param channelRef diff --git a/announcement/announcement-impl/impl/src/java/org/sakaiproject/announcement/impl/BaseAnnouncementService.java b/announcement/announcement-impl/impl/src/java/org/sakaiproject/announcement/impl/BaseAnnouncementService.java index 24b234054cab..5c0581f28df5 100644 --- a/announcement/announcement-impl/impl/src/java/org/sakaiproject/announcement/impl/BaseAnnouncementService.java +++ b/announcement/announcement-impl/impl/src/java/org/sakaiproject/announcement/impl/BaseAnnouncementService.java @@ -26,7 +26,6 @@ import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.time.Instant; -import java.util.Arrays; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -709,45 +708,6 @@ public String getRssUrl(Reference ref) return rssUrlString.toString(); } - /** - * {@inheritDoc} - */ - public boolean isMessageViewable(AnnouncementMessage message) - { - final ResourceProperties messageProps = message.getProperties(); - - final Instant now = Instant.now(); - try - { - final Instant releaseDate = message.getProperties().getInstantProperty(RELEASE_DATE); - - if (now.isBefore(releaseDate)) - { - return false; - } - } - catch (Exception e) - { - // Just not using/set Release Date - } - - try - { - final Instant retractDate = message.getProperties().getInstantProperty(RETRACT_DATE); - - if (now.isAfter(retractDate)) - { - return false; - } - } - catch (Exception e) - { - // Just not using/set Retract Date - } - - return true; - } - /** * {@inheritDoc} */ diff --git a/assignment/api/src/resources/assignment_es.properties b/assignment/api/src/resources/assignment_es.properties index 1cc3c0968b64..017b87bf69ce 100644 --- a/assignment/api/src/resources/assignment_es.properties +++ b/assignment/api/src/resources/assignment_es.properties @@ -200,7 +200,7 @@ gen.nograd=No hay calificaci\u00f3n gen.notavail=La tarea no est\u00e1 disponible; Estado\: {0} gen.notope=Sin abrir gen.notset=No establecido -gen.notsta=No la has empezado +gen.notsta=No ha empezado gen.hpsta=Cl\u00e1usula de veracidad aceptada gen.of=de gen.open=Abierta @@ -964,6 +964,7 @@ external.tool.label=Opciones de herramienta externa (LTI) external.tool.placeholder=Seleccione una herramienta externa external.tool.find=Seleccione una herramienta externa (LTI) external.tool.goto=Ir a la herramienta externa +external.tool.deleted=*Borrado* external.tool.new.window=Abrir herramienta externa en ventana nueva external.tool.launched=La herramienta externa se ha abierto, refresque la p\u00e1gina para volver a lanzarla. external.tool.expired=El lanzamiento ha expirado, refresque la p\u00e1gina diff --git a/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentEventObserver.java b/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentEventObserver.java index edbde8fd8e27..a3baffe2f7cc 100644 --- a/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentEventObserver.java +++ b/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentEventObserver.java @@ -22,6 +22,7 @@ import java.util.stream.IntStream; import org.apache.commons.lang3.StringUtils; +import org.sakaiproject.assignment.api.AssignmentReferenceReckoner; import org.sakaiproject.assignment.api.AssignmentService; import org.sakaiproject.assignment.api.model.Assignment; import org.sakaiproject.assignment.api.model.AssignmentSubmission; @@ -32,6 +33,10 @@ import org.sakaiproject.exception.PermissionException; import org.sakaiproject.grading.api.AssessmentNotFoundException; import org.sakaiproject.grading.api.GradingService; +import org.sakaiproject.site.api.SiteService; +import org.sakaiproject.tasks.api.Priorities; +import org.sakaiproject.tasks.api.TaskService; +import org.sakaiproject.tasks.api.UserTaskAdapterBean; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.user.api.UserNotDefinedException; @@ -45,6 +50,7 @@ public class AssignmentEventObserver implements Observer { @Setter private AssignmentService assignmentService; @Setter private EventTrackingService eventTrackingService; @Setter private GradingService gradingService; + @Setter private TaskService taskService; @Setter private UserDirectoryService userDirectoryService; public void init() { @@ -136,6 +142,26 @@ public void update(Observable o, Object arg) { } } break; + case SiteService.EVENT_USER_SITE_MEMBERSHIP_ADD: + + // A user has been added to a site. Lets make sure any current assignments + // for that site have a corresponding task for the new user. + String userId = userDirectoryService.idFromReference(event.getResource()); + String siteId = event.getContext(); + assignmentService.getAssignmentsForContext(siteId).forEach(ass -> { + + + String ref = AssignmentReferenceReckoner.reckoner().assignment(ass).reckon().getReference(); + taskService.getTask(ref).ifPresent(task -> { + + UserTaskAdapterBean userTaskBean = new UserTaskAdapterBean(); + userTaskBean.setTaskId(task.getId()); + userTaskBean.setUserId(userId); + userTaskBean.setPriority(Priorities.HIGH); + + taskService.createUserTask(task, userTaskBean); + }); + }); default: log.debug("This observer is not interested in event [{}]", event); break; diff --git a/assignment/impl/src/test/org/sakaiproject/assignment/impl/AssignmentServiceTest.java b/assignment/impl/src/test/org/sakaiproject/assignment/impl/AssignmentServiceTest.java index 0746fe164fad..5167799c36b7 100644 --- a/assignment/impl/src/test/org/sakaiproject/assignment/impl/AssignmentServiceTest.java +++ b/assignment/impl/src/test/org/sakaiproject/assignment/impl/AssignmentServiceTest.java @@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; import java.io.BufferedReader; import java.io.InputStream; @@ -46,6 +47,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Observable; import java.util.Optional; import java.util.Random; import java.util.Set; @@ -85,6 +87,10 @@ import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SiteService; +import org.sakaiproject.tasks.api.Priorities; +import org.sakaiproject.tasks.api.Task; +import org.sakaiproject.tasks.api.TaskService; +import org.sakaiproject.tasks.api.UserTaskAdapterBean; import org.sakaiproject.time.api.UserTimeService; import org.sakaiproject.tool.api.SessionManager; import org.sakaiproject.user.api.User; @@ -126,6 +132,7 @@ public class AssignmentServiceTest extends AbstractTransactionalJUnit4SpringCont @Autowired private SessionManager sessionManager; @Autowired private ServerConfigurationService serverConfigurationService; @Autowired private SiteService siteService; + @Autowired private TaskService taskService; @Resource(name = "org.sakaiproject.time.api.UserTimeService") private UserTimeService userTimeService; @Autowired private UserDirectoryService userDirectoryService; @@ -1489,6 +1496,45 @@ public void canSubmit() { } } + @Test + public void createsTasksForNewlyAddedUser() { + + String siteId = "xyz"; + + Assignment assignment = createNewAssignment(siteId); + + String assignmentRef = AssignmentReferenceReckoner.reckoner().assignment(assignment).reckon().getReference(); + + String studentId = "student1"; + String userReference = "/user/" + studentId; + when(userDirectoryService.idFromReference(userReference)).thenReturn(studentId); + + // Mock up an existing Task + Long taskId = 232L; + Task task = mock(Task.class); + when(task.getId()).thenReturn(taskId);; + when(taskService.getTask(assignmentRef)).thenReturn(Optional.of(task)); + + // Mock up an event, and then "fire" it + Event event = mock(Event.class); + when(event.getEvent()).thenReturn(SiteService.EVENT_USER_SITE_MEMBERSHIP_ADD); + when(event.getContext()).thenReturn(siteId); + when(event.getResource()).thenReturn(userReference); + when(event.getModify()).thenReturn(true); + assignmentEventObserver.update(null, event); + + // Verify that getTask is called on our taskService mock + verify(taskService).getTask(assignmentRef); + + UserTaskAdapterBean userTaskBean = new UserTaskAdapterBean(); + userTaskBean.setTaskId(task.getId()); + userTaskBean.setUserId(studentId); + userTaskBean.setPriority(Priorities.HIGH); + + // Verify that createUserTask is called on our taskService mock, with the correct arguments + verify(taskService).createUserTask(task, userTaskBean); + } + private AssignmentSubmission createNewSubmission(String context, String submitterId, Assignment assignment) throws UserNotDefinedException, IdUnusedException { if (assignment == null) { diff --git a/assignment/impl/src/webapp/WEB-INF/components.xml b/assignment/impl/src/webapp/WEB-INF/components.xml index f7cc024a919e..aa12885ce560 100644 --- a/assignment/impl/src/webapp/WEB-INF/components.xml +++ b/assignment/impl/src/webapp/WEB-INF/components.xml @@ -296,6 +296,7 @@ + diff --git a/assignment/tool/src/java/org/sakaiproject/assignment/entityproviders/AssignmentEntityProvider.java b/assignment/tool/src/java/org/sakaiproject/assignment/entityproviders/AssignmentEntityProvider.java index 534f30bf8ec9..457e6c748c22 100644 --- a/assignment/tool/src/java/org/sakaiproject/assignment/entityproviders/AssignmentEntityProvider.java +++ b/assignment/tool/src/java/org/sakaiproject/assignment/entityproviders/AssignmentEntityProvider.java @@ -2247,7 +2247,9 @@ public SimplePeerAssessmentItem(PeerAssessmentItem item) { this.scaledFactor = item.getScaledFactor(); this.draft = item.isDraft(); - this.attachmentUrlList = item.getAttachmentRefList().stream() + this.attachmentUrlList = Optional.ofNullable(item.getAttachmentRefList()) + .orElseGet(Collections::emptyList) + .stream() .map(Reference::getUrl) .collect(Collectors.toList()); } diff --git a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java index ae11ba71495d..9baaaeef3ee2 100644 --- a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java +++ b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java @@ -1698,6 +1698,7 @@ private String build_student_view_submission_context(VelocityPortlet portlet, Co String contextString = (String) state.getAttribute(STATE_CONTEXT_STRING); context.put("context", contextString); context.put("NamePropSubmissionScaledPreviousGrades", ResourceProperties.PROP_SUBMISSION_SCALED_PREVIOUS_GRADES); + context.put("showUserId", serverConfigurationService.getBoolean("assignment.users.ids.show", true)); User user = (User) state.getAttribute(STATE_USER); log.debug(this + " BUILD SUBMISSION FORM WITH USER " + user.getId() + " NAME " + user.getDisplayName()); diff --git a/assignment/tool/src/webapp/js/assignmentsByStudent.js b/assignment/tool/src/webapp/js/assignmentsByStudent.js index ba79eb005404..f964ba54c167 100644 --- a/assignment/tool/src/webapp/js/assignmentsByStudent.js +++ b/assignment/tool/src/webapp/js/assignmentsByStudent.js @@ -64,7 +64,7 @@ function renderGrouping({ studentName, actionLink, expanded, studentUserId, user
$model.getAccessInstruction()
A collection of useful servers, management tools, and configurations for developing the Sakai LMS
A shell in a box console in a maven container with all the development folders mounted to build sakai with mvn in the /source fodler.
Graylog is a centralized log management solution for capturing, storing, and enabling real-time analysis of logs
A robust system supporting over 4 million educational users to enhance collaborative teaching, learning and research.
Runs a super simple SMTP server which catches any message sent to it to display in a web interface.
An open source elasticsearch web admin tool built using Scala, Play Framework, AngularJS and Bootstrap.
An open source analytics and visualization platform designed to work with Elasticsearch.
A free software tool written in PHP, intended to handle the administration of MySQL over the Web.
+ + + +
This is a link.
${choiceRequired}
Algunas herramientas externas proporcionan un descriptor XML que incluye la URL y otra informaci\u00f3n de configuraci\u00f3n. Si su herramienta externa soporta el descriptor XML, copi\u00e9lo y p\u00e9guelo en este campo. +tool.xml.detail=
Algunas herramientas externas proporcionan un descriptor XML que incluye la URL y otra informaci\u00f3n de configuraci\u00f3n. Si su herramienta externa soporta el descriptor XML, c\u00f3pielo y p\u00e9guelo en este campo. tool.url=URL de la herramienta remota\: tool.url.detail= tool.key=Clave de la herramienta remota\: @@ -30,7 +30,6 @@ tool.secret.detail= page.title=Establecer el texto del bot\u00f3n\: page.title.detail=(Texto del men\u00fa de la herramienta) tool.title=Establecer el t\u00edtulo de la herramienta\: -tool.title.detail=(Sobre la herramienta) tool.fa_icon=Seleccionar un icono para esta herramienta\: new.page=Abrir en una nueva ventana\: new.page.detail= @@ -41,9 +40,9 @@ iframe.height.detail= toolorder=Orden de las herramientas\: toolorder.detail= debug.launch=Depurar lanzamiento\: -debug.launch.detail=Cuando se seleccionar "Depurar lanzamiento", la herramienta se para antes de lanzar y mostrar los datos del lanzamiento. -launch.privacy=Liberar informaci\u00f3n de la orla -launch.privacy.detail=Estas opciones permiten controlar qu\u00e9 informaci\u00f3n se libera a la herramienta externa. Algunas exigen informaci\u00f3n de la orla para funcionar. +debug.launch.detail=Cuando se selecciona "Depurar lanzamiento", la herramienta se para antes de lanzar y mostrar los datos del lanzamiento. +launch.privacy=Liberar informaci\u00f3n de participantes +launch.privacy.detail=Estas opciones permiten controlar qu\u00e9 informaci\u00f3n se libera a la herramienta externa. Algunas exigen informaci\u00f3n de participantes para funcionar. privacy.releasename=Enviar el nombre de los usuarios a la herramienta externa privacy.releaseemail=Enviar la direcci\u00f3n de correo de los usuarios a la herramienta externa privacy.allowroster=Permitir que la herramienta externa obtenga el listado de estudiantes del curso @@ -53,7 +52,7 @@ privacy.allowsettings=Permitir que la herramienta externa registre y recupere su allowsettings.detail=Permite que la herramienta externa guarde y recupere su propia configuraci\u00f3n para esta ubicaci\u00f3n. Esto s\u00f3lo da a la herramienta acceso a un espacio seguro donde guardar y leer sus propios datos. No se da a la herramienta potestad para acceder a otros datos. contentlink.legend=Configuraci\u00f3n del enlace a contenidos contentlink.label=Contenido del enlace a la URL -contentlink.detail=Permite especificar un enlace a un contenido que ser\u00e1 enviado a la herramienta externa. Este contenido debe estar disponible para usuarios no autenticados. El uso t\u00edpico de esta caracter\u00edsticas es para enviar un archivo (un objeto SCORM) a la herramienta externa para que sea esta quien lo reproduzca. +contentlink.detail=Permite especificar un enlace a un contenido que ser\u00e1 enviado a la herramienta externa. Este contenido debe estar disponible para usuarios no autenticados. El uso t\u00edpico de esta caracter\u00edsticas es para enviar un archivo (un objeto SCORM) a la herramienta externa para que sea \u00e9sta quien lo reproduzca. launch.custom=Par\u00e1metros de lanzamiento definidos por el usuario launch.custom.detail=Es posible a\u00f1adir una serie de par\u00e1metros de lanzamiento utilizando el esquema nombre\=valor incluyendo varios en la misma l\u00ednea separados por punto y coma (;). update.options=Actualizar opciones @@ -82,7 +81,7 @@ launch.create.site=Imposible crear el sitio launch.role.missing=No puede encontrar el rol launch.join.site=No puede a\u00f1adir un usuario al sitio launch.tool.search=Error buscando en las herramientas -launch.tool.add=No puede a\u00f1\u00f1adir la herramienta al sitio +launch.tool.add=No se puede a\u00f1adir la herramienta al sitio launch.continue=Presionar para continuar la herramienta launch.user.invalid=Imposible encontrar el usuario launch.user.noeid=No es posible determinar el eid @@ -107,7 +106,7 @@ gradable.information=Enviando las notas a Calificaciones gradable.title=Seleccione un elemento de Calificaciones\: gradable.nograde=No se aceptan notas de esta herramienta gradable.detail=Tenga cuidado con cambiar este valor. Si lo hace, las notas existentes no se mover\u00e1n al nuevo \u00edtem de calificaci\u00f3n. Solo las notas futuras recogidas desde la herramienta ser\u00e1n dirigidas al nuevo \u00edtem de calificaci\u00f3n. -gradable.newassignment=Crear un \u00edtem en el libro de notas +gradable.newassignment=Crear un \u00edtem en Calificaciones gradable.newassignment.detail=Esto crea un \u00edtem en Calificaciones y canaliza las notas a este nuevo \u00edtem. S\u00f3lo tiene que crear el \u00edtem una vez. error.gradable.badassign=Se ha seleccionado un elemento incorrecto de Calificaciones error.gradable.badcreate=No pudo crearse un \u00edtem de calificaci\u00f3n diff --git a/lti/lti-tool/src/bundle/basiclti-events_es.properties b/lti/lti-tool/src/bundle/basiclti-events_es.properties index 0c67b00249dc..0ae421f38961 100644 --- a/lti/lti-tool/src/bundle/basiclti-events_es.properties +++ b/lti/lti-tool/src/bundle/basiclti-events_es.properties @@ -1,2 +1,2 @@ # this defines the entity description for basiclti-events -basiclti-events=Activa el env\u00edo de informaci\u00f3n sobre el uso de Basic LTI a SiteStats. No hay interfaces usables aqu\u00ed. +basiclti-events=Activa el env\u00edo de informaci\u00f3n sobre el uso de LTI a Estad\u00edsticas. No hay interfaces usables aqu\u00ed. diff --git a/lti/lti-tool/src/bundle/ltitool_es.properties b/lti/lti-tool/src/bundle/ltitool_es.properties index 9c59b34576bb..5ce17e7b8ecb 100644 --- a/lti/lti-tool/src/bundle/ltitool_es.properties +++ b/lti/lti-tool/src/bundle/ltitool_es.properties @@ -1,7 +1,8 @@ gen.options=Opciones gen.cancel=Cancelar gen.save=Guardar -gen.done=Hecho +gen.continue=Continuar +gen.done=Aceptar gen.edit=Editar gen.test=Probar gen.delete=Eliminar @@ -15,7 +16,7 @@ gen.success=\u00c9xito gen.failure=Fallo gen.tools=Ver las herramientas gen.add=A\u00f1adir -gen.remove=Quitar +gen.remove=Borrar gen.register=Registro gen.reregister=Re-registro gen.activate=Activar @@ -28,10 +29,10 @@ tool.title=Herramientas Externas (LTI) tool.in.site=Enlaces de las herramientas tool.in.system=Herramientas instaladas add.auto=Registro din\u00e1mico LTI -tool.description.sites=Abajo se muestran las herramientas externas que tienen enlaces con un sitio. Una herramienta instalada puede tener varios enlaces. Seleccione "Editar" para revisar las opciones de un enlace concreto. Seleccione "Crear enlace a la herramienta" para crear un nuevo enlace. -tool.description.sites.helper=Abajo se muestran las herramientas externas que tienen enlaces en este sitio. Una herramienta instalada puede tener varios enlaces. Seleccione "Editar" para revisar las opciones un enlace concreto. Podr\u00eda haber referencias creadas manualmente a esos enlaces en el sitio. Si se borra un enlace de esta pantalla, esas referencias fallar\u00e1n, por lo que debe ser cuidadoso cuando borre enlaces de esta pantalla. +tool.description.sites=Abajo se muestran las herramientas externas que tienen enlaces con un sitio. Una herramienta instalada puede tener varios enlaces. Normalmente se crean cuando se coloca una herramienta LTI en un sitio utilizando Contenidos, Tareas, Informaci\u00f3n del sitio o el Editor de texto enriquecido. No es habitual crear o editar estos elementos desde esta p\u00e1gina. Seleccione "Editar" para revisar la configuraci\u00f3n de un enlace en particular. Seleccione "Crear enlace de herramienta" para a\u00f1adir un nuevo enlace. +tool.description.sites.helper=Abajo se muestran las herramientas externas que tienen enlaces con un sitio. Una herramienta instalada puede tener varios enlaces. Normalmente se crean cuando se coloca una herramienta LTI en un sitio utilizando Contenidos, Tareas, Informaci\u00f3n del sitio o el Editor de texto enriquecido. No es habitual crear o editar estos elementos desde esta p\u00e1gina. Seleccione "Editar" para revisar la configuraci\u00f3n de un enlace en particular. Puede haber referencias codificadas a estos enlaces en todo el sitio. Si elimina un enlace desde esta pantalla, esas referencias desaparecer\u00e1n, as\u00ed que tenga cuidado al eliminar enlaces desde esta pantalla. tool.description.system=Abajo se muestran herramientas externas que han sido a\u00f1adidas al sistema. Seleccione "Editar" para revisar las opciones de la herramienta. Selecciones "A\u00f1adir herramienta externa al sistema" para a\u00f1adir nuevas herramientas externas. -tool.post.insert=Valores LTIU 1.3 (Proporcionados por la herramienta) +tool.post.insert=Valores LTI 1.3 (Proporcionados por la herramienta) tool.view=Ver la herramienta instalada tool.put=Herramienta externa tool.delete=Borrar una herramienta instalada @@ -39,7 +40,7 @@ tool.delete.sure=Esta herramienta ser\u00e1 borrada de todos los sitios. \u00bfD tool.site.ids.input.info=Nota\: Introducir los sitios en l\u00edneas diferentes tool.site.insert=Lanzar la herramienta a sitios tool.site.edit=Editar el nombre de la tool del sitio -tool.site.deploy=Lanzar la herramienta a sitios +tool.site.deploy=Despliegue manual de la herramienta tool.site.deploy.success=Lanzar la herramienta a sitios {0} tool.site.edit.success=Actualizar el nombre de la tool del sitio. tool.site.delete=Eliminar herramienta del sitio @@ -52,7 +53,7 @@ error.transfer.fail=La transferencia ha fallado error.transfer.missing=Por favor, seleccione una herramienta error.maintain.transfer=Debe ser administrador para poder transferir tool.table=Herramientas externas (LTI) instaladas -tool.none=No hay herramientas disponibles en la lista de instaladas +tool.none=No hay herramientas disponibles tool.note=
Si tiene una clave-valor, instale primero esta herramienta usando esta pantalla y entonces lance la herramienta. Puede comprobar el lanzamiento de la herramienta y obtener una URL para su herramienta desde la pantalla de configuraci\u00f3n.
+ * Attach to a tag and provide the user uuid in the model + * * e.g. * - * <img wicket:id="photo" /> + * * * * * add(new ProfileImage("photo", new Model(userUuid))); * - * + * * For different size images, override the setSize - * + * * Note that browsers will cache the image for a while (this is the point!) so if users are changing images all the time, a browser cache flush is in order for the display to remain current. - * + * * @author Steve Swinsburg (steve.swinsburg@gmail.com) */ @Setter public class ProfileImage extends WebComponent { private static final long serialVersionUID = 1L; - - /** - * -- SETTER -- - * Use to specify ProfileConstants.PROFILE_IMAGE_THUMBNAIL or ProfileConstants.PROFILE_IMAGE_AVATAR - * Leave as is to use the main size image - * - * @param size - */ - private int size = ProfileConstants.PROFILE_IMAGE_MAIN; //default + private int size = ProfileConstants.PROFILE_IMAGE_MAIN; //default + private String siteId; public ProfileImage(String id, IModel model) { - super(id, model); + super(id, model); } @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); - checkComponentTag(tag, "img"); - + checkComponentTag(tag, "sakai-user-photo"); + String userUuid = this.getDefaultModelObjectAsString(); - - //determine size - String sizePart = ""; + tag.put("user-id", userUuid != null ? userUuid : ""); + + if (siteId != null) { + tag.put("site-id", siteId); + } + + String sizeClass = "large"; // default for main profile picture. switch (this.size) { case ProfileConstants.PROFILE_IMAGE_MAIN: { + sizeClass = "medium"; break; } - case ProfileConstants.PROFILE_IMAGE_THUMBNAIL: { - sizePart = "/thumb"; + case ProfileConstants.PROFILE_IMAGE_THUMBNAIL, ProfileConstants.PROFILE_IMAGE_AVATAR: { + sizeClass = "large-thumbnail"; break; } - case ProfileConstants.PROFILE_IMAGE_AVATAR: { - sizePart = "/avatar"; - break; - } - } - - //Force a reload - String url = "/direct/profile/"+userUuid + "/image" + sizePart + "?v=" + RandomStringUtils.randomAlphabetic(10); - - tag.put("src", url); - tag.put("alt", "User profile image"); + } + tag.put("classes", sizeClass); + tag.put("profile-popup", "off"); // Always turn off + } + @Override + public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) + { + // Nothing to render, the web component handles the rendering. } - - } diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html index f22c82721c0a..b9f9a7899378 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html @@ -35,21 +35,21 @@ - + [myProfileLabel] - + [otherProfileLabel] - + [preferencesLabel] diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java index 57cb9e0c3755..ca5dc6e030fb 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java @@ -21,7 +21,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.wicket.AttributeModifier; -import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.OnLoadHeaderItem; @@ -30,6 +29,7 @@ import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.Link; +import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; @@ -66,6 +66,10 @@ public class BasePage extends WebPage implements IHeaderContributor { Link myProfileLink; Link otherProfileLink; Link preferencesLink; + + WebMarkupContainer myProfileContainer; + WebMarkupContainer otherProfileContainer; + WebMarkupContainer preferencesContainer; public BasePage() { // super(); @@ -81,7 +85,8 @@ public BasePage() { // get currentUserUuid final String currentUserUuid = this.sakaiProxy.getCurrentUserId(); - // my profile link + // my profile link and container + myProfileContainer = new WebMarkupContainer("myProfileContainer"); this.myProfileLink = new Link("myProfileLink") { private static final long serialVersionUID = 1L; @@ -92,14 +97,16 @@ public void onClick() { }; this.myProfileLink.add(new Label("myProfileLabel", new ResourceModel("link.my.profile"))); this.myProfileLink.add(new AttributeModifier("title", new ResourceModel("link.my.profile.tooltip"))); + myProfileContainer.add(this.myProfileLink); if (!this.sakaiProxy.isMenuEnabledGlobally()) { this.myProfileLink.setVisible(false); } - add(this.myProfileLink); + add(myProfileContainer); - // other profile link + // other profile link and container + otherProfileContainer = new WebMarkupContainer("otherProfileContainer"); this.otherProfileLink = new Link("otherProfileLink") { private static final long serialVersionUID = 1L; @@ -109,9 +116,11 @@ public void onClick() { }; this.otherProfileLink.add(new Label("otherProfileLabel", new Model("INVISIBLE"))); this.otherProfileLink.setVisible(false); - add(this.otherProfileLink); + otherProfileContainer.add(this.otherProfileLink); + add(otherProfileContainer); - // preferences link + // preferences link and container + preferencesContainer = new WebMarkupContainer("preferencesContainer"); this.preferencesLink = new Link("preferencesLink") { private static final long serialVersionUID = 1L; @@ -122,11 +131,12 @@ public void onClick() { }; this.preferencesLink.add(new Label("preferencesLabel", new ResourceModel("link.my.preferences"))); this.preferencesLink.add(new AttributeModifier("title", new ResourceModel("link.my.preferences.tooltip"))); + preferencesContainer.add(this.preferencesLink); if (!this.sakaiProxy.isPreferenceEnabledGlobally()) { this.preferencesLink.setVisible(false); } - add(this.preferencesLink); + add(preferencesContainer); // rss link /* @@ -168,27 +178,10 @@ public void renderHead(final IHeaderResponse response) { */ public void setUserPreferredLocale() { final Locale locale = ProfileUtils.getUserPreferredLocale(); - log.debug("User preferred locale: " + locale); + log.debug("User preferred locale: {}", locale); getSession().setLocale(locale); } - /** - * Allow Pages to set the title - * - * @param model - */ - /* - * protected void setPageTitle(IModel model) { get("pageTitle").setDefaultModel(model); } - */ - - /** - * Disable a page nav link (PRFL-468) - */ - protected void disableLink(final Link l) { - l.add(new AttributeAppender("class", new Model("current"), " ")); - l.setEnabled(false); - } - /** * Parse a param * diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java index c0abc392242c..99d9c926161a 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java @@ -48,7 +48,8 @@ public MyPreferences() { log.debug("MyPreferences()"); - disableLink(preferencesLink); + preferencesLink.setEnabled(false); + preferencesContainer.add(new AttributeModifier("class", "current")); //get current user final String userUuid = sakaiProxy.getCurrentUserId(); diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html index 50862dac09c0..7c2334c01a0a 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html @@ -32,7 +32,7 @@ - + - - - - + + + + diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java index f21043b7f212..6ad775e82460 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java @@ -17,11 +17,11 @@ import lombok.extern.slf4j.Slf4j; import org.apache.wicket.RestartResponseException; -import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.AttributeModifier; import org.sakaiproject.profile2.model.ProfilePreferences; import org.sakaiproject.profile2.tool.components.ProfileImage; @@ -29,10 +29,12 @@ import org.sakaiproject.profile2.util.ProfileConstants; import org.sakaiproject.user.api.User; +import java.util.Objects; + @Slf4j public class ViewProfile extends BasePage { - public ViewProfile(final String userUuid, final String tab) { + public ViewProfile(final String userUuid, final String tab, final PageParameters parameters) { log.debug("ViewProfile()"); @@ -43,13 +45,13 @@ public ViewProfile(final String userUuid, final String tab) { // double check, if somehow got to own ViewPage, redirect to MyProfile instead if (userUuid.equals(currentUserId)) { - log.warn("ViewProfile: user " + userUuid + " accessed ViewProfile for self. Redirecting..."); + log.warn("ViewProfile: user {} accessed ViewProfile for self. Redirecting...", userUuid); throw new RestartResponseException(new MyProfile()); } // check if super user, to grant editing rights to another user's profile if (this.sakaiProxy.isSuperUser()) { - log.warn("ViewProfile: superUser " + currentUserId + " accessed ViewProfile for " + userUuid + ". Redirecting to allow edit."); + log.warn("ViewProfile: superUser {} accessed ViewProfile for {}. Redirecting to allow edit.", currentUserId, userUuid); throw new RestartResponseException(new MyProfile(userUuid)); } @@ -67,46 +69,41 @@ public ViewProfile(final String userUuid, final String tab) { otherProfileLink.get("otherProfileLabel").setDefaultModel( new StringResourceModel("link.other.profile").setParameters(userDisplayName)); otherProfileLink.setVisible(true); - disableLink(otherProfileLink); + otherProfileLink.setEnabled(false); + otherProfileContainer.add(new AttributeModifier("class", "current")); final String userType = user.getType(); final ProfilePreferences prefs = this.preferencesLogic.getPreferencesRecordForUser(userUuid); /* IMAGE */ - add(new ProfileImage("photo", new Model(userUuid))); + ProfileImage profileImage = new ProfileImage("photo", new Model(userUuid)); + if (parameters != null) { + String fromSiteId = getParamValue(parameters, "fromSiteId"); + if (fromSiteId != null) { + profileImage.setSiteId(fromSiteId); + } + } + add(profileImage); /* NAME */ final Label profileName = new Label("profileName", userDisplayName); add(profileName); add(new ViewProfilePanel("viewProfilePanel", userUuid, currentUserId)); - - /* SIDELINKS */ - final WebMarkupContainer sideLinks = new WebMarkupContainer("sideLinks"); - int visibleSideLinksCount = 0; - - visibleSideLinksCount++; - - // hide entire list if no links to show - if (visibleSideLinksCount == 0) { - sideLinks.setVisible(false); - } - - add(sideLinks); } /** * This constructor is called if we have a pageParameters object containing the userUuid as an id parameter Just redirects to normal * ViewProfile(String userUuid) - * - * @param parameters - */ + */ public ViewProfile(final PageParameters parameters) { - this(getParamValue(parameters, ProfileConstants.WICKET_PARAM_USERID), getParamValue(parameters, ProfileConstants.WICKET_PARAM_TAB)); + this(Objects.requireNonNull(getParamValue(parameters, ProfileConstants.WICKET_PARAM_USERID)), + getParamValue(parameters, ProfileConstants.WICKET_PARAM_TAB), + parameters); } public ViewProfile(final String userUuid) { - this(userUuid, null); + this(userUuid, null, null); } } diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java index e475fad1340c..fb287e30241c 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java @@ -84,7 +84,11 @@ public void onClick(Optional targetOptional) { editButton.add(new Label("editButtonLabel", new ResourceModel("button.edit"))); editButton.add(new AttributeModifier("aria-label", new ResourceModel("accessibility.edit.pronunciation"))); editButton.setOutputMarkupId(true); - if(userProfile.isLocked() && !sakaiProxy.isSuperUser()) { + + // Only show edit button if it's the user's own profile and it's not locked (unless superuser) + String currentUserId = sakaiProxy.getCurrentUserId(); + boolean isOwnProfile = currentUserId.equals(userProfile.getUserUuid()); + if(!isOwnProfile || (userProfile.isLocked() && !sakaiProxy.isSuperUser())) { editButton.setVisible(false); } add(editButton); diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html index a69b67fd0bfe..b5591fe2df5c 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html @@ -44,11 +44,33 @@ [nickname]
* e.g. * - * <img wicket:id="photo" /> + * * * * * add(new ProfileImage("photo", new Model(userUuid))); * - * + *
- * <img wicket:id="photo" /> + * *
* add(new ProfileImage("photo", new Model(userUuid))); *
* For different size images, override the setSize - * + *
* Note that browsers will cache the image for a while (this is the point!) so if users are changing images all the time, a browser cache flush is in order for the display to remain current. - * + * * @author Steve Swinsburg (steve.swinsburg@gmail.com) */ @Setter public class ProfileImage extends WebComponent { private static final long serialVersionUID = 1L; - - /** - * -- SETTER -- - * Use to specify ProfileConstants.PROFILE_IMAGE_THUMBNAIL or ProfileConstants.PROFILE_IMAGE_AVATAR - * Leave as is to use the main size image - * - * @param size - */ - private int size = ProfileConstants.PROFILE_IMAGE_MAIN; //default + private int size = ProfileConstants.PROFILE_IMAGE_MAIN; //default + private String siteId; public ProfileImage(String id, IModel model) { - super(id, model); + super(id, model); } @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); - checkComponentTag(tag, "img"); - + checkComponentTag(tag, "sakai-user-photo"); + String userUuid = this.getDefaultModelObjectAsString(); - - //determine size - String sizePart = ""; + tag.put("user-id", userUuid != null ? userUuid : ""); + + if (siteId != null) { + tag.put("site-id", siteId); + } + + String sizeClass = "large"; // default for main profile picture. switch (this.size) { case ProfileConstants.PROFILE_IMAGE_MAIN: { + sizeClass = "medium"; break; } - case ProfileConstants.PROFILE_IMAGE_THUMBNAIL: { - sizePart = "/thumb"; + case ProfileConstants.PROFILE_IMAGE_THUMBNAIL, ProfileConstants.PROFILE_IMAGE_AVATAR: { + sizeClass = "large-thumbnail"; break; } - case ProfileConstants.PROFILE_IMAGE_AVATAR: { - sizePart = "/avatar"; - break; - } - } - - //Force a reload - String url = "/direct/profile/"+userUuid + "/image" + sizePart + "?v=" + RandomStringUtils.randomAlphabetic(10); - - tag.put("src", url); - tag.put("alt", "User profile image"); + } + tag.put("classes", sizeClass); + tag.put("profile-popup", "off"); // Always turn off + } + @Override + public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) + { + // Nothing to render, the web component handles the rendering. } - - } diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html index f22c82721c0a..b9f9a7899378 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.html @@ -35,21 +35,21 @@ - + [myProfileLabel] - + [otherProfileLabel] - + [preferencesLabel] diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java index 57cb9e0c3755..ca5dc6e030fb 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/BasePage.java @@ -21,7 +21,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.wicket.AttributeModifier; -import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.OnLoadHeaderItem; @@ -30,6 +29,7 @@ import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.Link; +import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; @@ -66,6 +66,10 @@ public class BasePage extends WebPage implements IHeaderContributor { Link myProfileLink; Link otherProfileLink; Link preferencesLink; + + WebMarkupContainer myProfileContainer; + WebMarkupContainer otherProfileContainer; + WebMarkupContainer preferencesContainer; public BasePage() { // super(); @@ -81,7 +85,8 @@ public BasePage() { // get currentUserUuid final String currentUserUuid = this.sakaiProxy.getCurrentUserId(); - // my profile link + // my profile link and container + myProfileContainer = new WebMarkupContainer("myProfileContainer"); this.myProfileLink = new Link("myProfileLink") { private static final long serialVersionUID = 1L; @@ -92,14 +97,16 @@ public void onClick() { }; this.myProfileLink.add(new Label("myProfileLabel", new ResourceModel("link.my.profile"))); this.myProfileLink.add(new AttributeModifier("title", new ResourceModel("link.my.profile.tooltip"))); + myProfileContainer.add(this.myProfileLink); if (!this.sakaiProxy.isMenuEnabledGlobally()) { this.myProfileLink.setVisible(false); } - add(this.myProfileLink); + add(myProfileContainer); - // other profile link + // other profile link and container + otherProfileContainer = new WebMarkupContainer("otherProfileContainer"); this.otherProfileLink = new Link("otherProfileLink") { private static final long serialVersionUID = 1L; @@ -109,9 +116,11 @@ public void onClick() { }; this.otherProfileLink.add(new Label("otherProfileLabel", new Model("INVISIBLE"))); this.otherProfileLink.setVisible(false); - add(this.otherProfileLink); + otherProfileContainer.add(this.otherProfileLink); + add(otherProfileContainer); - // preferences link + // preferences link and container + preferencesContainer = new WebMarkupContainer("preferencesContainer"); this.preferencesLink = new Link("preferencesLink") { private static final long serialVersionUID = 1L; @@ -122,11 +131,12 @@ public void onClick() { }; this.preferencesLink.add(new Label("preferencesLabel", new ResourceModel("link.my.preferences"))); this.preferencesLink.add(new AttributeModifier("title", new ResourceModel("link.my.preferences.tooltip"))); + preferencesContainer.add(this.preferencesLink); if (!this.sakaiProxy.isPreferenceEnabledGlobally()) { this.preferencesLink.setVisible(false); } - add(this.preferencesLink); + add(preferencesContainer); // rss link /* @@ -168,27 +178,10 @@ public void renderHead(final IHeaderResponse response) { */ public void setUserPreferredLocale() { final Locale locale = ProfileUtils.getUserPreferredLocale(); - log.debug("User preferred locale: " + locale); + log.debug("User preferred locale: {}", locale); getSession().setLocale(locale); } - /** - * Allow Pages to set the title - * - * @param model - */ - /* - * protected void setPageTitle(IModel model) { get("pageTitle").setDefaultModel(model); } - */ - - /** - * Disable a page nav link (PRFL-468) - */ - protected void disableLink(final Link l) { - l.add(new AttributeAppender("class", new Model("current"), " ")); - l.setEnabled(false); - } - /** * Parse a param * diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java index c0abc392242c..99d9c926161a 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyPreferences.java @@ -48,7 +48,8 @@ public MyPreferences() { log.debug("MyPreferences()"); - disableLink(preferencesLink); + preferencesLink.setEnabled(false); + preferencesContainer.add(new AttributeModifier("class", "current")); //get current user final String userUuid = sakaiProxy.getCurrentUserId(); diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html index 50862dac09c0..7c2334c01a0a 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/MyProfile.html @@ -32,7 +32,7 @@ - + - - - - + + + + diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java index f21043b7f212..6ad775e82460 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/ViewProfile.java @@ -17,11 +17,11 @@ import lombok.extern.slf4j.Slf4j; import org.apache.wicket.RestartResponseException; -import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.AttributeModifier; import org.sakaiproject.profile2.model.ProfilePreferences; import org.sakaiproject.profile2.tool.components.ProfileImage; @@ -29,10 +29,12 @@ import org.sakaiproject.profile2.util.ProfileConstants; import org.sakaiproject.user.api.User; +import java.util.Objects; + @Slf4j public class ViewProfile extends BasePage { - public ViewProfile(final String userUuid, final String tab) { + public ViewProfile(final String userUuid, final String tab, final PageParameters parameters) { log.debug("ViewProfile()"); @@ -43,13 +45,13 @@ public ViewProfile(final String userUuid, final String tab) { // double check, if somehow got to own ViewPage, redirect to MyProfile instead if (userUuid.equals(currentUserId)) { - log.warn("ViewProfile: user " + userUuid + " accessed ViewProfile for self. Redirecting..."); + log.warn("ViewProfile: user {} accessed ViewProfile for self. Redirecting...", userUuid); throw new RestartResponseException(new MyProfile()); } // check if super user, to grant editing rights to another user's profile if (this.sakaiProxy.isSuperUser()) { - log.warn("ViewProfile: superUser " + currentUserId + " accessed ViewProfile for " + userUuid + ". Redirecting to allow edit."); + log.warn("ViewProfile: superUser {} accessed ViewProfile for {}. Redirecting to allow edit.", currentUserId, userUuid); throw new RestartResponseException(new MyProfile(userUuid)); } @@ -67,46 +69,41 @@ public ViewProfile(final String userUuid, final String tab) { otherProfileLink.get("otherProfileLabel").setDefaultModel( new StringResourceModel("link.other.profile").setParameters(userDisplayName)); otherProfileLink.setVisible(true); - disableLink(otherProfileLink); + otherProfileLink.setEnabled(false); + otherProfileContainer.add(new AttributeModifier("class", "current")); final String userType = user.getType(); final ProfilePreferences prefs = this.preferencesLogic.getPreferencesRecordForUser(userUuid); /* IMAGE */ - add(new ProfileImage("photo", new Model(userUuid))); + ProfileImage profileImage = new ProfileImage("photo", new Model(userUuid)); + if (parameters != null) { + String fromSiteId = getParamValue(parameters, "fromSiteId"); + if (fromSiteId != null) { + profileImage.setSiteId(fromSiteId); + } + } + add(profileImage); /* NAME */ final Label profileName = new Label("profileName", userDisplayName); add(profileName); add(new ViewProfilePanel("viewProfilePanel", userUuid, currentUserId)); - - /* SIDELINKS */ - final WebMarkupContainer sideLinks = new WebMarkupContainer("sideLinks"); - int visibleSideLinksCount = 0; - - visibleSideLinksCount++; - - // hide entire list if no links to show - if (visibleSideLinksCount == 0) { - sideLinks.setVisible(false); - } - - add(sideLinks); } /** * This constructor is called if we have a pageParameters object containing the userUuid as an id parameter Just redirects to normal * ViewProfile(String userUuid) - * - * @param parameters - */ + */ public ViewProfile(final PageParameters parameters) { - this(getParamValue(parameters, ProfileConstants.WICKET_PARAM_USERID), getParamValue(parameters, ProfileConstants.WICKET_PARAM_TAB)); + this(Objects.requireNonNull(getParamValue(parameters, ProfileConstants.WICKET_PARAM_USERID)), + getParamValue(parameters, ProfileConstants.WICKET_PARAM_TAB), + parameters); } public ViewProfile(final String userUuid) { - this(userUuid, null); + this(userUuid, null, null); } } diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java index e475fad1340c..fb287e30241c 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/MyNamePronunciationDisplay.java @@ -84,7 +84,11 @@ public void onClick(Optional targetOptional) { editButton.add(new Label("editButtonLabel", new ResourceModel("button.edit"))); editButton.add(new AttributeModifier("aria-label", new ResourceModel("accessibility.edit.pronunciation"))); editButton.setOutputMarkupId(true); - if(userProfile.isLocked() && !sakaiProxy.isSuperUser()) { + + // Only show edit button if it's the user's own profile and it's not locked (unless superuser) + String currentUserId = sakaiProxy.getCurrentUserId(); + boolean isOwnProfile = currentUserId.equals(userProfile.getUserUuid()); + if(!isOwnProfile || (userProfile.isLocked() && !sakaiProxy.isSuperUser())) { editButton.setVisible(false); } add(editButton); diff --git a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html index a69b67fd0bfe..b5591fe2df5c 100644 --- a/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html +++ b/profile2/tool/src/java/org/sakaiproject/profile2/tool/pages/panels/ViewProfilePanel.html @@ -44,11 +44,33 @@ [nickname]
- - -
- - - - -