From f4918ea73fce9c4e094be94e4420504b72347d7e Mon Sep 17 00:00:00 2001
From: Michael Simon <simon@kit.edu>
Date: Wed, 3 Jul 2024 08:01:49 +0200
Subject: [PATCH] ISSUE-191 make changes to project management

This commit includes a few changes:
* Add self as member with project creation
* Correct layout of project invitation page
* Add page to edit project admins
* Create sub project page
---
 .../UserEditLocalProjectAdminsBean.java       |  210 +++
 .../project/UserProjectCreateNewBean.java     |   20 +
 .../project/UserShowLocalProjectBean.java     |    3 +-
 .../project/UserSubprojectCreateNewBean.java  |  142 ++
 .../primefaces-kit-theme/theme-old.css        | 1188 -----------------
 .../main/resources/msg/messages_de.properties |   14 +-
 .../main/resources/msg/messages_en.properties |   14 +-
 .../main/resources/msg/messages_fr.properties |   14 +-
 .../admin/project/show-local-project.xhtml    |    5 +-
 .../connect-local-project-to-service.xhtml    |   62 +-
 .../webapp/project/create-new-project.xhtml   |   14 +-
 .../project/create-new-subproject.xhtml       |   77 ++
 .../project/edit-local-project-admins.xhtml   |  127 ++
 .../src/main/webapp/project/index.xhtml       |   14 +-
 .../webapp/project/invite-to-project.xhtml    |   61 +-
 .../webapp/project/show-local-project.xhtml   |   66 +-
 16 files changed, 743 insertions(+), 1288 deletions(-)
 create mode 100644 bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserEditLocalProjectAdminsBean.java
 create mode 100644 bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserSubprojectCreateNewBean.java
 delete mode 100644 bwreg-webapp/src/main/resources/META-INF/resources/primefaces-kit-theme/theme-old.css
 create mode 100644 bwreg-webapp/src/main/webapp/project/create-new-subproject.xhtml
 create mode 100644 bwreg-webapp/src/main/webapp/project/edit-local-project-admins.xhtml

diff --git a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserEditLocalProjectAdminsBean.java b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserEditLocalProjectAdminsBean.java
new file mode 100644
index 000000000..a6b445669
--- /dev/null
+++ b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserEditLocalProjectAdminsBean.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Michael Simon.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Public License v3.0
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/gpl.html
+ * 
+ * Contributors:
+ *     Michael Simon - initial
+ ******************************************************************************/
+package edu.kit.scc.webreg.bean.project;
+
+import static edu.kit.scc.webreg.dao.ops.RqlExpressions.equal;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.primefaces.model.LazyDataModel;
+
+import edu.kit.scc.webreg.entity.UserEntity;
+import edu.kit.scc.webreg.entity.UserStatus;
+import edu.kit.scc.webreg.entity.identity.IdentityEntity;
+import edu.kit.scc.webreg.entity.project.LocalProjectEntity;
+import edu.kit.scc.webreg.entity.project.ProjectAdminType;
+import edu.kit.scc.webreg.entity.project.ProjectIdentityAdminEntity;
+import edu.kit.scc.webreg.entity.project.ProjectMembershipEntity;
+import edu.kit.scc.webreg.entity.project.ProjectServiceEntity;
+import edu.kit.scc.webreg.exc.NotAuthorizedException;
+import edu.kit.scc.webreg.model.GenericLazyDataModelImpl;
+import edu.kit.scc.webreg.service.UserService;
+import edu.kit.scc.webreg.service.project.LocalProjectService;
+import edu.kit.scc.webreg.service.project.ProjectService;
+import edu.kit.scc.webreg.session.SessionManager;
+import edu.kit.scc.webreg.util.FacesMessageGenerator;
+import jakarta.faces.event.ComponentSystemEvent;
+import jakarta.faces.view.ViewScoped;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+
+@Named
+@ViewScoped
+public class UserEditLocalProjectAdminsBean implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@Inject
+	private SessionManager session;
+
+	@Inject
+	private LocalProjectService service;
+
+	@Inject
+	private UserService userService;
+
+	@Inject
+	private ProjectService projectService;
+
+	@Inject
+	private FacesMessageGenerator messageGenerator;
+
+	private LocalProjectEntity entity;
+	private Set<IdentityEntity> memberList;
+	private Set<IdentityEntity> effectiveMemberList;
+	private List<ProjectIdentityAdminEntity> adminList;
+	private List<ProjectServiceEntity> serviceList;
+	private LazyDataModel<UserEntity> allUserList;
+
+	private Long projectId;
+
+	private ProjectIdentityAdminEntity adminIdentity;
+
+	private Boolean savePossible = false;
+
+	private ProjectAdminType selectedAdminType;
+
+	public void preRenderView(ComponentSystemEvent ev) {
+		if (entity == null) {
+			entity = service.fetch(projectId);
+		}
+
+		for (ProjectIdentityAdminEntity a : getAdminList()) {
+			if (a.getIdentity().getId().equals(session.getIdentityId())) {
+				adminIdentity = a;
+				break;
+			}
+		}
+
+		if (adminIdentity == null) {
+			throw new NotAuthorizedException("Not authorized");
+		} else {
+			if (adminIdentity.getType().equals(ProjectAdminType.READ) || adminIdentity.getType().equals(ProjectAdminType.READ_WRITE)) {
+				throw new NotAuthorizedException("Not authorized. You need Admin or Owner rights.");
+			}
+		}
+	}
+
+	public void addAdmin(IdentityEntity i) {
+		if (getSelectedAdminType().equals(ProjectAdminType.OWNER) && (! adminIdentity.getType().equals(ProjectAdminType.OWNER))) {
+			messageGenerator.addResolvedErrorMessage("project.edit_admins.cant_add_owner_as_admin");
+			return;
+		}
+
+		projectService.addAdminToProject(entity, i, getSelectedAdminType(), "idty-" + session.getIdentityId());
+		adminList = null;
+	}
+
+	public void removeAdmin(ProjectIdentityAdminEntity pia) {
+		if (ProjectAdminType.OWNER.equals(pia.getType())) {
+			// Only OWNERs can remove OWNERs
+			if (! adminIdentity.getType().equals(ProjectAdminType.OWNER)) {
+				messageGenerator.addResolvedErrorMessage("project.edit_admins.cant_remove_owner_as_admin");
+				return;
+			}
+
+			if (getAdminList().stream().filter(a -> ProjectAdminType.OWNER.equals(a.getType())).count() <= 1L) {
+				messageGenerator.addResolvedErrorMessage("project.edit_admins.cant_remove_last_owner");
+				return;
+			}
+		}
+		projectService.removeAdminFromProject(pia, "idty-" + session.getIdentityId());
+		adminList = null;
+	}
+
+	public LocalProjectEntity getEntity() {
+		return entity;
+	}
+
+	public void setEntity(LocalProjectEntity entity) {
+		this.entity = entity;
+	}
+
+	public Long getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(Long projectId) {
+		this.projectId = projectId;
+	}
+
+	public Set<IdentityEntity> getMemberList() {
+		if (memberList == null) {
+			List<ProjectMembershipEntity> tempMemberList = projectService.findMembersForProject(getEntity());
+			memberList = new HashSet<IdentityEntity>();
+			for (ProjectMembershipEntity pme : tempMemberList) {
+				memberList.add(pme.getIdentity());
+			}
+		}
+		return memberList;
+	}
+
+	public List<ProjectIdentityAdminEntity> getAdminList() {
+		if (adminList == null) {
+			adminList = projectService.findAdminsForProject(entity);
+		}
+		return adminList;
+	}
+
+	public List<ProjectServiceEntity> getServiceList() {
+		if (serviceList == null) {
+			serviceList = projectService.findServicesForProject(entity);
+		}
+		return serviceList;
+	}
+
+	public LazyDataModel<UserEntity> getAllUserList() {
+		if (allUserList == null) {
+			allUserList = new GenericLazyDataModelImpl<UserEntity, UserService>(userService,
+					equal("userStatus", UserStatus.ACTIVE));
+		}
+		return allUserList;
+	}
+
+	public Boolean getSavePossible() {
+		return savePossible;
+	}
+
+	public ProjectIdentityAdminEntity getAdminIdentity() {
+		return adminIdentity;
+	}
+
+	public Set<IdentityEntity> getEffectiveMemberList() {
+		if (effectiveMemberList == null) {
+			List<ProjectMembershipEntity> tempMemberList = projectService.findMembersForProject(entity, true);
+			effectiveMemberList = new HashSet<IdentityEntity>();
+			for (ProjectMembershipEntity pme : tempMemberList) {
+				effectiveMemberList.add(pme.getIdentity());
+			}
+		}
+		return effectiveMemberList;
+	}
+
+	public ProjectAdminType getSelectedAdminType() {
+		return selectedAdminType;
+	}
+
+	public void setSelectedAdminType(ProjectAdminType selectedAdminType) {
+		this.selectedAdminType = selectedAdminType;
+	}
+
+	public ProjectAdminType[] getAdminTypes() {
+		if (adminIdentity.getType().equals(ProjectAdminType.OWNER))
+			return new ProjectAdminType[] { ProjectAdminType.OWNER, ProjectAdminType.ADMIN, ProjectAdminType.READ_WRITE, ProjectAdminType.READ };
+		else if (adminIdentity.getType().equals(ProjectAdminType.ADMIN))
+			return new ProjectAdminType[] { ProjectAdminType.ADMIN, ProjectAdminType.READ_WRITE, ProjectAdminType.READ };
+		else
+			return new ProjectAdminType[] { };
+	}
+}
diff --git a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserProjectCreateNewBean.java b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserProjectCreateNewBean.java
index a29c46c6b..185cf8aea 100644
--- a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserProjectCreateNewBean.java
+++ b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserProjectCreateNewBean.java
@@ -21,6 +21,7 @@ import edu.kit.scc.webreg.entity.identity.IdentityEntity;
 import edu.kit.scc.webreg.entity.project.LocalProjectEntity;
 import edu.kit.scc.webreg.service.identity.IdentityService;
 import edu.kit.scc.webreg.service.project.LocalProjectService;
+import edu.kit.scc.webreg.service.project.ProjectService;
 import edu.kit.scc.webreg.session.SessionManager;
 
 @Named
@@ -35,12 +36,17 @@ public class UserProjectCreateNewBean implements Serializable {
 	@Inject
 	private LocalProjectService localProjectService;
 
+	@Inject
+	private ProjectService projectService;
+	
 	@Inject
 	private IdentityService identityService;
 
 	private IdentityEntity identity;
 	private LocalProjectEntity entity;
 
+	private Boolean selfMember;
+	
 	public void preRenderView(ComponentSystemEvent ev) {
 
 	}
@@ -54,6 +60,9 @@ public class UserProjectCreateNewBean implements Serializable {
 
 	public String save() {
 		entity = localProjectService.save(entity, getIdentity().getId());
+		if (getSelfMember()) {
+			projectService.addProjectMember(entity, getIdentity(), "idty-" + getIdentity().getId());
+		}
 		return "show-local-project.xhtml?id=" + entity.getId() + "&faces-redirect=true";
 	}
 
@@ -71,4 +80,15 @@ public class UserProjectCreateNewBean implements Serializable {
 	public void setEntity(LocalProjectEntity entity) {
 		this.entity = entity;
 	}
+
+	public Boolean getSelfMember() {
+		if (selfMember == null) {
+			selfMember = Boolean.FALSE;
+		}
+		return selfMember;
+	}
+
+	public void setSelfMember(Boolean selfMember) {
+		this.selfMember = selfMember;
+	}
 }
diff --git a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserShowLocalProjectBean.java b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserShowLocalProjectBean.java
index a17c24d60..6560b451c 100644
--- a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserShowLocalProjectBean.java
+++ b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserShowLocalProjectBean.java
@@ -21,6 +21,7 @@ import jakarta.inject.Named;
 import edu.kit.scc.webreg.entity.project.LocalProjectEntity;
 import edu.kit.scc.webreg.entity.project.LocalProjectEntity_;
 import edu.kit.scc.webreg.entity.project.ProjectAdminType;
+import edu.kit.scc.webreg.entity.project.ProjectEntity_;
 import edu.kit.scc.webreg.entity.project.ProjectIdentityAdminEntity;
 import edu.kit.scc.webreg.entity.project.ProjectMembershipEntity;
 import edu.kit.scc.webreg.entity.project.ProjectServiceEntity;
@@ -84,7 +85,7 @@ public class UserShowLocalProjectBean implements Serializable {
 
 	public LocalProjectEntity getEntity() {
 		if (entity == null) {
-			entity = service.findByIdWithAttrs(id, LocalProjectEntity_.projectServices);
+			entity = service.findByIdWithAttrs(id, LocalProjectEntity_.projectServices, ProjectEntity_.childProjects);
 		}
 
 		return entity;
diff --git a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserSubprojectCreateNewBean.java b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserSubprojectCreateNewBean.java
new file mode 100644
index 000000000..41d71734f
--- /dev/null
+++ b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/project/UserSubprojectCreateNewBean.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Michael Simon.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Public License v3.0
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/gpl.html
+ * 
+ * Contributors:
+ *     Michael Simon - initial
+ ******************************************************************************/
+package edu.kit.scc.webreg.bean.project;
+
+import java.io.Serializable;
+import java.util.List;
+
+import edu.kit.scc.webreg.entity.identity.IdentityEntity;
+import edu.kit.scc.webreg.entity.project.LocalProjectEntity;
+import edu.kit.scc.webreg.entity.project.ProjectAdminType;
+import edu.kit.scc.webreg.entity.project.ProjectIdentityAdminEntity;
+import edu.kit.scc.webreg.exc.NotAuthorizedException;
+import edu.kit.scc.webreg.service.identity.IdentityService;
+import edu.kit.scc.webreg.service.project.LocalProjectService;
+import edu.kit.scc.webreg.service.project.ProjectService;
+import edu.kit.scc.webreg.session.SessionManager;
+import jakarta.faces.event.ComponentSystemEvent;
+import jakarta.faces.view.ViewScoped;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+
+@Named
+@ViewScoped
+public class UserSubprojectCreateNewBean implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@Inject
+	private SessionManager session;
+
+	@Inject
+	private LocalProjectService localProjectService;
+
+	@Inject
+	private ProjectService projectService;
+	
+	@Inject
+	private IdentityService identityService;
+
+	private IdentityEntity identity;
+	private LocalProjectEntity entity;
+
+	private Boolean selfMember;
+	private Long parentId;
+	private LocalProjectEntity parentProject;
+	
+	private ProjectIdentityAdminEntity adminIdentity;
+	private List<ProjectIdentityAdminEntity> adminList;
+	
+	public void preRenderView(ComponentSystemEvent ev) {
+		if (! getParentProject().getSubProjectsAllowed()) {
+			throw new NotAuthorizedException("Subpropjects are not allowed for this project");
+		}
+		
+		for (ProjectIdentityAdminEntity a : getAdminList()) {
+			if (a.getIdentity().getId().equals(session.getIdentityId())) {
+				adminIdentity = a;
+				break;
+			}
+		}
+
+		if (adminIdentity == null) {
+			throw new NotAuthorizedException("Not authorized");
+		} else {
+			if (! adminIdentity.getType().equals(ProjectAdminType.OWNER)) {
+				throw new NotAuthorizedException("Not authorized. You need Owner rights on the parent project.");
+			}
+		}
+	}
+
+	public IdentityEntity getIdentity() {
+		if (identity == null) {
+			identity = identityService.fetch(session.getIdentityId());
+		}
+		return identity;
+	}
+
+	public String save() {
+		entity.setParentProject(getParentProject());
+		entity = localProjectService.save(entity, getIdentity().getId());
+		if (getSelfMember()) {
+			projectService.addProjectMember(entity, getIdentity(), "idty-" + getIdentity().getId());
+		}
+		return "show-local-project.xhtml?id=" + entity.getId() + "&faces-redirect=true";
+	}
+
+	public String cancel() {
+		return "index.xhtml?faces-redirect=true";
+	}
+
+	public LocalProjectEntity getEntity() {
+		if (entity == null) {
+			entity = localProjectService.createNew();
+		}
+		return entity;
+	}
+
+	public void setEntity(LocalProjectEntity entity) {
+		this.entity = entity;
+	}
+
+	public Boolean getSelfMember() {
+		if (selfMember == null) {
+			selfMember = Boolean.FALSE;
+		}
+		return selfMember;
+	}
+
+	public void setSelfMember(Boolean selfMember) {
+		this.selfMember = selfMember;
+	}
+
+	public Long getParentId() {
+		return parentId;
+	}
+
+	public void setParentId(Long parentId) {
+		this.parentId = parentId;
+	}
+
+	public LocalProjectEntity getParentProject() {
+		if (parentProject == null) {
+			parentProject = localProjectService.fetch(getParentId());
+		}
+		return parentProject;
+	}
+	
+	public List<ProjectIdentityAdminEntity> getAdminList() {
+		if (adminList == null) {
+			adminList = projectService.findAdminsForProject(getParentProject());
+		}
+		return adminList;
+	}
+}
diff --git a/bwreg-webapp/src/main/resources/META-INF/resources/primefaces-kit-theme/theme-old.css b/bwreg-webapp/src/main/resources/META-INF/resources/primefaces-kit-theme/theme-old.css
deleted file mode 100644
index 7671402d5..000000000
--- a/bwreg-webapp/src/main/resources/META-INF/resources/primefaces-kit-theme/theme-old.css
+++ /dev/null
@@ -1,1188 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2014 Michael Simon.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the GNU Public License v3.0
-# which accompanies this distribution, and is available at
-# http://www.gnu.org/licenses/gpl.html
-# 
-# Contributors:
-#     Michael Simon - initial
-#-------------------------------------------------------------------------------
-/*! jQuery UI - v1.10.3 - 2013-05-13
-* http://jqueryui.com
-* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=%23808080&bgTextureHeader=flat&bgImgOpacityHeader=100&borderColorHeader=%23ffffff&fcHeader=%23ffffff&iconColorHeader=%23ffffff&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23e5e5e5&fcContent=%23000000&iconColorContent=%23000000&bgColorDefault=%23e5e5e5&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%23d3d3d3&fcDefault=%23555555&iconColorDefault=%23888888&bgColorHover=%23D9EFEC&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=%23999999&fcHover=%23212121&iconColorHover=%23454545&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23aaaaaa&fcActive=%23212121&iconColorActive=%23454545&bgColorHighlight=%23fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23fcefa1&fcHighlight=%23363636&iconColorHighlight=%232e83ff&bgColorError=%23fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=%23cd0a0a&fcError=%23cd0a0a&iconColorError=%23cd0a0a&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
-* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden {
-	display: none;
-}
-.ui-helper-hidden-accessible {
-	border: 0;
-	clip: rect(0 0 0 0);
-	height: 1px;
-	margin: -1px;
-	overflow: hidden;
-	padding: 0;
-	position: absolute;
-	width: 1px;
-}
-.ui-helper-reset {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	outline: 0;
-	line-height: 1.3;
-	text-decoration: none;
-	font-size: 100%;
-	list-style: none;
-}
-.ui-helper-clearfix:before,
-.ui-helper-clearfix:after {
-	content: "";
-	display: table;
-	border-collapse: collapse;
-}
-.ui-helper-clearfix:after {
-	clear: both;
-}
-.ui-helper-clearfix {
-	min-height: 0; /* support: IE7 */
-}
-.ui-helper-zfix {
-	width: 100%;
-	height: 100%;
-	top: 0;
-	left: 0;
-	position: absolute;
-	opacity: 0;
-	filter:Alpha(Opacity=0);
-}
-
-.ui-front {
-	z-index: 100;
-}
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled {
-	cursor: default !important;
-}
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
-	display: block;
-	text-indent: -99999px;
-	overflow: hidden;
-	background-repeat: no-repeat;
-}
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay {
-	position: fixed;
-	top: 0;
-	left: 0;
-	width: 100%;
-	height: 100%;
-}
-.ui-resizable {
-	position: relative;
-}
-.ui-resizable-handle {
-	position: absolute;
-	font-size: 0.1px;
-	display: block;
-}
-.ui-resizable-disabled .ui-resizable-handle,
-.ui-resizable-autohide .ui-resizable-handle {
-	display: none;
-}
-.ui-resizable-n {
-	cursor: n-resize;
-	height: 7px;
-	width: 100%;
-	top: -5px;
-	left: 0;
-}
-.ui-resizable-s {
-	cursor: s-resize;
-	height: 7px;
-	width: 100%;
-	bottom: -5px;
-	left: 0;
-}
-.ui-resizable-e {
-	cursor: e-resize;
-	width: 7px;
-	right: -5px;
-	top: 0;
-	height: 100%;
-}
-.ui-resizable-w {
-	cursor: w-resize;
-	width: 7px;
-	left: -5px;
-	top: 0;
-	height: 100%;
-}
-.ui-resizable-se {
-	cursor: se-resize;
-	width: 12px;
-	height: 12px;
-	right: 1px;
-	bottom: 1px;
-}
-.ui-resizable-sw {
-	cursor: sw-resize;
-	width: 9px;
-	height: 9px;
-	left: -5px;
-	bottom: -5px;
-}
-.ui-resizable-nw {
-	cursor: nw-resize;
-	width: 9px;
-	height: 9px;
-	left: -5px;
-	top: -5px;
-}
-.ui-resizable-ne {
-	cursor: ne-resize;
-	width: 9px;
-	height: 9px;
-	right: -5px;
-	top: -5px;
-}
-.ui-selectable-helper {
-	position: absolute;
-	z-index: 100;
-	border: 1px dotted black;
-}
-.ui-accordion .ui-accordion-header {
-	display: block;
-	cursor: pointer;
-	position: relative;
-	margin-top: 2px;
-	padding: .5em .5em .5em .7em;
-	min-height: 0; /* support: IE7 */
-}
-.ui-accordion .ui-accordion-icons {
-	padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-noicons {
-	padding-left: .7em;
-}
-.ui-accordion .ui-accordion-icons .ui-accordion-icons {
-	padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
-	position: absolute;
-	left: .5em;
-	top: 50%;
-	margin-top: -8px;
-}
-.ui-accordion .ui-accordion-content {
-	padding: 1em 2.2em;
-	border-top: 0;
-	overflow: auto;
-}
-.ui-autocomplete {
-	position: absolute;
-	top: 0;
-	left: 0;
-	cursor: default;
-}
-.ui-button {
-	display: inline-block;
-	position: relative;
-	padding: 0;
-	line-height: normal;
-	margin-right: .1em;
-	cursor: pointer;
-	vertical-align: middle;
-	text-align: center;
-	overflow: visible; /* removes extra width in IE */
-}
-.ui-button,
-.ui-button:link,
-.ui-button:visited,
-.ui-button:hover,
-.ui-button:active {
-	text-decoration: none;
-}
-/* to make room for the icon, a width needs to be set here */
-.ui-button-icon-only {
-	width: 2.2em;
-}
-/* button elements seem to need a little more width */
-button.ui-button-icon-only {
-	width: 2.4em;
-}
-.ui-button-icons-only {
-	width: 3.4em;
-}
-button.ui-button-icons-only {
-	width: 3.7em;
-}
-
-/* button text element */
-.ui-button .ui-button-text {
-	display: block;
-	line-height: normal;
-}
-.ui-button-text-only .ui-button-text {
-	padding: .4em 1em;
-}
-.ui-button-icon-only .ui-button-text,
-.ui-button-icons-only .ui-button-text {
-	padding: .4em;
-	text-indent: -9999999px;
-}
-.ui-button-text-icon-primary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
-	padding: .4em 1em .4em 2.1em;
-}
-.ui-button-text-icon-secondary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
-	padding: .4em 2.1em .4em 1em;
-}
-.ui-button-text-icons .ui-button-text {
-	padding-left: 2.1em;
-	padding-right: 2.1em;
-}
-/* no icon support for input elements, provide padding by default */
-input.ui-button {
-	padding: .4em 1em;
-}
-
-/* button icon element(s) */
-.ui-button-icon-only .ui-icon,
-.ui-button-text-icon-primary .ui-icon,
-.ui-button-text-icon-secondary .ui-icon,
-.ui-button-text-icons .ui-icon,
-.ui-button-icons-only .ui-icon {
-	position: absolute;
-	top: 50%;
-	margin-top: -8px;
-}
-.ui-button-icon-only .ui-icon {
-	left: 50%;
-	margin-left: -8px;
-}
-.ui-button-text-icon-primary .ui-button-icon-primary,
-.ui-button-text-icons .ui-button-icon-primary,
-.ui-button-icons-only .ui-button-icon-primary {
-	left: .5em;
-}
-.ui-button-text-icon-secondary .ui-button-icon-secondary,
-.ui-button-text-icons .ui-button-icon-secondary,
-.ui-button-icons-only .ui-button-icon-secondary {
-	right: .5em;
-}
-
-/* button sets */
-.ui-buttonset {
-	margin-right: 7px;
-}
-.ui-buttonset .ui-button {
-	margin-left: 0;
-	margin-right: -.3em;
-}
-
-/* workarounds */
-/* reset extra padding in Firefox, see h5bp.com/l */
-input.ui-button::-moz-focus-inner,
-button.ui-button::-moz-focus-inner {
-	border: 0;
-	padding: 0;
-}
-.ui-datepicker {
-	width: 17em;
-	padding: .2em .2em 0;
-	display: none;
-}
-.ui-datepicker .ui-datepicker-header {
-	position: relative;
-	padding: .2em 0;
-}
-.ui-datepicker .ui-datepicker-prev,
-.ui-datepicker .ui-datepicker-next {
-	position: absolute;
-	top: 2px;
-	width: 1.8em;
-	height: 1.8em;
-}
-.ui-datepicker .ui-datepicker-prev-hover,
-.ui-datepicker .ui-datepicker-next-hover {
-	top: 1px;
-}
-.ui-datepicker .ui-datepicker-prev {
-	left: 2px;
-}
-.ui-datepicker .ui-datepicker-next {
-	right: 2px;
-}
-.ui-datepicker .ui-datepicker-prev-hover {
-	left: 1px;
-}
-.ui-datepicker .ui-datepicker-next-hover {
-	right: 1px;
-}
-.ui-datepicker .ui-datepicker-prev span,
-.ui-datepicker .ui-datepicker-next span {
-	display: block;
-	position: absolute;
-	left: 50%;
-	margin-left: -8px;
-	top: 50%;
-	margin-top: -8px;
-}
-.ui-datepicker .ui-datepicker-title {
-	margin: 0 2.3em;
-	line-height: 1.8em;
-	text-align: center;
-}
-.ui-datepicker .ui-datepicker-title select {
-	font-size: 1em;
-	margin: 1px 0;
-}
-.ui-datepicker select.ui-datepicker-month-year {
-	width: 100%;
-}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year {
-	width: 49%;
-}
-.ui-datepicker table {
-	width: 100%;
-	font-size: .9em;
-	border-collapse: collapse;
-	margin: 0 0 .4em;
-}
-.ui-datepicker th {
-	padding: .7em .3em;
-	text-align: center;
-	font-weight: bold;
-	border: 0;
-}
-.ui-datepicker td {
-	border: 0;
-	padding: 1px;
-}
-.ui-datepicker td span,
-.ui-datepicker td a {
-	display: block;
-	padding: .2em;
-	text-align: right;
-	text-decoration: none;
-}
-.ui-datepicker .ui-datepicker-buttonpane {
-	background-image: none;
-	margin: .7em 0 0 0;
-	padding: 0 .2em;
-	border-left: 0;
-	border-right: 0;
-	border-bottom: 0;
-}
-.ui-datepicker .ui-datepicker-buttonpane button {
-	float: right;
-	margin: .5em .2em .4em;
-	cursor: pointer;
-	padding: .2em .6em .3em .6em;
-	width: auto;
-	overflow: visible;
-}
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
-	float: left;
-}
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi {
-	width: auto;
-}
-.ui-datepicker-multi .ui-datepicker-group {
-	float: left;
-}
-.ui-datepicker-multi .ui-datepicker-group table {
-	width: 95%;
-	margin: 0 auto .4em;
-}
-.ui-datepicker-multi-2 .ui-datepicker-group {
-	width: 50%;
-}
-.ui-datepicker-multi-3 .ui-datepicker-group {
-	width: 33.3%;
-}
-.ui-datepicker-multi-4 .ui-datepicker-group {
-	width: 25%;
-}
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
-	border-left-width: 0;
-}
-.ui-datepicker-multi .ui-datepicker-buttonpane {
-	clear: left;
-}
-.ui-datepicker-row-break {
-	clear: both;
-	width: 100%;
-	font-size: 0;
-}
-
-/* RTL support */
-.ui-datepicker-rtl {
-	direction: rtl;
-}
-.ui-datepicker-rtl .ui-datepicker-prev {
-	right: 2px;
-	left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next {
-	left: 2px;
-	right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-prev:hover {
-	right: 1px;
-	left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next:hover {
-	left: 1px;
-	right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane {
-	clear: right;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button {
-	float: left;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
-.ui-datepicker-rtl .ui-datepicker-group {
-	float: right;
-}
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
-	border-right-width: 0;
-	border-left-width: 1px;
-}
-.ui-dialog {
-	position: absolute;
-	top: 0;
-	left: 0;
-	padding: .2em;
-	outline: 0;
-}
-.ui-dialog .ui-dialog-titlebar {
-	padding: .4em 1em;
-	position: relative;
-}
-.ui-dialog .ui-dialog-title {
-	float: left;
-	margin: .1em 0;
-	white-space: nowrap;
-	width: 90%;
-	overflow: hidden;
-	text-overflow: ellipsis;
-}
-.ui-dialog .ui-dialog-titlebar-close {
-	position: absolute;
-	right: .3em;
-	top: 50%;
-	width: 21px;
-	margin: -10px 0 0 0;
-	padding: 1px;
-	height: 20px;
-}
-.ui-dialog .ui-dialog-content {
-	position: relative;
-	border: 0;
-	padding: .5em 1em;
-	background: none;
-	overflow: auto;
-}
-.ui-dialog .ui-dialog-buttonpane {
-	text-align: left;
-	border-width: 1px 0 0 0;
-	background-image: none;
-	margin-top: .5em;
-	padding: .3em 1em .5em .4em;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
-	float: right;
-}
-.ui-dialog .ui-dialog-buttonpane button {
-	margin: .5em .4em .5em 0;
-	cursor: pointer;
-}
-.ui-dialog .ui-resizable-se {
-	width: 12px;
-	height: 12px;
-	right: -5px;
-	bottom: -5px;
-	background-position: 16px 16px;
-}
-.ui-draggable .ui-dialog-titlebar {
-	cursor: move;
-}
-.ui-menu {
-	list-style: none;
-	padding: 2px;
-	margin: 0;
-	display: block;
-	outline: none;
-}
-.ui-menu .ui-menu {
-	margin-top: -3px;
-	position: absolute;
-}
-.ui-menu .ui-menu-item {
-	margin: 0;
-	padding: 0;
-	width: 100%;
-	/* support: IE10, see #8844 */
-	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
-}
-.ui-menu .ui-menu-divider {
-	margin: 5px -2px 5px -2px;
-	height: 0;
-	font-size: 0;
-	line-height: 0;
-	border-width: 1px 0 0 0;
-}
-.ui-menu .ui-menu-item a {
-	text-decoration: none;
-	display: block;
-	padding: 2px .4em;
-	line-height: 1.5;
-	min-height: 0; /* support: IE7 */
-	font-weight: normal;
-}
-.ui-menu .ui-menu-item a.ui-state-focus,
-.ui-menu .ui-menu-item a.ui-state-active {
-	font-weight: normal;
-	margin: -1px;
-}
-
-.ui-menu .ui-state-disabled {
-	font-weight: normal;
-	margin: .4em 0 .2em;
-	line-height: 1.5;
-}
-.ui-menu .ui-state-disabled a {
-	cursor: default;
-}
-
-/* icon support */
-.ui-menu-icons {
-	position: relative;
-}
-.ui-menu-icons .ui-menu-item a {
-	position: relative;
-	padding-left: 2em;
-}
-
-/* left-aligned */
-.ui-menu .ui-icon {
-	position: absolute;
-	top: .2em;
-	left: .2em;
-}
-
-/* right-aligned */
-.ui-menu .ui-menu-icon {
-	position: static;
-	float: right;
-}
-.ui-progressbar {
-	height: 2em;
-	text-align: left;
-	overflow: hidden;
-}
-.ui-progressbar .ui-progressbar-value {
-	margin: -1px;
-	height: 100%;
-}
-.ui-progressbar .ui-progressbar-overlay {
-	background: url("#{resource['primefaces-kit-theme:images/animated-overlay.gif']}");
-	height: 100%;
-	filter: alpha(opacity=25);
-	opacity: 0.25;
-}
-.ui-progressbar-indeterminate .ui-progressbar-value {
-	background-image: none;
-}
-.ui-slider {
-	position: relative;
-	text-align: left;
-}
-.ui-slider .ui-slider-handle {
-	position: absolute;
-	z-index: 2;
-	width: 1.2em;
-	height: 1.2em;
-	cursor: default;
-}
-.ui-slider .ui-slider-range {
-	position: absolute;
-	z-index: 1;
-	font-size: .7em;
-	display: block;
-	border: 0;
-	background-position: 0 0;
-}
-
-/* For IE8 - See #6727 */
-.ui-slider.ui-state-disabled .ui-slider-handle,
-.ui-slider.ui-state-disabled .ui-slider-range {
-	filter: inherit;
-}
-
-.ui-slider-horizontal {
-	height: .8em;
-}
-.ui-slider-horizontal .ui-slider-handle {
-	top: -.3em;
-	margin-left: -.6em;
-}
-.ui-slider-horizontal .ui-slider-range {
-	top: 0;
-	height: 100%;
-}
-.ui-slider-horizontal .ui-slider-range-min {
-	left: 0;
-}
-.ui-slider-horizontal .ui-slider-range-max {
-	right: 0;
-}
-
-.ui-slider-vertical {
-	width: .8em;
-	height: 100px;
-}
-.ui-slider-vertical .ui-slider-handle {
-	left: -.3em;
-	margin-left: 0;
-	margin-bottom: -.6em;
-}
-.ui-slider-vertical .ui-slider-range {
-	left: 0;
-	width: 100%;
-}
-.ui-slider-vertical .ui-slider-range-min {
-	bottom: 0;
-}
-.ui-slider-vertical .ui-slider-range-max {
-	top: 0;
-}
-.ui-spinner {
-	position: relative;
-	display: inline-block;
-	overflow: hidden;
-	padding: 0;
-	vertical-align: middle;
-}
-.ui-spinner-input {
-	border: none;
-	background: none;
-	color: inherit;
-	padding: 0;
-	margin: .2em 0;
-	vertical-align: middle;
-	margin-left: .4em;
-	margin-right: 22px;
-}
-.ui-spinner-button {
-	width: 16px;
-	height: 50%;
-	font-size: .5em;
-	padding: 0;
-	margin: 0;
-	text-align: center;
-	position: absolute;
-	cursor: default;
-	display: block;
-	overflow: hidden;
-	right: 0;
-}
-/* more specificity required here to overide default borders */
-.ui-spinner a.ui-spinner-button {
-	border-top: none;
-	border-bottom: none;
-	border-right: none;
-}
-/* vertical centre icon */
-.ui-spinner .ui-icon {
-	position: absolute;
-	margin-top: -8px;
-	top: 50%;
-	left: 0;
-}
-.ui-spinner-up {
-	top: 0;
-}
-.ui-spinner-down {
-	bottom: 0;
-}
-
-/* TR overrides */
-.ui-spinner .ui-icon-triangle-1-s {
-	/* need to fix icons sprite */
-	background-position: -65px -16px;
-}
-.ui-tabs {
-	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
-	padding: .2em;
-}
-.ui-tabs .ui-tabs-nav {
-	margin: 0;
-	padding: .2em .2em 0;
-}
-.ui-tabs .ui-tabs-nav li {
-	list-style: none;
-	float: left;
-	position: relative;
-	top: 0;
-	margin: 1px .2em 0 0;
-	border-bottom-width: 0;
-	padding: 0;
-	white-space: nowrap;
-}
-.ui-tabs .ui-tabs-nav li a {
-	float: left;
-	padding: .5em 1em;
-	text-decoration: none;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active {
-	margin-bottom: -1px;
-	padding-bottom: 1px;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
-.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
-.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
-	cursor: text;
-}
-.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
-	cursor: pointer;
-}
-.ui-tabs .ui-tabs-panel {
-	/*display: block;*/
-	border-width: 0;
-	padding: 1em 1.4em;
-	background: none;
-}
-.ui-tooltip {
-	padding: 8px;
-	position: absolute;
-	z-index: 9999;
-	max-width: 300px;
-	-webkit-box-shadow: 0 0 5px #aaa;
-	box-shadow: 0 0 5px #aaa;
-}
-body .ui-tooltip {
-	border-width: 2px;
-}
-
-/* Component containers
-----------------------------------*/
-.ui-widget {
-	font-family: Verdana,Arial,sans-serif;
-	font-size: 1.1em;
-}
-.ui-widget .ui-widget {
-	font-size: 1em;
-}
-.ui-widget input,
-.ui-widget select,
-.ui-widget textarea,
-.ui-widget button {
-	font-family: Verdana,Arial,sans-serif;
-	font-size: 1em;
-}
-.ui-widget-content {
-	border: 1px solid #e5e5e5;
-	background: #ffffff url("#{resource['primefaces-kit-theme:images/ui-bg_flat_75_ffffff_40x100.png']}") 50% 50% repeat-x;
-	color: #000000;
-}
-.ui-widget-content a {
-	color: #000000;
-}
-.ui-widget-header {
-	border: 1px solid #ffffff;
-	background: #808080 url("#{resource['primefaces-kit-theme:images/ui-bg_flat_100_808080_40x100.png']}") 50% 50% repeat-x;
-	color: #ffffff;
-	font-weight: bold;
-}
-.ui-widget-header a {
-	color: #ffffff;
-}
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default,
-.ui-widget-content .ui-state-default,
-.ui-widget-header .ui-state-default {
-	border: 1px solid #d3d3d3;
-	background: #e5e5e5 url("#{resource['primefaces-kit-theme:images/ui-bg_flat_75_e5e5e5_40x100.png']}") 50% 50% repeat-x;
-	font-weight: normal;
-	color: #555555;
-}
-.ui-state-default a,
-.ui-state-default a:link,
-.ui-state-default a:visited {
-	color: #555555;
-	text-decoration: none;
-}
-.ui-state-hover,
-.ui-widget-content .ui-state-hover,
-.ui-widget-header .ui-state-hover,
-.ui-state-focus,
-.ui-widget-content .ui-state-focus,
-.ui-widget-header .ui-state-focus {
-	border: 1px solid #999999;
-	background: #fbf9ee url("#{resource['primefaces-kit-theme:images/ui-bg_glass_55_fbf9ee_1x400.png']}") 50% 50% repeat-x;
-	font-weight: normal;
-	color: #212121;
-}
-.ui-state-hover a,
-.ui-state-hover a:hover,
-.ui-state-hover a:link,
-.ui-state-hover a:visited {
-	color: #212121;
-	text-decoration: none;
-}
-.ui-state-active,
-.ui-widget-content .ui-state-active,
-.ui-widget-header .ui-state-active {
-	border: 1px solid #fcefa1;
-	background: #D9EFEC url("#{resource['primefaces-kit-theme:images/ui-bg_glass_75_D9EFEC_1x400.png']}") 50% 50% repeat-x;
-	font-weight: normal;
-	color: #212121;
-}
-.ui-state-active a,
-.ui-state-active a:link,
-.ui-state-active a:visited {
-	color: #212121;
-	text-decoration: none;
-}
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight,
-.ui-widget-content .ui-state-highlight,
-.ui-widget-header .ui-state-highlight {
-	border: 1px solid #fcefa1;
-	background: #D9EFEC url("#{resource['primefaces-kit-theme:images/ui-bg_glass_75_D9EFEC_1x400.png']}") 50% 50% repeat-x;
-	color: #363636;
-}
-.ui-state-highlight a,
-.ui-widget-content .ui-state-highlight a,
-.ui-widget-header .ui-state-highlight a {
-	color: #363636;
-}
-.ui-state-error,
-.ui-widget-content .ui-state-error,
-.ui-widget-header .ui-state-error {
-	border: 1px solid #cd0a0a;
-	background: #fef1ec url("#{resource['primefaces-kit-theme:images/ui-bg_glass_95_fef1ec_1x400.png']}") 50% 50% repeat-x;
-	color: #cd0a0a;
-}
-.ui-state-error a,
-.ui-widget-content .ui-state-error a,
-.ui-widget-header .ui-state-error a {
-	color: #cd0a0a;
-}
-.ui-state-error-text,
-.ui-widget-content .ui-state-error-text,
-.ui-widget-header .ui-state-error-text {
-	color: #cd0a0a;
-}
-.ui-priority-primary,
-.ui-widget-content .ui-priority-primary,
-.ui-widget-header .ui-priority-primary {
-	font-weight: bold;
-}
-.ui-priority-secondary,
-.ui-widget-content .ui-priority-secondary,
-.ui-widget-header .ui-priority-secondary {
-	opacity: .7;
-	filter:Alpha(Opacity=70);
-	font-weight: normal;
-}
-.ui-state-disabled,
-.ui-widget-content .ui-state-disabled,
-.ui-widget-header .ui-state-disabled {
-	opacity: .35;
-	filter:Alpha(Opacity=35);
-	background-image: none;
-}
-.ui-state-disabled .ui-icon {
-	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
-}
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
-	width: 16px;
-	height: 16px;
-}
-.ui-icon,
-.ui-widget-content .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_000000_256x240.png']}");
-}
-.ui-widget-header .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_ffffff_256x240.png']}");
-}
-.ui-state-default .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_888888_256x240.png']}");
-}
-.ui-state-hover .ui-icon,
-.ui-state-focus .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_454545_256x240.png']}");
-}
-.ui-state-active .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_454545_256x240.png']}");
-}
-.ui-state-highlight .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_2e83ff_256x240.png']}");
-}
-.ui-state-error .ui-icon,
-.ui-state-error-text .ui-icon {
-	background-image: url("#{resource['primefaces-kit-theme:images/ui-icons_cd0a0a_256x240.png']}");
-}
-
-/* positioning */
-.ui-icon-blank { background-position: 16px 16px; }
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-on { background-position: -96px -144px; }
-.ui-icon-radio-off { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-left,
-.ui-corner-tl {
-	border-top-left-radius: 0px;
-}
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-right,
-.ui-corner-tr {
-	border-top-right-radius: 0px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-left,
-.ui-corner-bl {
-	border-bottom-left-radius: 0px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-right,
-.ui-corner-br {
-	border-bottom-right-radius: 0px;
-}
-
-/* Overlays */
-.ui-widget-overlay {
-	background: #aaaaaa url("#{resource['primefaces-kit-theme:images/ui-bg_flat_0_aaaaaa_40x100.png']}") 50% 50% repeat-x;
-	opacity: .3;
-	filter: Alpha(Opacity=30);
-}
-.ui-widget-shadow {
-	margin: -8px 0 0 -8px;
-	padding: 8px;
-	background: #aaaaaa url("#{resource['primefaces-kit-theme:images/ui-bg_flat_0_aaaaaa_40x100.png']}") 50% 50% repeat-x;
-	opacity: .3;
-	filter: Alpha(Opacity=30);
-	border-radius: 8px;
-}
-
diff --git a/bwreg-webapp/src/main/resources/msg/messages_de.properties b/bwreg-webapp/src/main/resources/msg/messages_de.properties
index 37a275658..4445ea853 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_de.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_de.properties
@@ -851,21 +851,27 @@ project.connect_to_service_connect_text                 = W\u00E4hlen Sie die Di
 project.connect_to_service_list                         = Dienste ausw\u00E4hlen
 project.create_new_project                              = Neues Projekt anlegen
 project.create_new_project_text                         = Legen Sie hier ein neues Projekt an. Im folgenden k\u00F6nnen Sie Mitglieder zum Projekt einladen und die Nutzung innerhalb von Diensten beantragen.<br/>\nName: Der volle Name des Projekts (z.B. Forschungs-Projekt Alpha)<br/>\nKurzname: Das Akronym/K\u00FCrzel des Projekts (z.B. fpa)<br/>\nGruppenname: Vorschlag f\u00FCr einen Gruppennamen bei den genutzten Diensten. Dieser Wert kann von dem Dienst \u00FCberschrieben werden. Z.B. fpa\n
+project.create_new_sub_project.header                   = Neues Unterprojekt anlegen
+project.create_new_sub_project.intro_text               = Erstellen Sie hier ein neues Unterprojekt zu Ihrem Projekt. Die Mitglieder des Unterprojekts werden automatisch Mitglieder des \u00FCbergeordneten Projekts. <br/>\nName: Der vollst\u00E4ndige Name des Projekts (z.B. Forschungsprojekt Alpha)<br/>\nKurzname: Das Akronym/die Abk\u00FCrzung des Projekts (z. B. rpa)<br/>\nGroup name: Suggestion for a group name for the services used. This value can be overwritten by the service. E.g. rpa
 project.delete_local_project.delete_now                 = Jetzt l\u00F6schen
 project.delete_local_project.delete_project             = Projekt l\u00F6schen
 project.edit                                            = Projektdetails editieren
 project.edit_admins                                     = Projekt Administratoren verwalten
+project.edit_admins.cant_add_owner_as_admin             = Sie k\u00F6nnen den Besitzer nicht als Administrator hinzuf\u00FCgen
+project.edit_admins.cant_remove_last_owner              = Letzter Besitzer des Projekts kann nicht gel\u00F6scht werden.
+project.edit_admins.cant_remove_owner_as_admin          = Sie k\u00F6nnen als Administrator keine Besitzer entfernen
 project.edit_connected_services                         = Zugeordnete Dienste konfigurieren
 project.edit_members                                    = Mitglieder verwalten
 project.effective_members                               = Effektive Mitglieder (mit Mitgliedern aus Subprojekten)
 project.group_name                                      = Gruppenname f\u00FCr das Projekt
+project.include_myself_as_member                        = Selbst Mitglied werden
 project.invite_project.delete_token_confirm             = Wollen Sie die Projekteinladung zur\u00FCcknehmen?
 project.invite_project.members                          = Mitglieder einladen
 project.invite_project.members_text                     = Laden Sie Mitglieder zu Ihrem Projekt ein. 
 project.invite_project.members_with_email               = Einladung per E-Mail
 project.invite_project.members_with_email_text          = Sie k\u00F6nnen eine Projekteinladung erstellen, die in Ihrem Namen per E-Mail verschickt wird. Der Empf\u00E4nger erh\u00E4lt einen Code, mit dem sie oder er an Ihrem Projekt teilnehmen kann.
-project.invite_project.rcpt_mail                        = E-Mail Adresse
-project.invite_project.rcpt_name                        = Empf\u00E4nger
+project.invite_project.rcpt_mail                        = E-Mail Adresse der einzuladenden Person
+project.invite_project.rcpt_name                        = Name der einzuladenden Person
 project.invite_project.send_invitation                  = Einladung schicken
 project.invite_project.sender_mail                      = Absender E-Mail
 project.invite_project.sender_name                      = Absender Name
@@ -880,6 +886,7 @@ project.local_project.approver_admin_header             = Genehmigung
 project.local_project.approver_admin_message            = Projektzugriff auf den Dienst genehmigen oder ablehnen:
 project.local_project.approver_admin_txt                = Erlaubt oder verweigert dem Projekt den Zugang zu diesem Dienst. Zus\u00E4tzlich kann hier ein Gruppenname festgelegt werden, den dieses Projekt bei diesem Dienst hat. Wenn das Feld leer bleibt, wird der oben angegebene Name verwendet.
 project.local_project.approver_set_override_groupname   = Name der Gruppe f\u00FCr diesen Dienst
+project.local_project.children                          = Unterprojekte
 project.local_project.parent_vo                         = \u00DCbergeordnetes Projekt
 project.long_description                                = Beschreibung des Projekts
 project.members                                         = Projekt Mitglieder
@@ -922,9 +929,12 @@ project.projects                                        = Projekte
 project.short_description                               = Kurze Beschreibung
 project.show_local_project.connect_to_service_link      = Mit Dienst verbinden
 project.show_local_project.connect_to_service_link_text = Hier k\u00F6nnen Sie die Nutzung einer Resource f\u00FCr Ihr Projekt beantragen.
+project.show_local_project.create_sub_project           = Unterprojekt anlegen
+project.show_local_project.create_sub_project_text      = Erstellen Sie ein Unterprojekt f\u00FCr Ihr Projekt.
 project.show_local_project.delete_member_confirm        = M\u00F6chten Sie das Projektmitglied aus dem Projekt entfernen?
 project.show_local_project.delete_project_link          = Projekt l\u00F6schen
 project.show_local_project.delete_project_link_text     = \u00D6ffnet eine neue Seite, auf der das Projekt gel\u00F6scht werden kann.
+project.show_local_project.edit_project_admins_link     = Projektrollen verwalten
 project.show_local_project.invite_to_project_link       = Mitglieder einladen
 project.show_local_project.invite_to_project_link_text  = Laden Sie Mitglieder f\u00FCr Ihr Projekt ein. Die Einladung erfolgt \u00FCber eine E-Mail mit einem Einladungscode.
 project.show_local_project.manage_oidc_credentials      = OIDC Clients
diff --git a/bwreg-webapp/src/main/resources/msg/messages_en.properties b/bwreg-webapp/src/main/resources/msg/messages_en.properties
index 7898242d5..4d6e97c48 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_en.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_en.properties
@@ -851,21 +851,27 @@ project.connect_to_service_connect_text                 = Select the services yo
 project.connect_to_service_list                         = Choose services
 project.create_new_project                              = Create new project
 project.create_new_project_text                         = Create a new project here. In the following, you can invite members to the project and apply for use within services.<br/>\nName: The full name of the project (e.g. Research Project Alpha)<br/>\nShort name: The acronym/abbreviation of the project (e.g. rpa)<br/>\nGroup name: Suggestion for a group name for the services used. This value can be overwritten by the service. E.g. rpa
+project.create_new_sub_project.header                   = Create new subproject
+project.create_new_sub_project.intro_text               = Create a new sub-project for your project here. The members of the sub-project automatically become members of the parent project. <br/>\nName: The full name of the project (e.g. Alpha research project)<br/>\nShort name: The acronym/abbreviation of the project (e.g. rpa)<br/>\nGroup name: Suggestion for a group name for the services used. This value can be overwritten by the service. E.g. rpa
 project.delete_local_project.delete_now                 = Delete now
 project.delete_local_project.delete_project             = Delete project
 project.edit                                            = Edit project details
 project.edit_admins                                     = Edit project admins
+project.edit_admins.cant_add_owner_as_admin             = You can't add owner as an admin
+project.edit_admins.cant_remove_last_owner              = Last owner of the project cannot be deleted.
+project.edit_admins.cant_remove_owner_as_admin          = You can't remove owners as admin
 project.edit_connected_services                         = Edit connected services
 project.edit_members                                    = Edit members
 project.effective_members                               = Effective members (with members from sub-projects)
 project.group_name                                      = Group name for project
+project.include_myself_as_member                        = Become a member yourself
 project.invite_project.delete_token_confirm             = Do you want to withdraw the project invitation?
 project.invite_project.members                          = Invite members
 project.invite_project.members_text                     = Invite members to your project. 
 project.invite_project.members_with_email               = Invitation by e-mail
 project.invite_project.members_with_email_text          = You can generate a project invitation, that is sent via e-mail on your behalf. The recipient gets a code, which enables her or him to join your project.
-project.invite_project.rcpt_mail                        = E-mail address
-project.invite_project.rcpt_name                        = Recipient
+project.invite_project.rcpt_mail                        = E-mail address of the person to be invited
+project.invite_project.rcpt_name                        = Name of the person to be invited
 project.invite_project.send_invitation                  = Send invitation
 project.invite_project.sender_mail                      = Sender e-mail
 project.invite_project.sender_name                      = Sender name
@@ -880,6 +886,7 @@ project.local_project.approver_admin_header             = Approval
 project.local_project.approver_admin_message            = Approve or deny project access to the service:
 project.local_project.approver_admin_txt                = Allows or denies the project access to this service. A group name that this project has for this service can also be specified here. If the field remains empty, the name specified above is used.
 project.local_project.approver_set_override_groupname   = Name of the group for this service
+project.local_project.children                          = Subprojects
 project.local_project.parent_vo                         = Parent project
 project.long_description                                = Project description
 project.members                                         = Project members
@@ -922,9 +929,12 @@ project.projects                                        = Projects
 project.short_description                               = Short description
 project.show_local_project.connect_to_service_link      = Connect with service
 project.show_local_project.connect_to_service_link_text = Here you can request the use of a resource for your project.
+project.show_local_project.create_sub_project           = Create subproject
+project.show_local_project.create_sub_project_text      = Create a subproject for your project.
 project.show_local_project.delete_member_confirm        = Do you want to remove the project member from the project?
 project.show_local_project.delete_project_link          = Delete project
 project.show_local_project.delete_project_link_text     = Opens a new page on which the project can be deleted.
+project.show_local_project.edit_project_admins_link     = Manage project roles
 project.show_local_project.invite_to_project_link       = Invite members
 project.show_local_project.invite_to_project_link_text  = Invite members for your project. The invitation is done via an email with an invitation code.
 project.show_local_project.manage_oidc_credentials      = OIDC Clients
diff --git a/bwreg-webapp/src/main/resources/msg/messages_fr.properties b/bwreg-webapp/src/main/resources/msg/messages_fr.properties
index 089de86b3..6cec0dc56 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_fr.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_fr.properties
@@ -851,21 +851,27 @@ project.connect_to_service_connect_text                 = S\u00E9lectionnez les
 project.connect_to_service_list                         = Choisir des services
 project.create_new_project                              = Cr\u00E9er un nouveau projet
 project.create_new_project_text                         = Cr\u00E9ez ici un nouveau projet. Vous pouvez ensuite inviter des membres au projet et demander \u00E0 l'utiliser dans le cadre de services.<br/>\nNom : le nom complet du projet (p.ex. projet de recherche Alpha)<br/>\nNom court : l'acronyme/abr\u00E9viation du projet (par ex. fpa)<br/>\nNom de groupe : proposition de nom de groupe pour les services utilis\u00E9s. Cette valeur peut \u00EAtre remplac\u00E9e par le service. Par exemple, pra
+project.create_new_sub_project.header                   = Cr\u00E9er un nouveau sous-projet
+project.create_new_sub_project.intro_text               = Cr\u00E9ez ici un nouveau sous-projet pour votre projet. Les membres du sous-projet deviennent automatiquement membres du projet parent. <br/>\nNom : le nom complet du projet (p.ex. projet de recherche Alpha).<br/>\nAbr\u00E9viation : l'acronyme/abr\u00E9viation du projet (p. ex. rpa).<br/>\nNom du groupe : Suggestion d'un nom de groupe pour les services utilis\u00E9s. Cette valeur peut \u00EAtre remplac\u00E9e par le service. E.g. rpa
 project.delete_local_project.delete_now                 = Supprimer maintenant
 project.delete_local_project.delete_project             = Supprimer le projet
 project.edit                                            = Editer les d\u00E9tails du projet
 project.edit_admins                                     = Modifier les admins du projet
+project.edit_admins.cant_add_owner_as_admin             = Vous ne pouvez pas ajouter un propri\u00E9taire en tant qu'administrateur
+project.edit_admins.cant_remove_last_owner              = Le dernier propri\u00E9taire du projet ne peut pas \u00EAtre supprim\u00E9.
+project.edit_admins.cant_remove_owner_as_admin          = Vous ne pouvez pas supprimer des propri\u00E9taires en tant qu'administrateur
 project.edit_connected_services                         = Editer les services connect\u00E9s
 project.edit_members                                    = Editer les membres
 project.effective_members                               = Membres effectifs (avec les membres des sous-projets)
 project.group_name                                      = Nom de groupe du projet
+project.include_myself_as_member                        = Devenir membre
 project.invite_project.delete_token_confirm             = Voulez-vous retirer l'invitation \u00E0 participer au projet ?
 project.invite_project.members                          = Inviter des membres
 project.invite_project.members_text                     = Invitez des membres \u00E0 participer \u00E0 votre projet. 
 project.invite_project.members_with_email               = Invitation par e-mail
 project.invite_project.members_with_email_text          = Vous pouvez g\u00E9n\u00E9rer une invitation \u00E0 un projet, qui est envoy\u00E9e par e-mail en votre nom. Le destinataire re\u00E7oit un code qui lui permet de se joindre \u00E0 votre projet.
-project.invite_project.rcpt_mail                        = Adresse e-mail
-project.invite_project.rcpt_name                        = Receveur
+project.invite_project.rcpt_mail                        = Adresse e-mail de la personne \u00E0 inviter
+project.invite_project.rcpt_name                        = Nom de la personne \u00E0 inviter
 project.invite_project.send_invitation                  = Envoyer l'invitation
 project.invite_project.sender_mail                      = Exp\u00E9diteur e-mail
 project.invite_project.sender_name                      = Exp\u00E9diteur Nom
@@ -880,6 +886,7 @@ project.local_project.approver_admin_header             = Approuv\u00E9
 project.local_project.approver_admin_message            = Approuver ou refuser l'acc\u00E8s au service par le projet :
 project.local_project.approver_admin_txt                = Autorise ou refuse au projet l'acc\u00E8s \u00E0 ce service. De plus, il est possible de d\u00E9finir ici un nom de groupe que ce projet a aupr\u00E8s de ce service. Si le champ reste vide, le nom indiqu\u00E9 ci-dessus est utilis\u00E9.
 project.local_project.approver_set_override_groupname   = Nom du groupe pour ce service
+project.local_project.children                          = Sous-projets
 project.local_project.parent_vo                         = Projet parent
 project.long_description                                = Description du projet
 project.members                                         = Membres du projet
@@ -922,9 +929,12 @@ project.projects                                        = Projets
 project.short_description                               = Br\u00E8ve description
 project.show_local_project.connect_to_service_link      = Connecter au service
 project.show_local_project.connect_to_service_link_text = Ici, vous pouvez demander l'utilisation d'une ressource pour votre projet.
+project.show_local_project.create_sub_project           = Cr\u00E9er un sous-projet
+project.show_local_project.create_sub_project_text      = Cr\u00E9ez un sous-projet pour votre projet.
 project.show_local_project.delete_member_confirm        = Souhaitez-vous retirer le membre du projet ?
 project.show_local_project.delete_project_link          = Supprimer le projet
 project.show_local_project.delete_project_link_text     = Ouvre une nouvelle page sur laquelle le projet peut \u00EAtre supprim\u00E9.
+project.show_local_project.edit_project_admins_link     = G\u00E9rer les r\u00F4les de projet
 project.show_local_project.invite_to_project_link       = Inviter des membres
 project.show_local_project.invite_to_project_link_text  = Invitez des membres pour votre projet. L'invitation se fait par un e-mail avec un code d'invitation.
 project.show_local_project.manage_oidc_credentials      = OIDC Clients
diff --git a/bwreg-webapp/src/main/webapp/admin/project/show-local-project.xhtml b/bwreg-webapp/src/main/webapp/admin/project/show-local-project.xhtml
index 824fc020f..64613b33d 100644
--- a/bwreg-webapp/src/main/webapp/admin/project/show-local-project.xhtml
+++ b/bwreg-webapp/src/main/webapp/admin/project/show-local-project.xhtml
@@ -39,7 +39,10 @@
 		        <h:outputText value="#{admin.showLocalProjectBean.entity.groupName}"/>
 					
 		        <h:outputText value="#{messages.parent_vo}:"/>
-		        <h:outputText value="#{admin.showLocalProjectBean.entity.parentProject}"/>
+		        <h:panelGroup>
+		        	<h:outputText value="#{admin.showLocalProjectBean.entity.parentProject.name}" rendered="#{admin.showLocalProjectBean.entity.parentProject != null}"/>
+		        	<h:outputText value="no parent" rendered="#{admin.showLocalProjectBean.entity.parentProject == null}"/>
+				</h:panelGroup>
 				
 		        <h:outputText value="#{messages.published}:"/>
 		        <h:outputText value="#{admin.showLocalProjectBean.entity.published}"/>
diff --git a/bwreg-webapp/src/main/webapp/project/connect-local-project-to-service.xhtml b/bwreg-webapp/src/main/webapp/project/connect-local-project-to-service.xhtml
index f30c7c1bd..1d428c70f 100644
--- a/bwreg-webapp/src/main/webapp/project/connect-local-project-to-service.xhtml
+++ b/bwreg-webapp/src/main/webapp/project/connect-local-project-to-service.xhtml
@@ -20,44 +20,42 @@
 	<ui:param name="title" value="#{messages.title}"/>
 
 	<ui:define name="content">
-	<h:form id="form" class="full form">
+	<h:form id="form" class="full">
 
 		<h2><h:outputText value="#{messages['project.connect_to_service']}: #{connectLocalProjectToServiceBean.entity.name}"/></h2>
 
 		<p:messages id="messageBox" showDetail="true" />
 		
-		<p:panel header="#{messages.properties}">
-			<p:panelGrid id="baseData" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
-		
-		        <h:outputText value="#{messages.id}:"/>
-		        <h:outputText value="#{connectLocalProjectToServiceBean.entity.id}"/>
-		
-		        <h:outputText value="#{messages.name}:"/>
-		        <h:outputText value="#{connectLocalProjectToServiceBean.entity.name}"/>
+		<h:panelGrid id="baseData" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
+	
+	        <h:outputText value="#{messages.id}:"/>
+	        <h:outputText value="#{connectLocalProjectToServiceBean.entity.id}"/>
+	
+	        <h:outputText value="#{messages.name}:"/>
+	        <h:outputText value="#{connectLocalProjectToServiceBean.entity.name}"/>
 
-		        <h:outputText value="#{messages['project.connect_to_service_list']}:"/>
-		        <p:selectManyMenu id="servicePicker" value="#{connectLocalProjectToServiceBean.selectedServices}"
-                            converter="#{serviceConverter}" style="min-width: 300px;"
-                            var="s" showCheckbox="true">
-					<p:ajax listener="#{connectLocalProjectToServiceBean.connectionAdded()}" update="btnPanel policyHolderList" />                            
-					<f:selectItems value="#{connectLocalProjectToServiceBean.serviceList}" var="service" itemLabel="#{service.name}"
-                            itemValue="#{service}"/>
-					<p:column>
-						<h:outputText value="#{s.name}"/>
-					</p:column>       
-		        </p:selectManyMenu>
-		        
-		        <h:outputText value="#{messages.services}:"/>
-		        <ui:repeat value="#{connectLocalProjectToServiceBean.entity.projectServices}" var="s">
-		        	<div><h:outputText value="#{s.service.name} (#{s.status})"/></div>
-				</ui:repeat>
-						        
-			</p:panelGrid>
-		</p:panel>
+	        <h:outputText value="#{messages['project.connect_to_service_list']}:"/>
+	        <p:selectManyMenu id="servicePicker" value="#{connectLocalProjectToServiceBean.selectedServices}"
+                           converter="#{serviceConverter}" style="min-width: 300px;"
+                           var="s" showCheckbox="true">
+				<p:ajax listener="#{connectLocalProjectToServiceBean.connectionAdded()}" update="btnPanel policyHolderList" />                            
+				<f:selectItems value="#{connectLocalProjectToServiceBean.serviceList}" var="service" itemLabel="#{service.name}"
+                           itemValue="#{service}"/>
+				<p:column>
+					<h:outputText value="#{s.name}"/>
+				</p:column>       
+	        </p:selectManyMenu>
+	        
+	        <h:outputText value="#{messages.services}:"/>
+	        <ui:repeat value="#{connectLocalProjectToServiceBean.entity.projectServices}" var="s">
+	        	<div><h:outputText value="#{s.service.name} (#{s.status})"/></div>
+			</ui:repeat>
+					        
+		</h:panelGrid>
 
-		<p:panel>
+		<div class="text">
 			<h:outputText value="#{messages['project.connect_to_service_connect_text']}" />
-		</p:panel>
+		</div>
 
 
 		<p:panel id="policyHolderList">
@@ -75,10 +73,10 @@
   		  </p:panel>
 		</p:panel>
 		
-		<p:panel id="btnPanel">
+		<h:panelGroup id="btnPanel" layout="block" styleClass="form">
 			<p:commandButton id="saveBtn" action="#{connectLocalProjectToServiceBean.save}" value="#{messages['project.connect_to_service_connect_button']}" 
 				update="messageBox" disabled="#{not connectLocalProjectToServiceBean.savePossible}" />
-		</p:panel>
+		</h:panelGroup>
 
 		<div class="text full" style="margin-top: 0.4em;">
 			<a href="show-local-project.xhtml?id=#{connectLocalProjectToServiceBean.entity.id}"><h:outputText value="#{messages.back}"/></a>
diff --git a/bwreg-webapp/src/main/webapp/project/create-new-project.xhtml b/bwreg-webapp/src/main/webapp/project/create-new-project.xhtml
index b4505934c..a15921911 100644
--- a/bwreg-webapp/src/main/webapp/project/create-new-project.xhtml
+++ b/bwreg-webapp/src/main/webapp/project/create-new-project.xhtml
@@ -21,7 +21,7 @@
 	<ui:param name="title" value="#{messages.title}"/>
 
 	<ui:define name="content">
-	<h:form id="form" class="full form">
+	<h:form id="form" class="full">
 
 		<h2><h:outputText value="#{messages['project.create_new_project']}"/></h2>
 
@@ -42,22 +42,26 @@
 		        <bw:inputText id="shortDescField" label="#{messages['project.short_description']}" 
 		        	value="#{userProjectCreateNewBean.entity.shortDescription}" required="false"/>
 
-		        <h:outputText for="@next" value="#{messages['project.long_description']}"/>
+		        <p:outputLabel for="@next" value="#{messages['project.long_description']}"/>
 		        <p:outputPanel>
 			        <p:inputTextarea id="keyInputArea" value="#{userProjectCreateNewBean.entity.description}" 
 			        	style="height: 160px;" autoResize="false" maxlength="8128">
 			        </p:inputTextarea>
 		        </p:outputPanel>
 
+		        <p:outputLabel for="@next" value="#{messages['project.include_myself_as_member']}"/>
+				<p:inputSwitch value="#{userProjectCreateNewBean.selfMember}"></p:inputSwitch>
+				
 			</h:panelGrid>
 			
 		</p:panel>
 
-		<p:panel>
+		<h:panelGroup layout="block" styleClass="form">
 			<p:commandButton id="cancel" action="#{userProjectCreateNewBean.cancel}" value="#{messages.cancel}"
 				immediate="true"/>
-			<p:commandButton id="save" action="#{userProjectCreateNewBean.save}" value="#{messages.save}"/>
-		</p:panel>
+			<p:commandButton id="save" action="#{userProjectCreateNewBean.save}" value="#{messages.save}"
+				style="margin-left: 1em;"/>
+		</h:panelGroup>
 		
 	</h:form>
 	</ui:define>
diff --git a/bwreg-webapp/src/main/webapp/project/create-new-subproject.xhtml b/bwreg-webapp/src/main/webapp/project/create-new-subproject.xhtml
new file mode 100644
index 000000000..88038c42a
--- /dev/null
+++ b/bwreg-webapp/src/main/webapp/project/create-new-subproject.xhtml
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:f="jakarta.faces.core"
+	xmlns:h="jakarta.faces.html"
+	xmlns:ui="jakarta.faces.facelets"
+	xmlns:bw="http://www.scc.kit.edu/bwfacelets"
+	xmlns:p="http://primefaces.org/ui"
+	xmlns:of="http://omnifaces.org/functions">
+<head>
+<title></title>
+</head>
+<body>
+<f:view>
+	<f:metadata>
+		<f:viewParam name="id" value="#{userSubprojectCreateNewBean.parentId}"/>
+		<f:event type="jakarta.faces.event.PreRenderViewEvent"
+            listener="#{userSubprojectCreateNewBean.preRenderView}" />
+	</f:metadata>
+
+<ui:composition template="/template/default.xhtml">
+	<ui:param name="title" value="#{messages.title}"/>
+
+	<ui:define name="content">
+	<h:form id="form" class="full">
+
+		<h2><h:outputText value="#{messages['project.create_new_sub_project.header']}"/></h2>
+
+		<div><h:outputText value="#{messages['project.create_new_sub_project.intro_text']}" escape="false" /></div>
+		
+		<p:panel>
+			<h:panelGrid id="baseData" columns="2" columnClasses="labelColumn, elementColumn">
+
+		        <bw:inputText id="nameField" label="#{messages.name}" 
+		        	value="#{userSubprojectCreateNewBean.entity.name}" required="true"/>
+
+			    <p:outputLabel for="shortNameField" value="#{messages.short_name}"/>
+			    <h:panelGroup>
+				    <p:inputText id="shortNameField" value="#{userSubprojectCreateNewBean.entity.shortName}" required="true">
+				        <f:ajax event="blur" execute="@this" render="shortNameField-message" />
+				    </p:inputText>
+				    <p:message id="shortNameField-message" for="shortNameField" />
+				</h:panelGroup>
+
+		        <bw:inputText id="groupNameField" label="#{messages.group_name}" 
+		        	value="#{userSubprojectCreateNewBean.entity.groupName}" required="true"/>
+
+		        <bw:inputText id="shortDescField" label="#{messages['project.short_description']}" 
+		        	value="#{userSubprojectCreateNewBean.entity.shortDescription}" required="false"/>
+
+		        <p:outputLabel for="@next" value="#{messages['project.long_description']}"/>
+		        <p:outputPanel>
+			        <p:inputTextarea id="keyInputArea" value="#{userSubprojectCreateNewBean.entity.description}" 
+			        	style="height: 160px;" autoResize="false" maxlength="8128">
+			        </p:inputTextarea>
+		        </p:outputPanel>
+
+		        <p:outputLabel for="@next" value="#{messages['project.include_myself_as_member']}"/>
+				<p:inputSwitch value="#{userSubprojectCreateNewBean.selfMember}"></p:inputSwitch>
+				
+			</h:panelGrid>
+			
+		</p:panel>
+
+		<h:panelGroup layout="block" styleClass="form">
+			<p:commandButton id="cancel" action="#{userSubprojectCreateNewBean.cancel}" value="#{messages.cancel}"
+				immediate="true"/>
+			<p:commandButton id="save" action="#{userSubprojectCreateNewBean.save}" value="#{messages.save}"
+				style="margin-left: 1em;"/>
+		</h:panelGroup>
+		
+	</h:form>
+	</ui:define>
+</ui:composition>
+</f:view>
+</body>
+</html>
diff --git a/bwreg-webapp/src/main/webapp/project/edit-local-project-admins.xhtml b/bwreg-webapp/src/main/webapp/project/edit-local-project-admins.xhtml
new file mode 100644
index 000000000..2e9b47563
--- /dev/null
+++ b/bwreg-webapp/src/main/webapp/project/edit-local-project-admins.xhtml
@@ -0,0 +1,127 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:f="jakarta.faces.core"
+	xmlns:h="jakarta.faces.html"
+	xmlns:ui="jakarta.faces.facelets"
+	xmlns:bw="http://www.scc.kit.edu/bwfacelets"
+	xmlns:p="http://primefaces.org/ui"
+	xmlns:of="http://omnifaces.org/functions">
+<head>
+<title></title>
+</head>
+<body>
+<f:view>
+	<f:metadata>
+		<f:viewParam name="id" value="#{userEditLocalProjectAdminsBean.projectId}"/>
+		<f:event type="jakarta.faces.event.PreRenderViewEvent"
+            listener="#{userEditLocalProjectAdminsBean.preRenderView}" />
+	</f:metadata>
+
+<ui:composition template="/template/default.xhtml">
+	<ui:param name="title" value="#{messages.title}"/>
+
+	<ui:define name="content">
+	<h:form id="form" styleClass="full">
+
+		<h2><h:outputText value="#{messages.edit_admins}: #{userEditLocalProjectAdminsBean.entity.name}"/></h2>
+
+		<p:messages id="messageBox" showDetail="true" />
+
+		<h:panelGrid id="baseData" style="margin-top:1em;" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
+			
+			<h:outputText value="#{messages.id}:"/>
+			<h:outputText value="#{userEditLocalProjectAdminsBean.entity.id}"/>
+			
+			<h:outputText value="#{messages.name}:"/>
+			<h:outputText value="#{userEditLocalProjectAdminsBean.entity.name}"/>
+			
+		</h:panelGrid>
+
+		<div class="text" style="margin-top: 0.4em;">
+			<h:panelGroup rendered="#{userEditLocalProjectAdminsBean.entity.class.simpleName == 'LocalProjectEntity'}">
+				<a href="show-local-project.xhtml?id=#{userEditLocalProjectAdminsBean.entity.id}"><h:outputText value="#{messages.back}"/></a>
+			</h:panelGroup>
+			<h:panelGroup rendered="#{userEditLocalProjectAdminsBean.entity.class.simpleName == 'AttributeSourceProjectEntity'}">
+				<a href="show-as-project.xhtml?id=#{userEditLocalProjectAdminsBean.entity.id}"><h:outputText value="#{messages.back}"/></a>
+			</h:panelGroup>		
+		</div>
+
+		<p:outputPanel>
+	        <p:selectOneMenu value="#{userEditLocalProjectAdminsBean.selectedAdminType}">
+            	<f:selectItems value="#{userEditLocalProjectAdminsBean.adminTypes}" 
+            		var="et" itemLabel="#{et}" itemValue="#{et}"/>
+            </p:selectOneMenu>
+		</p:outputPanel>
+		
+		<p:dataTable id="dataTableAllMemberList" var="member" value="#{userEditLocalProjectAdminsBean.memberList}" paginator="true"
+					lazy="true" rows="15">
+			<p:column sortBy="#{member.prefUser.id}" style="width:128px;">
+				<f:facet name="header">
+					<h:outputText value="#{messages.id}" />
+				</f:facet>
+				<h:outputText value="#{member.prefUser.id}" />
+			</p:column>
+			<p:column sortBy="#{member.prefUser.surName}" filterBy="#{member.prefUser.surName}" filterMatchMode="contains">
+				<f:facet name="header">
+					<h:outputText value="#{messages.sur_name}" />
+				</f:facet>
+				<h:outputText value="#{member.prefUser.surName}" />
+			</p:column>			
+			<p:column sortBy="#{member.prefUser.givenName}" filterBy="#{member.prefUser.givenName}" filterMatchMode="contains">
+				<f:facet name="header">
+					<h:outputText value="#{messages.given_name}" />
+				</f:facet>
+				<h:outputText value="#{member.prefUser.givenName}" />
+			</p:column>			
+			<p:column sortBy="#{member.primaryEmail}" filterBy="#{member.primaryEmail}" filterMatchMode="contains">
+				<f:facet name="header">
+					<h:outputText value="#{messages.email}" />
+				</f:facet>
+				<h:outputText value="#{member.primaryEmail != null ? member.primaryEmail : 'nicht gesetzt'}" />
+			</p:column>
+			<p:column sortBy="#{member.prefUser.userStatus}" style="width:96px;">
+				<f:facet name="header">
+					<h:outputText value="#{messages.status}" />
+				</f:facet>
+				<h:outputText value="#{member.prefUser.userStatus}" />
+			</p:column>			
+			<p:column>
+				<p:commandLink action="#{userEditLocalProjectAdminsBean.addAdmin(member)}" value="#{messages.add}"
+							update=":form:dataTableAdmins"/>
+			</p:column>	
+		</p:dataTable>
+
+		<p:dataTable id="dataTableAdmins" var="a" value="#{userEditLocalProjectAdminsBean.adminList}" paginator="true"
+					rows="15">
+			<p:column>
+				<f:facet name="header">
+					<h:outputText value="#{messages.id}" />
+				</f:facet>
+				<h:outputText value="#{a.identity.id}" />
+			</p:column>			
+			<p:column sortBy="#{a.identity.prefUser.eppn}" filterBy="#{a.identity.prefUser.eppn}" filterMatchMode="contains">
+				<f:facet name="header">
+					<h:outputText value="#{messages.name}" />
+				</f:facet>
+				<h:outputText value="#{a.identity.prefUser.eppn}" />
+			</p:column>
+			<p:column>
+				<f:facet name="header">
+					<h:outputText value="#{messages.type}" />
+				</f:facet>
+				<h:outputText value="#{a.type}" />
+			</p:column>			
+			<p:column>
+				<p:commandLink action="#{userEditLocalProjectAdminsBean.removeAdmin(a)}" value="#{messages.remove}"
+							update=":form:dataTableAdmins :form:messageBox"/>
+			</p:column>	
+		</p:dataTable>		
+		
+	</h:form>
+
+	</ui:define>
+</ui:composition>
+</f:view>		
+</body>
+</html>
diff --git a/bwreg-webapp/src/main/webapp/project/index.xhtml b/bwreg-webapp/src/main/webapp/project/index.xhtml
index 1bb894008..ede535179 100644
--- a/bwreg-webapp/src/main/webapp/project/index.xhtml
+++ b/bwreg-webapp/src/main/webapp/project/index.xhtml
@@ -21,7 +21,7 @@
 	<ui:param name="title" value="#{messages.title}"/>
 
 	<ui:define name="content">
-	<h:form id="form" class="full form">
+	<h:form id="form" class="full">
 
 		<h2><h:outputText value="#{messages['project.my_projects']}"/></h2>
 				
@@ -50,13 +50,13 @@
 			</p:column>			
 		</p:dataTable>
 
-		<p:panel>
-		<p:panelGrid columns="2">
-			<p:linkButton href="create-new-project.xhtml" value="#{messages['project.my_projects.create_new_project_link']}" />
+		<div class="text thrid">
+			<a href="create-new-project.xhtml"><h:outputText value="#{messages['project.my_projects.create_new_project_link']}" /></a>
+		</div>
+		<div class="text thrid">
 			<h:outputText value="#{messages['project.my_projects.create_new_project_link_text']}" />
-		</p:panelGrid>
-		</p:panel>
-		
+		</div>
+
 		<div class="text full" style="margin-top: 0.4em;">
 			<a href="../index.xhtml"><h:outputText value="#{messages.back}"/></a>
 		</div>		
diff --git a/bwreg-webapp/src/main/webapp/project/invite-to-project.xhtml b/bwreg-webapp/src/main/webapp/project/invite-to-project.xhtml
index 3c0b99702..5551a14f3 100644
--- a/bwreg-webapp/src/main/webapp/project/invite-to-project.xhtml
+++ b/bwreg-webapp/src/main/webapp/project/invite-to-project.xhtml
@@ -20,17 +20,18 @@
 	<ui:param name="title" value="#{messages.title}"/>
 
 	<ui:define name="content">
-	<h:form id="form" class="full form">
+	<h:form id="form" class="full">
 
 		<h2><h:outputText value="#{messages['project.invite_project.members']}: #{inviteToProjectBean.entity.name}"/></h2>
 
 		<p:messages id="messageBox" showDetail="true" />
 		
-		<p:panel>
+		<div class="text">
 			<h:outputText value="#{messages['project.invite_project.members_text']}"/>
-		</p:panel>
+		</div>
 
-		<p:dataTable id="dataTable" var="t" value="#{inviteToProjectBean.tokenList}">
+		<p:dataTable id="dataTable" var="t" value="#{inviteToProjectBean.tokenList}"
+				style="margin-top: 1em; width:auto; font-size: 1.2rem;">
 			<p:column>
 				<f:facet name="header">
 					<h:outputText value="#{messages.token}" />
@@ -65,33 +66,33 @@
        		</p:column>
 		</p:dataTable>
 
-
-		<p:panel id="inputPanel" header="#{messages['project.invite_project.members_with_email']}">
-			<h:outputText value="#{messages['project.invite_project.members_with_email_text']}"/>
-			
-			<h:panelGrid columns="2">
+		<h6 style="margin-top: 1em;"><h:outputText value="#{messages['project.invite_project.members_with_email']}"/></h6>
+		<h:outputText value="#{messages['project.invite_project.members_with_email_text']}"/>
+		
+		<h:panelGrid columns="2">
+		
+			<h:outputLabel value="#{messages['project.invite_project.rcpt_mail']}" />
+			<p:inputText value="#{inviteToProjectBean.rcptMail}"/>
 			
-				<h:outputLabel value="#{messages['project.invite_project.rcpt_mail']}" />
-				<p:inputText value="#{inviteToProjectBean.rcptMail}"/>
-				
-				<h:outputLabel value="#{messages['project.invite_project.rcpt_name']}" />
-				<p:inputText value="#{inviteToProjectBean.rcptName}"/>
+			<h:outputLabel value="#{messages['project.invite_project.rcpt_name']}" />
+			<p:inputText value="#{inviteToProjectBean.rcptName}"/>
 
-				<h:outputLabel value="#{messages['project.invite_project.sender_mail']}" />
-				<p:selectOneMenu id="senderMailOption" value="#{inviteToProjectBean.senderMail}">
-					<f:selectItems value="#{inviteToProjectBean.senderEmailList}"/>
-				</p:selectOneMenu>
+			<h:outputLabel value="#{messages['project.invite_project.sender_mail']}" />
+			<p:selectOneMenu id="senderMailOption" value="#{inviteToProjectBean.senderMail}">
+				<f:selectItems value="#{inviteToProjectBean.senderEmailList}"/>
+			</p:selectOneMenu>
 
-				<h:outputLabel value="#{messages['project.invite_project.sender_name']}" />
-				<p:selectOneMenu id="senderNameOption" value="#{inviteToProjectBean.senderName}">
-					<f:selectItems value="#{inviteToProjectBean.senderNameList}"/>
-				</p:selectOneMenu>
-				
-			</h:panelGrid>
+			<h:outputLabel value="#{messages['project.invite_project.sender_name']}" />
+			<p:selectOneMenu id="senderNameOption" value="#{inviteToProjectBean.senderName}">
+				<f:selectItems value="#{inviteToProjectBean.senderNameList}"/>
+			</p:selectOneMenu>
 			
-			<p:commandButton action="#{inviteToProjectBean.sendToken()}" value="#{messages['project.invite_project.send_invitation']}" update="messageBox, dataTable, inputPanel"/>
-		</p:panel>
-
+		</h:panelGrid>
+		
+		<div class="form">
+			<p:commandButton action="#{inviteToProjectBean.sendToken()}" value="#{messages['project.invite_project.send_invitation']}" update="@form"/>
+		</div>
+		
 		<div class="text full" style="margin-top: 0.4em;">
 			<p:outputPanel rendered="#{inviteToProjectBean.entity.class.simpleName == 'LocalProjectEntity'}">
 				<a href="show-local-project.xhtml?id=#{inviteToProjectBean.entity.id}"><h:outputText value="#{messages.back}"/></a>
@@ -103,8 +104,10 @@
 
 	    <p:confirmDialog global="true" showEffect="fade" hideEffect="fade" closable="false" 
 	    	closeOnEscape="true" width="320">
-	        <p:commandButton value="#{messages.yes}" type="button" styleClass="ui-confirmdialog-yes"/>
-	        <p:commandButton value="#{messages.no}" type="button" styleClass="ui-confirmdialog-no"/>
+	    	<div class="form">
+	        	<p:commandButton value="#{messages.yes}" type="button" styleClass="ui-confirmdialog-yes"/>
+	        	<p:commandButton value="#{messages.no}" type="button" styleClass="ui-confirmdialog-no"/>
+	        </div>
 	    </p:confirmDialog>    
 
 	</h:form>
diff --git a/bwreg-webapp/src/main/webapp/project/show-local-project.xhtml b/bwreg-webapp/src/main/webapp/project/show-local-project.xhtml
index 002eb6b61..999fce1b6 100644
--- a/bwreg-webapp/src/main/webapp/project/show-local-project.xhtml
+++ b/bwreg-webapp/src/main/webapp/project/show-local-project.xhtml
@@ -20,13 +20,13 @@
 	<ui:param name="title" value="#{messages.title}"/>
 
 	<ui:define name="content">
-	<h:form id="form" class="full form">
+	<h:form id="form" styleClass="full">
 
 		<h2><h:outputText value="#{messages['project.local_project']}: #{userShowLocalProjectBean.entity.name}"/></h2>
 
 		<p:messages id="messageBox" showDetail="true" />
 		
-		<p:panelGrid style="margin-top:1em;" id="baseData" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
+		<h:panelGrid style="margin-top:1em;" id="baseData" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
 	
 	        <h:outputText value="#{messages.id}:"/>
 	        <h:outputText value="#{userShowLocalProjectBean.entity.id}"/>
@@ -40,41 +40,62 @@
 	        <h:outputText value="#{messages['project.local_project.parent_vo']}:" rendered="#{userShowLocalProjectBean.entity.parentProject != null}"/>
 	        <h:outputText value="#{userShowLocalProjectBean.entity.parentProject.name}" rendered="#{userShowLocalProjectBean.entity.parentProject != null}"/>
 			
+	        <h:outputText value="#{messages['project.local_project.children']}:" rendered="#{userShowLocalProjectBean.entity.childProjects != null and userShowLocalProjectBean.entity.childProjects.size() > 0}"/>
+	        <h:panelGroup layout="block" styleClass="text" rendered="#{userShowLocalProjectBean.entity.childProjects != null and userShowLocalProjectBean.entity.childProjects.size() > 0}">
+	        	<ul>
+			        <ui:repeat value="#{userShowLocalProjectBean.entity.childProjects}" var="s">
+			        	<li><h:outputText value="#{s.name}"/></li>
+					</ui:repeat>
+	        	</ul>
+			</h:panelGroup>
+			
 	        <h:outputText value="#{messages.services}:"/>
 	        <ui:repeat value="#{userShowLocalProjectBean.entity.projectServices}" var="s">
 	        	<div><h:outputText value="#{s.service.name} (#{s.status})"/></div>
 			</ui:repeat>
-		</p:panelGrid>
+		</h:panelGrid>
 
-		<p:panelGrid style="margin-top:1em;" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
-			<p:linkButton href="connect-local-project-to-service.xhtml" value="#{messages['project.show_local_project.connect_to_service_link']}">
+		<h:panelGrid style="margin-top:1em;" columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
+			<h:outputLink value="connect-local-project-to-service.xhtml" >
+				<h:outputText value="#{messages['project.show_local_project.connect_to_service_link']}"/>
 				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
-			</p:linkButton>
+			</h:outputLink>
 			<h:outputText value="#{messages['project.show_local_project.connect_to_service_link_text']}" />
 
-			<p:linkButton href="invite-to-project.xhtml" value="#{messages['project.show_local_project.invite_to_project_link']}">
+			<h:outputLink value="invite-to-project.xhtml">
+				<h:outputText value="#{messages['project.show_local_project.invite_to_project_link']}"/>
 				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
-			</p:linkButton>
+			</h:outputLink>
 			<h:outputText value="#{messages['project.show_local_project.invite_to_project_link_text']}" />
 
-			<p:linkButton href="oidc/list-clients.xhtml" value="#{messages['project.show_local_project.manage_oidc_credentials']}"
+			<h:outputLink value="oidc/list-clients.xhtml" 
 				rendered="#{userShowLocalProjectBean.entity.approved}">
+				<h:outputText value="#{messages['project.show_local_project.manage_oidc_credentials']}"/>
 				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
-			</p:linkButton>
+			</h:outputLink>
 			<h:outputText value="#{messages['project.show_local_project.manage_oidc_credentials_text']}" rendered="#{userShowLocalProjectBean.entity.approved}"/>	
+
+			<h:outputLink value="create-new-subproject.xhtml" 
+				rendered="#{userShowLocalProjectBean.entity.subProjectsAllowed}">
+				<h:outputText value="#{messages['project.show_local_project.create_sub_project']}"/>
+				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
+			</h:outputLink>
+			<h:outputText value="#{messages['project.show_local_project.create_sub_project_text']}" rendered="#{userShowLocalProjectBean.entity.subProjectsAllowed}"/>	
 			
-			<p:linkButton href="delete-local-project.xhtml" value="#{messages['project.show_local_project.delete_project_link']}">
+			<h:outputLink value="delete-local-project.xhtml" >
+				<h:outputText value="#{messages['project.show_local_project.delete_project_link']}"/>
 				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
-			</p:linkButton>
+			</h:outputLink>
 			<h:outputText value="#{messages['project.show_local_project.delete_project_link_text']}" />	
-		</p:panelGrid>
+		</h:panelGrid>
 
 		<div class="text full" style="margin-top: 0.4em;">
 			<a href="index.xhtml"><h:outputText value="#{messages.back}"/></a>
 		</div>		
 
 		<h5 style="margin-top: 1em;"><h:outputText value="#{messages['project.members']}" /></h5>
-		<p:dataTable id="dataTableMember" var="member" value="#{userShowLocalProjectBean.memberList}">
+		<p:dataTable id="dataTableMember" var="member" value="#{userShowLocalProjectBean.memberList}"
+			style="width:auto; font-size: 1.2rem;">
 			<p:column sortBy="#{member.identity.prefUser.eppn}" filterBy="#{member.identity.prefUser.eppn}" filterMatchMode="contains">
 				<f:facet name="header">
 					<h:outputText value="#{messages.name}" />
@@ -110,7 +131,8 @@
 		</p:dataTable>	
 		
 		<h5 style="margin-top: 1em;"><h:outputText value="#{messages['project.admins']}" /></h5>
-		<p:dataTable id="dataTableAdmin" var="a" value="#{userShowLocalProjectBean.adminList}">
+		<p:dataTable id="dataTableAdmin" var="a" value="#{userShowLocalProjectBean.adminList}"
+			style="width:auto; font-size: 1.2rem;">
 			<p:column sortBy="#{a.identity.prefUser.eppn}" filterBy="#{a.identity.prefUser.eppn}" filterMatchMode="contains">
 				<f:facet name="header">
 					<h:outputText value="#{messages.name}" />
@@ -135,16 +157,22 @@
 				</f:facet>
 				<h:outputText value="#{a.type}" />
 			</p:column>			
-		</p:dataTable>	
-
+		</p:dataTable>
+		<div class="text">
+			<h:outputLink value="edit-local-project-admins.xhtml" >
+				<h:outputText value="#{messages['project.show_local_project.edit_project_admins_link']}"/>
+				<f:param name="id" value="#{userShowLocalProjectBean.entity.id}"/>
+			</h:outputLink>
+		</div>
+		
 		<h5 style="margin-top: 1em;"><h:outputText value="#{messages['more_properties']}" /></h5>
-		<p:panelGrid id="descData" columns="2">	
+		<h:panelGrid id="descData" columns="2">	
 	        <h:outputText value="#{messages['project.short_description']}:"/>
 			<h:outputText value="#{userShowLocalProjectBean.entity.shortDescription}" />	
 
 	        <h:outputText value="#{messages['project.long_description']}:"/>
 			<h:outputText value="#{userShowLocalProjectBean.entity.description}" />	
-		</p:panelGrid>		
+		</h:panelGrid>		
 					
 	    <p:confirmDialog global="true" showEffect="fade" hideEffect="fade" closable="false" 
 	    	closeOnEscape="true" width="320">
-- 
GitLab