From bb0d8f19da5caff8bad3986e17cdff4cb5dcd236 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Sun, 13 Nov 2022 09:35:49 +0100 Subject: [PATCH] Group management --- .../OSGI-INF/l10n/bundle.properties | 3 + .../OSGI-INF/l10n/bundle_fr.properties | 3 + .../src/org/argeo/app/ui/SuiteMsg.java | 2 + .../argeo/app/ui/people/ChooseUserDialog.java | 75 ++++++++++++++++++ .../argeo/app/ui/people/GroupUiProvider.java | 77 +++++++++++++++++-- .../org/argeo/app/ui/people/NewOrgForm.java | 12 +-- .../argeo/app/ui/people/PeopleEntryArea.java | 7 +- .../org/argeo/app/ui/people/UserColumn.java | 39 ++++++++++ .../org/argeo/app/ui/people/UsersPart.java | 37 +-------- 9 files changed, 203 insertions(+), 52 deletions(-) create mode 100644 swt/org.argeo.app.ui/src/org/argeo/app/ui/people/ChooseUserDialog.java create mode 100644 swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UserColumn.java diff --git a/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties b/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties index 1215485..0cd0f2f 100644 --- a/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties +++ b/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle.properties @@ -36,6 +36,9 @@ groupAdminRole=Can create groups and organisations and modify them publisherRole=Can validate and publish content coworkerRole=Is an active user of the organisation +# Group +chooseAMember=Choose a member + # ContextAddressComposite chooseAnOrganisation=Choose an organisation street=Street diff --git a/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties b/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties index 22c5de6..e0520a5 100644 --- a/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties +++ b/swt/org.argeo.app.ui/OSGI-INF/l10n/bundle_fr.properties @@ -40,6 +40,9 @@ groupAdminRole=Peut cr publisherRole=Peut publier et valider du contenu coworkerRole=Est un membre en activité de l'organisation +# Group +chooseAMember=Choisir un membre + # ContextAddressComposite chooseAnOrganisation=Choisir une organisation street=Rue diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java index 84ba5f0..4bbcb62 100644 --- a/swt/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/SuiteMsg.java @@ -14,6 +14,8 @@ public enum SuiteMsg implements Localized { orgWizardWindowTitle, orgWizardPageTitle, legalName, legalForm, vatId, // Roles userAdminRole, groupAdminRole, publisherRole, coworkerRole, + // Group + chooseAMember, // ContextAddressComposite chooseAnOrganisation, street, streetComplement, zipCode, city, state, country, geopoint, // FilteredOrderableEntityTable diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/ChooseUserDialog.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/ChooseUserDialog.java new file mode 100644 index 0000000..60c79b4 --- /dev/null +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/ChooseUserDialog.java @@ -0,0 +1,75 @@ +package org.argeo.app.ui.people; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.ContentSession; +import org.argeo.api.cms.directory.CmsUserManager; +import org.argeo.api.cms.directory.HierarchyUnit; +import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.dialogs.CmsMessageDialog; +import org.argeo.cms.swt.widgets.SwtTableView; +import org.argeo.cms.swt.widgets.SwtTreeView; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +public class ChooseUserDialog extends CmsMessageDialog { + private ContentSession contentSession; + private CmsUserManager cmsUserManager; + private HierarchyUnit defaultHierarchyUnit; + + private Content selected; + + public ChooseUserDialog(Shell parentShell, String message, ContentSession contentSession, + CmsUserManager cmsUserManager, HierarchyUnit defaultHierarchyUnit) { + super(parentShell, message, CmsMessageDialog.QUESTION); + this.contentSession = contentSession; + this.cmsUserManager = cmsUserManager; + this.defaultHierarchyUnit = defaultHierarchyUnit; + } + + @Override + protected Control createInputArea(Composite parent) { + SashForm sashForm = new SashForm(parent, SWT.VERTICAL); + CmsSwtUtils.fill(sashForm); + + HierarchyUnitPart hierarchyPart = new HierarchyUnitPart(contentSession, cmsUserManager); + SwtTreeView directoriesView = new SwtTreeView<>(sashForm, SWT.BORDER, hierarchyPart); + + UsersPart usersPart = new UsersPart(contentSession, cmsUserManager); + + SwtTableView usersView = new SwtTableView<>(sashForm, SWT.BORDER, usersPart); + usersView.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // CONTROLLER + hierarchyPart.onSelected((o) -> { + if (o instanceof HierarchyUnit) { + HierarchyUnit hierarchyUnit = (HierarchyUnit) o; + usersPart.setInput(hierarchyUnit); + } + }); + + usersPart.onSelected((o) -> { + Content user = (Content) o; + selected = user; + }); + + hierarchyPart.refresh(); + + sashForm.setWeights(new int[] { 30, 70 }); + return sashForm; + } + + public Content getSelected() { + return selected; + } + + @Override + protected Point getInitialSize() { + return new Point(600, 800); + } + +} diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/GroupUiProvider.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/GroupUiProvider.java index f0a5b38..8cf24f0 100644 --- a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/GroupUiProvider.java +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/GroupUiProvider.java @@ -1,18 +1,34 @@ package org.argeo.app.ui.people; import org.argeo.api.acr.Content; +import org.argeo.api.acr.ContentSession; import org.argeo.api.acr.ldap.LdapAttr; import org.argeo.api.acr.ldap.LdapObj; +import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.cms.directory.CmsGroup; import org.argeo.api.cms.directory.CmsUserManager; import org.argeo.api.cms.directory.HierarchyUnit; +import org.argeo.app.ui.SuiteIcon; import org.argeo.app.ui.SuiteMsg; import org.argeo.app.ui.SuiteUiUtils; import org.argeo.cms.CurrentUser; +import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.swt.CmsSwtTheme; +import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.Selected; +import org.argeo.cms.swt.acr.SwtSection; import org.argeo.cms.swt.acr.SwtUiProvider; +import org.argeo.cms.swt.widgets.SwtTableView; +import org.argeo.cms.ux.widgets.AbstractTabularPart; +import org.argeo.cms.ux.widgets.CmsDialog; +import org.argeo.cms.ux.widgets.TabularPart; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; import org.osgi.service.useradmin.Role; public class GroupUiProvider implements SwtUiProvider { @@ -20,10 +36,37 @@ public class GroupUiProvider implements SwtUiProvider { @Override public Control createUiPart(Composite parent, Content context) { - CmsGroup group = context.adapt(CmsGroup.class); + CmsSwtTheme theme = CmsSwtUtils.getCmsTheme(parent); + Content hierarchyUnitContent = context.getParent().getParent(); HierarchyUnit hierarchyUnit = hierarchyUnitContent.adapt(HierarchyUnit.class); + ContentSession contentSession = ((ProvidedContent) context).getSession(); + + TabularPart membersPart = new AbstractTabularPart() { + Role[] roles = context.adapt(CmsGroup.class).getMembers(); + + @Override + public int getItemCount() { + return roles.length; + } + + @Override + public Content getData(int row) { + Role role = roles[row]; + Content content = ContentUtils.roleToContent(cmsUserManager, contentSession, role); + return content; + } + + }; + membersPart.addColumn(new UserColumn()); + + // VIEW + SwtSection area = new SwtSection(parent, 0, context); + area.setLayoutData(CmsSwtUtils.fillAll()); + area.setLayout(new GridLayout()); + + // title // TODO localise at content level String title; if (context.hasContentClass(LdapObj.organization)) @@ -32,12 +75,32 @@ public class GroupUiProvider implements SwtUiProvider { else title = SuiteMsg.group.lead() + " " + context.attr(LdapAttr.cn) + " (" + hierarchyUnit.getHierarchyUnitLabel(CurrentUser.locale()) + ")"; - SuiteUiUtils.addFormLabel(parent, title); + SuiteUiUtils.addFormLabel(area, title); + + // toolbar + ToolBar toolBar = new ToolBar(area, SWT.NONE); + toolBar.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); + + ToolItem deleteItem = new ToolItem(toolBar, SWT.FLAT); + deleteItem.setEnabled(false); + deleteItem.setImage(theme.getSmallIcon(SuiteIcon.delete)); + + ToolItem addItem = new ToolItem(toolBar, SWT.FLAT); + addItem.setImage(theme.getSmallIcon(SuiteIcon.add)); + addItem.addSelectionListener((Selected) (e) -> { + ChooseUserDialog chooseUserDialog = new ChooseUserDialog(parent.getDisplay().getActiveShell(), + SuiteMsg.chooseAMember.lead(), contentSession, cmsUserManager, hierarchyUnit); + if (chooseUserDialog.open() == CmsDialog.OK) { + Content chosen = chooseUserDialog.getSelected(); + // TODO add + } + }); - for (Role member : group.getMembers()) { - new Label(parent, 0).setText(member.getName()); - } - return null; + // members view + SwtTableView membersView = new SwtTableView<>(area, SWT.BORDER, membersPart); + membersView.setLayoutData(CmsSwtUtils.fillAll()); + membersView.refresh(); + return membersView; } diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/NewOrgForm.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/NewOrgForm.java index 7af60b5..a9800e6 100644 --- a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/NewOrgForm.java +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/NewOrgForm.java @@ -21,7 +21,7 @@ public class NewOrgForm extends AbstractGuidedForm { private Content hierarchyUnit; private CmsUserManager cmsUserManager; - protected Text firstNameT; + protected Text orgNameT; public NewOrgForm(CmsUserManager cmsUserManager, Content hierarchyUnit) { this.hierarchyUnit = hierarchyUnit; @@ -55,7 +55,7 @@ public class NewOrgForm extends AbstractGuidedForm { @Override public boolean canFinish() { - String firstName = firstNameT.getText(); + String firstName = orgNameT.getText(); if (isEmpty(firstName)) { return false; } else @@ -74,9 +74,9 @@ public class NewOrgForm extends AbstractGuidedForm { // FirstName SuiteUiUtils.createBoldLabel(parent, SuiteMsg.org); - firstNameT = new Text(parent, SWT.BORDER); + orgNameT = new Text(parent, SWT.BORDER); // firstNameTxt.setMessage("a first name"); - firstNameT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + orgNameT.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); ModifyListener ml = new ModifyListener() { private static final long serialVersionUID = 1939491923843870844L; @@ -87,9 +87,9 @@ public class NewOrgForm extends AbstractGuidedForm { } }; - firstNameT.addModifyListener(ml); + orgNameT.addModifyListener(ml); - firstNameT.setFocus(); + orgNameT.setFocus(); } } } diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java index 1cbd9be..e233991 100644 --- a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java @@ -23,9 +23,9 @@ import org.argeo.cms.swt.widgets.SwtGuidedFormDialog; import org.argeo.cms.swt.widgets.SwtTableView; import org.argeo.cms.swt.widgets.SwtTreeView; import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ux.widgets.CmsDialog; import org.argeo.cms.ux.widgets.Column; import org.argeo.cms.ux.widgets.GuidedForm; -import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.graphics.Point; @@ -83,7 +83,6 @@ public class PeopleEntryArea implements SwtUiProvider, CmsUiProvider { ToolItem deleteItem = new ToolItem(bottomToolBar, SWT.FLAT); deleteItem.setEnabled(false); -// CmsUiUtils.style(deleteItem, SuiteStyle.recentItems); deleteItem.setImage(theme.getSmallIcon(SuiteIcon.delete)); Menu menu = new Menu(Display.getCurrent().getActiveShell(), SWT.POP_UP); @@ -97,7 +96,7 @@ public class PeopleEntryArea implements SwtUiProvider, CmsUiProvider { Content huContent = ContentUtils.hierarchyUnitToContent(contentSession, hierarchyUnit); GuidedForm wizard = new NewUserForm(cmsUserManager, huContent); SwtGuidedFormDialog dialog = new SwtGuidedFormDialog(parent.getShell(), wizard); - if (dialog.open() == Window.OK) { + if (dialog.open() == CmsDialog.OK) { // TODO create } }); @@ -110,7 +109,7 @@ public class PeopleEntryArea implements SwtUiProvider, CmsUiProvider { Content huContent = ContentUtils.hierarchyUnitToContent(contentSession, hierarchyUnit); GuidedForm wizard = new NewOrgForm(cmsUserManager, huContent); SwtGuidedFormDialog dialog = new SwtGuidedFormDialog(parent.getShell(), wizard); - if (dialog.open() == Window.OK) { + if (dialog.open() == CmsDialog.OK) { // TODO create } }); diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UserColumn.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UserColumn.java new file mode 100644 index 0000000..c8c4ae1 --- /dev/null +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UserColumn.java @@ -0,0 +1,39 @@ +package org.argeo.app.ui.people; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.ldap.LdapAttr; +import org.argeo.api.acr.ldap.LdapObj; +import org.argeo.api.cms.ux.CmsIcon; +import org.argeo.app.ui.SuiteIcon; +import org.argeo.cms.auth.UserAdminUtils; +import org.argeo.cms.ux.widgets.Column; +import org.osgi.service.useradmin.User; + +public class UserColumn implements Column { + @Override + public String getText(Content role) { + if (role.hasContentClass(LdapObj.inetOrgPerson)) + return UserAdminUtils.getUserDisplayName(role.adapt(User.class)); + else if (role.hasContentClass(LdapObj.organization)) + return role.attr(LdapAttr.o); + else if (role.hasContentClass(LdapObj.groupOfNames)) + return role.attr(LdapAttr.cn); + else + return null; + } + + @Override + public CmsIcon getIcon(Content role) { + if (role.hasContentClass(LdapObj.posixAccount)) + return SuiteIcon.user; + else if (role.hasContentClass(LdapObj.inetOrgPerson)) + return SuiteIcon.person; + else if (role.hasContentClass(LdapObj.organization)) + return SuiteIcon.organisationContact; + else if (role.hasContentClass(LdapObj.groupOfNames)) + return SuiteIcon.group; + else + return null; + } + +} diff --git a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UsersPart.java b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UsersPart.java index 96e2444..c615ebf 100644 --- a/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UsersPart.java +++ b/swt/org.argeo.app.ui/src/org/argeo/app/ui/people/UsersPart.java @@ -5,19 +5,13 @@ import java.util.List; import org.argeo.api.acr.Content; import org.argeo.api.acr.ContentSession; -import org.argeo.api.acr.ldap.LdapAttr; import org.argeo.api.acr.ldap.LdapObj; import org.argeo.api.cms.directory.CmsUserManager; import org.argeo.api.cms.directory.HierarchyUnit; import org.argeo.api.cms.directory.UserDirectory; -import org.argeo.api.cms.ux.CmsIcon; -import org.argeo.app.ui.SuiteIcon; import org.argeo.cms.acr.ContentUtils; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.ux.widgets.Column; import org.argeo.cms.ux.widgets.DefaultTabularPart; import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; public class UsersPart extends DefaultTabularPart { private ContentSession contentSession; @@ -26,33 +20,7 @@ public class UsersPart extends DefaultTabularPart { public UsersPart(ContentSession contentSession, CmsUserManager cmsUserManager) { this.contentSession = contentSession; this.cmsUserManager = cmsUserManager; - addColumn(new Column() { - - @Override - public String getText(Content role) { - if (role.hasContentClass(LdapObj.inetOrgPerson)) - return UserAdminUtils.getUserDisplayName(role.adapt(User.class)); - else if (role.hasContentClass(LdapObj.organization)) - return role.attr(LdapAttr.o); - else if (role.hasContentClass(LdapObj.groupOfNames)) - return role.attr(LdapAttr.cn); - else - return null; - } - - @Override - public CmsIcon getIcon(Content role) { - if (role.hasContentClass(LdapObj.posixAccount)) - return SuiteIcon.user; - else if (role.hasContentClass(LdapObj.inetOrgPerson)) - return SuiteIcon.person; - else if (role.hasContentClass(LdapObj.organization)) - return SuiteIcon.organisationContact; - else if (role.hasContentClass(LdapObj.groupOfNames)) - return SuiteIcon.group; - else - return null; - } + addColumn(new UserColumn() { @Override public int getWidth() { @@ -79,8 +47,7 @@ public class UsersPart extends DefaultTabularPart { || directChild.isType(HierarchyUnit.Type.ROLES))) { for (Role r : ud.getHierarchyUnitRoles(directChild, null, false)) { Content content = ContentUtils.roleToContent(cmsUserManager, contentSession, r); - if (content.hasContentClass(LdapObj.inetOrgPerson, LdapObj.organization, - LdapObj.groupOfNames)) + if (content.hasContentClass(LdapObj.inetOrgPerson, LdapObj.organization, LdapObj.groupOfNames)) roles.add(content); } } -- 2.30.2