diff --git a/src/main/java/org/olat/modules/qpool/QPoolSecurityCallback.java b/src/main/java/org/olat/modules/qpool/QPoolSecurityCallback.java index 7072a7f0a2a4027573796da323625756dbf910f7..4bae90c1f725aa0528ba8f3d1c2e4c87c9eba712 100644 --- a/src/main/java/org/olat/modules/qpool/QPoolSecurityCallback.java +++ b/src/main/java/org/olat/modules/qpool/QPoolSecurityCallback.java @@ -26,6 +26,10 @@ package org.olat.modules.qpool; * */ public interface QPoolSecurityCallback { + + public void setAdmin(boolean admin); + + public void setPoolAdmin(boolean poolAdmin); boolean canUseCollections(); @@ -35,6 +39,18 @@ public interface QPoolSecurityCallback { boolean canUseReviewProcess(); - boolean canAdmin(); + boolean canEditAllQuestions(); + + boolean canConfigReviewProcess(); + + boolean canConfigTaxonomies(); + + boolean canConfigPools(); + + boolean canConfigItemTypes(); + + boolean canConfigEducationalContext(); + + boolean canConfigLicences(); } diff --git a/src/main/java/org/olat/modules/qpool/QuestionItemSecurityCallback.java b/src/main/java/org/olat/modules/qpool/QuestionItemSecurityCallback.java index 2454fd8c64c88b0fabda55d57de78ae879253ada..4771c2c6007e2460ed5fab49cbb61eb640c30a84 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionItemSecurityCallback.java +++ b/src/main/java/org/olat/modules/qpool/QuestionItemSecurityCallback.java @@ -35,6 +35,8 @@ public interface QuestionItemSecurityCallback { public void setAdmin(boolean admin); + public void setPoolAdmin(boolean poolAdmin); + public boolean canEditQuestion(); public boolean canEditMetadata(); diff --git a/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java b/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java index 6e546128f505963f35faf006bcbc296b6dd00125..7acd6c6f34239f8797dac4e303aed46dfb19dd07 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java +++ b/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java @@ -61,6 +61,14 @@ public class QuestionPoolModule extends AbstractSpringModule implements ConfigOn private static final String FINAL_VISIBLE_TEACH = "final.visible.teach"; private static final String TAXONOMY_QPOOL_KEY = "taxonomy.qpool.key"; public static final String DEFAULT_TAXONOMY_QPOOL_IDENTIFIER = "QPOOL"; + private static final String POOL_ADMIN_METADATA = "pool.admin.metadata"; + private static final String POOL_ADMIN_STATUS = "pool.admin.status"; + private static final String POOL_ADMIN_REVIEW_PROCESS = "pool.admin.review.process"; + private static final String POOL_ADMIN_TAXONOMY = "pool.admin.taxonomy"; + private static final String POOL_ADMIN_POOLS = "pool.admin.pools"; + private static final String POOL_ADMIN_ITEM_TYPES = "pool.admin.item.types"; + private static final String POOL_ADMIN_EDUCATIONAL_CONTEXT = "pool.admin.educational.context"; + private static final String POOL_ADMIN_LICENSES = "pool.admin.licenses"; private boolean collectionsEnabled = true; private boolean poolsEnabled = true; @@ -70,6 +78,15 @@ public class QuestionPoolModule extends AbstractSpringModule implements ConfigOn private boolean finalVisibleTeach = false; private String taxonomyQPoolKey; + private boolean poolAdminAllowedToEditMetadata = false; + private boolean poolAdminAllowedToEditStatus = false; + private boolean poolAdminAllowedToConfigReviewProcess = true; + private boolean poolAdminAllowedToConfigTaxonomy = true; + private boolean poolAdminAllowedToConfigPools = true; + private boolean poolAdminAllowedToConfigItemTypes = true; + private boolean poolAdminAllowedToConfigEducationalContext = true; + private boolean poolAdminAllowedToConfigLicenses = true; + @Autowired private DB dbInstance; @Autowired @@ -154,6 +171,47 @@ public class QuestionPoolModule extends AbstractSpringModule implements ConfigOn if(StringHelper.containsNonWhitespace(taxonomyQPoolKeyObj)) { taxonomyQPoolKey = taxonomyQPoolKeyObj; } + + String poolAdminAllowedToEditMetadataObj = getStringPropertyValue(POOL_ADMIN_METADATA, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToEditMetadataObj)) { + poolAdminAllowedToEditMetadata = "true".equals(poolAdminAllowedToEditMetadataObj); + } + + String poolAdminAllowedToEditStatusObj = getStringPropertyValue(POOL_ADMIN_STATUS, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToEditStatusObj)) { + poolAdminAllowedToEditStatus = "true".equals(poolAdminAllowedToEditStatusObj); + } + + String poolAdminAllowedToConfigReviewProcessObj = getStringPropertyValue(POOL_ADMIN_REVIEW_PROCESS, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigReviewProcessObj)) { + poolAdminAllowedToConfigReviewProcess = "true".equals(poolAdminAllowedToConfigReviewProcessObj); + } + + String poolAdminAllowedToConfigTaxonomyObj = getStringPropertyValue(POOL_ADMIN_TAXONOMY, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigTaxonomyObj)) { + poolAdminAllowedToConfigTaxonomy = "true".equals(poolAdminAllowedToConfigTaxonomyObj); + } + + String poolAdminAllowedToConfigPoolsObj = getStringPropertyValue(POOL_ADMIN_POOLS, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigPoolsObj)) { + poolAdminAllowedToConfigPools = "true".equals(poolAdminAllowedToConfigPoolsObj); + } + + String poolAdminAllowedToConfigItemTypesObj = getStringPropertyValue(POOL_ADMIN_ITEM_TYPES, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigItemTypesObj)) { + poolAdminAllowedToConfigItemTypes = "true".equals(poolAdminAllowedToConfigItemTypesObj); + } + + String poolAdminAllowedToConfigEducationalContextObj = getStringPropertyValue(POOL_ADMIN_EDUCATIONAL_CONTEXT, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigEducationalContextObj)) { + poolAdminAllowedToConfigEducationalContext = "true".equals(poolAdminAllowedToConfigEducationalContextObj); + } + + String poolAdminAllowedToConfigLicensesObj = getStringPropertyValue(POOL_ADMIN_LICENSES, true); + if(StringHelper.containsNonWhitespace(poolAdminAllowedToConfigLicensesObj)) { + poolAdminAllowedToConfigLicenses = "true".equals(poolAdminAllowedToConfigLicensesObj); + } + } @Override @@ -270,4 +328,77 @@ public class QuestionPoolModule extends AbstractSpringModule implements ConfigOn setStringProperty(TAXONOMY_QPOOL_KEY, taxonomyQPoolKey, true); } + public boolean isPoolAdminAllowedToEditMetadata() { + return poolAdminAllowedToEditMetadata; + } + + public void setPoolAdminAllowedToEditMetadata(boolean poolAdminAllowedToEditMetadata) { + this.poolAdminAllowedToEditMetadata = poolAdminAllowedToEditMetadata; + setStringProperty(POOL_ADMIN_METADATA, Boolean.toString(poolAdminAllowedToEditMetadata), true); + } + + public boolean isPoolAdminAllowedToEditStatus() { + return poolAdminAllowedToEditStatus; + } + + public void setPoolAdminAllowedToEditStatus(boolean poolAdminAllowedToEditStatus) { + this.poolAdminAllowedToEditStatus = poolAdminAllowedToEditStatus; + setStringProperty(POOL_ADMIN_STATUS, Boolean.toString(poolAdminAllowedToEditStatus), true); + } + + + public boolean isPoolAdminAllowedToConfigReviewProcess() { + return poolAdminAllowedToConfigReviewProcess; + } + + public void setPoolAdminAllowedToConfigReviewProcess(boolean poolAdminAllowedToConfigReviewProcess) { + this.poolAdminAllowedToConfigReviewProcess = poolAdminAllowedToConfigReviewProcess; + setStringProperty(POOL_ADMIN_REVIEW_PROCESS, Boolean.toString(poolAdminAllowedToConfigReviewProcess), true); + } + + public boolean isPoolAdminAllowedToConfigTaxonomy() { + return poolAdminAllowedToConfigTaxonomy; + } + + public void setPoolAdminAllowedToConfigTaxonomy(boolean poolAdminAllowedToConfigTaxonomy) { + this.poolAdminAllowedToConfigTaxonomy = poolAdminAllowedToConfigTaxonomy; + setStringProperty(POOL_ADMIN_TAXONOMY, Boolean.toString(poolAdminAllowedToConfigTaxonomy), true); + } + + public boolean isPoolAdminAllowedToConfigPools() { + return poolAdminAllowedToConfigPools; + } + + public void setPoolAdminAllowedToConfigPools(boolean poolAdminAllowedToConfigPools) { + this.poolAdminAllowedToConfigPools = poolAdminAllowedToConfigPools; + setStringProperty(POOL_ADMIN_POOLS, Boolean.toString(poolAdminAllowedToConfigPools), true); + } + + public boolean isPoolAdminAllowedToConfigItemTypes() { + return poolAdminAllowedToConfigItemTypes; + } + + public void setPoolAdminAllowedToConfigItemTypes(boolean poolAdminAllowedToConfigItemTypes) { + this.poolAdminAllowedToConfigItemTypes = poolAdminAllowedToConfigItemTypes; + setStringProperty(POOL_ADMIN_ITEM_TYPES, Boolean.toString(poolAdminAllowedToConfigItemTypes), true); + } + + public boolean isPoolAdminAllowedToConfigEducationalContext() { + return poolAdminAllowedToConfigEducationalContext; + } + + public void setPoolAdminAllowedToConfigEducationalContext(boolean poolAdminAllowedToConfigEducationalContext) { + this.poolAdminAllowedToConfigEducationalContext = poolAdminAllowedToConfigEducationalContext; + setStringProperty(POOL_ADMIN_EDUCATIONAL_CONTEXT, Boolean.toString(poolAdminAllowedToConfigEducationalContext), true); + } + + public boolean isPoolAdminAllowedToConfigLicenses() { + return poolAdminAllowedToConfigLicenses; + } + + public void setPoolAdminAllowedToConfigLicenses(boolean poolAdminAllowedToConfigLicenses) { + this.poolAdminAllowedToConfigLicenses = poolAdminAllowedToConfigLicenses; + setStringProperty(POOL_ADMIN_LICENSES, Boolean.toString(poolAdminAllowedToConfigLicenses), true); + } + } diff --git a/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java index c52e2f0b3f30f1c10285726a5e0e424a6878cd7a..e338252e59e9f049e994bf1254c8b51884b37a07 100644 --- a/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java +++ b/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java @@ -21,7 +21,9 @@ package org.olat.modules.qpool.security; import org.olat.modules.qpool.QuestionItemSecurityCallback; import org.olat.modules.qpool.QuestionItemView; +import org.olat.modules.qpool.QuestionPoolModule; import org.olat.modules.qpool.ui.QuestionItemsSource; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -37,8 +39,12 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback private QuestionItemView itemView; private QuestionItemsSource questionItemSource; - private boolean isAdmin = false; + private boolean admin = false; + private boolean poolAdmin = false; + @Autowired + private QuestionPoolModule qpoolModule; + @Override public void setQuestionItemView(QuestionItemView itemView) { this.itemView = itemView; @@ -51,22 +57,31 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback @Override public void setAdmin(boolean admin) { - this.isAdmin = admin; + this.admin = admin; + } + + @Override + public void setPoolAdmin(boolean poolAdmin) { + this.poolAdmin = poolAdmin; } @Override public boolean canEditQuestion() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); } @Override public boolean canEditMetadata() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata()); } @Override public boolean canRemoveTaxonomy() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); } @Override @@ -86,38 +101,58 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback @Override public boolean canSetDraft() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canSetRevised() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canSetReview() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canSetFinal() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canSetEndOfLife() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin + || itemView.isAuthor() + || itemView.isEditableInPool() + || itemView.isEditableInShare() + || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canDelete() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); } @Override public boolean canRemove() { return questionItemSource.isRemoveEnabled() - && (isAdmin || itemView.isAuthor()); + && (admin || itemView.isAuthor()); } @Override @@ -127,7 +162,7 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback @Override public boolean canChangeVersion() { - return isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); + return admin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare(); } } diff --git a/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackFactory.java b/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackFactory.java index 3f775f9e078df7120cfb25cf362b55ece127007c..9c1aaded4cc313a71da7772590b53701f3687455 100644 --- a/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackFactory.java +++ b/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackFactory.java @@ -42,8 +42,8 @@ public class QPoolSecurityCallbackFactory { @Autowired private QuestionPoolModule qpoolModule; - public QuestionItemSecurityCallback createQuestionItemSecurityCallback(QuestionItemView itemView, QuestionItemsSource questionItemSource, - boolean isOLATAdmin) { + public QuestionItemSecurityCallback createQuestionItemSecurityCallback(QuestionItemView itemView, + QuestionItemsSource questionItemSource, Roles roles) { QuestionItemSecurityCallback securityCallback; if (qpoolModule.isReviewProcessEnabled()) { securityCallback = CoreSpringFactory.getImpl(ReviewProcessSecurityCallback.class); @@ -52,17 +52,15 @@ public class QPoolSecurityCallbackFactory { } securityCallback.setQuestionItemView(itemView); securityCallback.setQuestionItemSource(questionItemSource); - securityCallback.setAdmin(isOLATAdmin); + securityCallback.setAdmin(roles.isOLATAdmin()); + securityCallback.setPoolAdmin(roles.isPoolAdmin()); return securityCallback; } public QPoolSecurityCallback createQPoolSecurityCallback(Roles roles) { - QPoolSecurityCallback securityCallback; - if (roles.isOLATAdmin()) { - securityCallback = CoreSpringFactory.getImpl(AdministratorQPoolSecurityCallback.class); - } else { - securityCallback = CoreSpringFactory.getImpl(RegularQPoolSecurityCallback.class); - } + QPoolSecurityCallback securityCallback = CoreSpringFactory.getImpl(QPoolSecurityCallbackImpl.class); + securityCallback.setAdmin(roles.isOLATAdmin()); + securityCallback.setPoolAdmin(roles.isPoolAdmin()); return securityCallback; } diff --git a/src/main/java/org/olat/modules/qpool/security/AdministratorQPoolSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackImpl.java similarity index 57% rename from src/main/java/org/olat/modules/qpool/security/AdministratorQPoolSecurityCallback.java rename to src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackImpl.java index 7c5d33c8cad762e48e1d6877d738fdca1eafd4a3..bde9a0c40a3d4c9ba07fb7e42b9562786a4df226 100644 --- a/src/main/java/org/olat/modules/qpool/security/AdministratorQPoolSecurityCallback.java +++ b/src/main/java/org/olat/modules/qpool/security/QPoolSecurityCallbackImpl.java @@ -33,11 +33,24 @@ import org.springframework.stereotype.Component; */ @Component @Scope("prototype") -public class AdministratorQPoolSecurityCallback implements QPoolSecurityCallback { +public class QPoolSecurityCallbackImpl implements QPoolSecurityCallback { + private boolean admin = false; + private boolean poolAdmin = false; + @Autowired private QuestionPoolModule qpoolModule; - + + @Override + public void setAdmin(boolean admin) { + this.admin = admin; + } + + @Override + public void setPoolAdmin(boolean poolAdmin) { + this.poolAdmin = poolAdmin; + } + @Override public boolean canUseCollections() { return qpoolModule.isCollectionsEnabled(); @@ -59,9 +72,38 @@ public class AdministratorQPoolSecurityCallback implements QPoolSecurityCallback } @Override - public boolean canAdmin() { - return true; + public boolean canEditAllQuestions() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata()); + } + + @Override + public boolean canConfigReviewProcess() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigReviewProcess()); + } + + @Override + public boolean canConfigTaxonomies() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigTaxonomy()); } + @Override + public boolean canConfigPools() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigPools()); + } + + @Override + public boolean canConfigItemTypes() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigItemTypes()); + } + + @Override + public boolean canConfigEducationalContext() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigEducationalContext()); + } + + @Override + public boolean canConfigLicences() { + return admin || (poolAdmin && qpoolModule.isPoolAdminAllowedToConfigLicenses()); + } } diff --git a/src/main/java/org/olat/modules/qpool/security/RegularQPoolSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/RegularQPoolSecurityCallback.java deleted file mode 100644 index dd5bac65a2472bd3c9148ccde7575f8565412e2a..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/modules/qpool/security/RegularQPoolSecurityCallback.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.modules.qpool.security; - -import org.olat.modules.qpool.QPoolSecurityCallback; -import org.olat.modules.qpool.QuestionPoolModule; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -/** - * - * Initial date: 05.12.2017<br> - * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com - * - */ -@Component -@Scope("prototype") -public class RegularQPoolSecurityCallback implements QPoolSecurityCallback { - - @Autowired - private QuestionPoolModule qpoolModule; - - @Override - public boolean canUseCollections() { - return qpoolModule.isCollectionsEnabled(); - } - - @Override - public boolean canUsePools() { - return qpoolModule.isPoolsEnabled(); - } - - @Override - public boolean canUseGroups() { - return qpoolModule.isSharesEnabled(); - } - - @Override - public boolean canUseReviewProcess() { - return qpoolModule.isReviewProcessEnabled(); - } - - @Override - public boolean canAdmin() { - return false; - } - -} diff --git a/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java index 6d95b93abb558468ea34198131f11491415328ee..b5bcc7f867521f18d6ee10def9df35af90e62151 100644 --- a/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java +++ b/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java @@ -24,6 +24,7 @@ import java.util.Collection; import org.olat.modules.qpool.QuestionItemSecurityCallback; import org.olat.modules.qpool.QuestionItemView; +import org.olat.modules.qpool.QuestionPoolModule; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.ReviewService; import org.olat.modules.qpool.ui.QuestionItemsSource; @@ -49,8 +50,11 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba private QuestionItemView itemView; private QuestionItemsSource questionItemSource; - private boolean isAdmin = false; + private boolean admin = false; + private boolean poolAdmin = false; + @Autowired + private QuestionPoolModule qpoolModule; @Autowired private ReviewService reviewService; @@ -66,38 +70,43 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba @Override public void setAdmin(boolean admin) { - this.isAdmin = admin; + this.admin = admin; + } + + @Override + public void setPoolAdmin(boolean poolAdmin) { + this.poolAdmin = poolAdmin; } @Override public boolean canEditQuestion() { return reviewService.isEditableQuestionStatus(itemView.getQuestionStatus()) - && (isAdmin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare()) ; + && (admin || itemView.isAuthor() || itemView.isEditableInPool() || itemView.isEditableInShare()) ; } @Override public boolean canEditMetadata() { - return isAdmin || itemView.isAuthor() || itemView.isManager(); + return admin || itemView.isAuthor() || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata()); } @Override public boolean canRemoveTaxonomy() { return QuestionStatus.draft.equals(itemView.getQuestionStatus()) - && (isAdmin || itemView.isAuthor() || itemView.isManager()); + && (admin || itemView.isAuthor() || itemView.isManager()); } @Override public boolean canStartReview() { return itemView.isReviewableFormat() && reviewService.isEditableQuestionStatus(itemView.getQuestionStatus()) - && (isAdmin || itemView.isAuthor()); + && (admin || itemView.isAuthor()); } @Override public boolean canReviewNotStartable() { return !itemView.isReviewableFormat() && reviewService.isEditableQuestionStatus(itemView.getQuestionStatus()) - && (isAdmin || itemView.isAuthor()); + && (admin || itemView.isAuthor()); } @Override @@ -109,13 +118,13 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba @Override public boolean canSetDraft() { - return isAdmin; + return admin; } @Override public boolean canSetRevised() { return itemView.isReviewableFormat() - && (isAdmin || itemView.isManager()); + && (admin || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus())); } @Override @@ -126,24 +135,24 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba @Override public boolean canSetFinal() { return itemView.isReviewableFormat() - && (isAdmin || itemView.isManager()); + && (admin || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus())); } @Override public boolean canSetEndOfLife() { - return isAdmin || itemView.isManager(); + return admin || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()); } @Override public boolean canDelete() { return DELETABLE_STATES.contains(itemView.getQuestionStatus()) - && (isAdmin || itemView.isManager()); + && (admin || itemView.isManager()); } @Override public boolean canRemove() { return questionItemSource.isRemoveEnabled() - && (isAdmin || itemView.isAuthor()); + && (admin || itemView.isAuthor()); } @Override diff --git a/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java b/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java index c479afa648ac965bcfd52ddceea4cd9fc0f1ba5d..3c01421d8f4224328b88a086624a70e67ce0c18f 100644 --- a/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java +++ b/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java @@ -57,6 +57,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.Roles; import org.olat.core.util.StringHelper; import org.olat.core.util.event.EventBus; import org.olat.core.util.event.GenericEventListener; @@ -105,7 +106,7 @@ public abstract class AbstractItemListController extends FormBasicController private EventBus eventBus; private QuestionItemsSource itemsSource; - private final boolean isOLATAdmin; + private final Roles roles; public AbstractItemListController(UserRequest ureq, WindowControl wControl, QPoolSecurityCallback securityCallback, QuestionItemsSource source, String key) { @@ -129,7 +130,7 @@ public abstract class AbstractItemListController extends FormBasicController this.securityCallback = securityCallback; this.prefsKey = key; this.itemsSource = source; - this.isOLATAdmin = ureq.getUserSession().getRoles().isOLATAdmin(); + this.roles = ureq.getUserSession().getRoles(); this.restrictToFormat = restrictToFormat; eventBus = ureq.getUserSession().getSingleUserEventCenter(); @@ -456,7 +457,7 @@ public abstract class AbstractItemListController extends FormBasicController protected ItemRow forgeRow(QuestionItemView item) { boolean marked = item.isMarked(); QuestionItemSecurityCallback securityCallback = qpoolSecurityCallbackFactory - .createQuestionItemSecurityCallback(item, getSource(), isOLATAdmin); + .createQuestionItemSecurityCallback(item, getSource(), roles); ItemRow row = new ItemRow(item, securityCallback); FormLink markLink = uifactory.addFormLink("mark_" + row.getKey(), "mark", " ", null, null, Link.NONTRANSLATED); markLink.setIconLeftCSS(marked ? Mark.MARK_CSS_LARGE : Mark.MARK_ADD_CSS_LARGE); @@ -469,7 +470,7 @@ public abstract class AbstractItemListController extends FormBasicController protected ItemRow wrapNewItem(QuestionItem item) { ItemWrapper itemWrapper = ItemWrapper.builder(item).setAuthor(true).create(); QuestionItemSecurityCallback securityCallback = qpoolSecurityCallbackFactory - .createQuestionItemSecurityCallback(itemWrapper, getSource(), isOLATAdmin); + .createQuestionItemSecurityCallback(itemWrapper, getSource(), roles); return new ItemRow(itemWrapper, securityCallback); } } diff --git a/src/main/java/org/olat/modules/qpool/ui/_content/item_list_overview.html b/src/main/java/org/olat/modules/qpool/ui/_content/item_list_overview.html index 033fc0589377173085bea900577efed8e486546c..29f9eee1ab3e491da7d4e75a5d427b27f2c812a5 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_content/item_list_overview.html +++ b/src/main/java/org/olat/modules/qpool/ui/_content/item_list_overview.html @@ -1,5 +1,5 @@ <h4> - <i class="o_icon o_icon-fw o_icon_qpool"> </i> + <i class="o_icon o_icon-fw o_icon_qpool"> </i> $r.translate("menu.pools.main") </h4> <div class="clearfix"> diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties index a48d80bb09dc8ac2f97882bdca890290f9f1b373..62d0db743aaefd54ac8d569febc2ce86d4487dde 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties @@ -108,6 +108,7 @@ menu.admin.levels.alt=Stufe menu.admin.licenses=Lizenz menu.admin.licenses.alt=Lizenz menu.admin.pools=Pool-Verwaltung +menu.admin.review.process=Beurteilungsprozess menu.admin.studyfields=Fachbereich menu.admin.studyfields.alt=Fachbereich menu.admin.types=Fragetyp diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties index c700b6eebd56d862bb717d3aa586cde8d3690fc3..a3eff9954f2429832bc5d8dd3d5fb3c9fc2aab5e 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties @@ -108,6 +108,7 @@ menu.admin.levels.alt=Level menu.admin.licenses=License menu.admin.licenses.alt=License menu.admin.pools=Pool administration +menu.admin.review.process=Review Process menu.admin.studyfields=Subject menu.admin.studyfields.alt=Subject menu.admin.types=Type diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/QuestionPoolAdminConfigurationController.java b/src/main/java/org/olat/modules/qpool/ui/admin/QuestionPoolAdminConfigurationController.java index f510b2d15c9c714d327116715f257226b9e57652..714abd694765312cb8364fa3ca37f01adc0cd4fc 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/QuestionPoolAdminConfigurationController.java +++ b/src/main/java/org/olat/modules/qpool/ui/admin/QuestionPoolAdminConfigurationController.java @@ -19,7 +19,9 @@ */ package org.olat.modules.qpool.ui.admin; +import java.util.Collection; import java.util.List; +import java.util.stream.Stream; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; @@ -48,12 +50,31 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class QuestionPoolAdminConfigurationController extends FormBasicController { - private static final String[] onKeys = new String[] { "on" }; + private static final String[] onKeys = { "on" }; + private static final String POOL_MANAGER_EDIT_METADATA = "pool.manager.edit.matadata"; + private static final String POOL_MANAGER_EDIT_STATUS = "pool.manager.edit.status"; + private static final String POOL_MANAGER_REVIEW_PROCESS = "pool.manager.review.process"; + private static final String POOL_MANAGER_TAXONOMY = "pool.manager.taxonomy"; + private static final String POOL_MANAGER_POOLS = "pool.manager.pools"; + private static final String POOL_MANAGER_ITEM_TYPES = "pool.manager.item.types"; + private static final String POOL_MANAGER_EDUCATIONAL_CONTEXT = "pool.manager.educational.context"; + private static final String POOL_MANAGER_LICENSES = "pool.manager.licenses"; + private static final String[] POOL_MANAGER_RIGHTS_KEYS = { + POOL_MANAGER_EDIT_METADATA, + POOL_MANAGER_EDIT_STATUS, + POOL_MANAGER_REVIEW_PROCESS, + POOL_MANAGER_TAXONOMY, + POOL_MANAGER_POOLS, + POOL_MANAGER_ITEM_TYPES, + POOL_MANAGER_EDUCATIONAL_CONTEXT, + POOL_MANAGER_LICENSES + }; private MultipleSelectionElement reviewProcessEnabledEl; private MultipleSelectionElement collectionsEnabledEl; private MultipleSelectionElement poolsEnabledEl; private MultipleSelectionElement sharesEnabledEl; + private MultipleSelectionElement poolManagerRightsEl; private SingleSelection taxonomyTreeEl; private CloseableModalController closeableModalCtrl; @@ -69,36 +90,36 @@ public class QuestionPoolAdminConfigurationController extends FormBasicControlle private QPoolService qpoolService; public QuestionPoolAdminConfigurationController(UserRequest ureq, WindowControl wControl) { - super(ureq, wControl); + super(ureq, wControl, "admin_config"); initForm(ureq); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - setFormTitle("admin.configuration.title"); + FormLayoutContainer moduleCont = FormLayoutContainer.createDefaultFormLayout("module", getTranslator()); + moduleCont.setFormTitle(translate("admin.configuration.title")); + moduleCont.setRootForm(mainForm); + formLayout.add("module", moduleCont); String[] onValues = new String[] { translate("on") }; - reviewProcessEnabledEl = uifactory.addCheckboxesHorizontal("review.process.enabled", formLayout, onKeys, onValues); + reviewProcessEnabledEl = uifactory.addCheckboxesHorizontal("review.process.enabled", moduleCont, onKeys, onValues); reviewProcessEnabledEl.addActionListener(FormEvent.ONCHANGE); if (qpoolModule.isReviewProcessEnabled()) { reviewProcessEnabledEl.select(onKeys[0], true); } - collectionsEnabledEl = uifactory.addCheckboxesHorizontal("collections.enabled", formLayout, onKeys, onValues); - collectionsEnabledEl.addActionListener(FormEvent.ONCHANGE); + collectionsEnabledEl = uifactory.addCheckboxesHorizontal("collections.enabled", moduleCont, onKeys, onValues); if (qpoolModule.isCollectionsEnabled()) { collectionsEnabledEl.select(onKeys[0], true); } - poolsEnabledEl = uifactory.addCheckboxesHorizontal("pools.enabled", formLayout, onKeys, onValues); - poolsEnabledEl.addActionListener(FormEvent.ONCHANGE); + poolsEnabledEl = uifactory.addCheckboxesHorizontal("pools.enabled", moduleCont, onKeys, onValues); if (qpoolModule.isPoolsEnabled()) { poolsEnabledEl.select(onKeys[0], true); } - sharesEnabledEl = uifactory.addCheckboxesHorizontal("shares.enabled", formLayout, onKeys, onValues); - sharesEnabledEl.addActionListener(FormEvent.ONCHANGE); + sharesEnabledEl = uifactory.addCheckboxesHorizontal("shares.enabled", moduleCont, onKeys, onValues); if (qpoolModule.isSharesEnabled()) { sharesEnabledEl.select(onKeys[0], true); } @@ -115,7 +136,7 @@ public class QuestionPoolAdminConfigurationController extends FormBasicControlle } String selectedTaxonomyQPoolKey = qpoolModule.getTaxonomyQPoolKey(); - taxonomyTreeEl = uifactory.addDropdownSingleselect("selected.taxonomy.tree", formLayout, taxonomyKeys, taxonomyValues, null); + taxonomyTreeEl = uifactory.addDropdownSingleselect("selected.taxonomy.tree", moduleCont, taxonomyKeys, taxonomyValues, null); taxonomyTreeEl.setEnabled(false); if(StringHelper.containsNonWhitespace(selectedTaxonomyQPoolKey)) { for(String taxonomyKey:taxonomyKeys) { @@ -125,11 +146,36 @@ public class QuestionPoolAdminConfigurationController extends FormBasicControlle } } + FormLayoutContainer poolManagerRightsCont = FormLayoutContainer.createDefaultFormLayout("poolManagerRights", getTranslator()); + poolManagerRightsCont.setFormTitle(translate("admin.pool.manager.title")); + poolManagerRightsCont.setRootForm(mainForm); + formLayout.add("poolManagerRights", poolManagerRightsCont); + + poolManagerRightsEl = uifactory.addCheckboxesVertical("pool.manager.allowed", poolManagerRightsCont, + POOL_MANAGER_RIGHTS_KEYS, translateKeys(POOL_MANAGER_RIGHTS_KEYS), 1); + poolManagerRightsEl.select(POOL_MANAGER_EDIT_METADATA, qpoolModule.isPoolAdminAllowedToEditMetadata()); + poolManagerRightsEl.select(POOL_MANAGER_EDIT_STATUS, qpoolModule.isPoolAdminAllowedToEditStatus()); + poolManagerRightsEl.select(POOL_MANAGER_REVIEW_PROCESS, qpoolModule.isPoolAdminAllowedToConfigReviewProcess()); + poolManagerRightsEl.select(POOL_MANAGER_TAXONOMY, qpoolModule.isPoolAdminAllowedToConfigTaxonomy()); + poolManagerRightsEl.select(POOL_MANAGER_POOLS, qpoolModule.isPoolAdminAllowedToConfigPools()); + poolManagerRightsEl.select(POOL_MANAGER_ITEM_TYPES, qpoolModule.isPoolAdminAllowedToConfigItemTypes()); + poolManagerRightsEl.select(POOL_MANAGER_EDUCATIONAL_CONTEXT, qpoolModule.isPoolAdminAllowedToConfigEducationalContext()); + poolManagerRightsEl.select(POOL_MANAGER_LICENSES, qpoolModule.isPoolAdminAllowedToConfigLicenses()); + + FormLayoutContainer buttonsWrapperCont = FormLayoutContainer.createDefaultFormLayout("global", getTranslator()); + buttonsWrapperCont.setRootForm(mainForm); + formLayout.add("buttonsWrapper", buttonsWrapperCont); FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); - formLayout.add(buttonsCont); + buttonsWrapperCont.add(buttonsCont); uifactory.addFormSubmitButton("save", buttonsCont); } + private String[] translateKeys(String[] keys) { + return Stream.of(keys) + .map(key -> getTranslator().translate(key)) + .toArray(String[]::new); + } + @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if (reviewProcessEnabledEl == source) { @@ -192,6 +238,24 @@ public class QuestionPoolAdminConfigurationController extends FormBasicControlle String selectedTaxonomyQPoolKey = taxonomyTreeEl.getSelectedKey(); qpoolModule.setTaxonomyQPoolKey(selectedTaxonomyQPoolKey); + + Collection<String> selectedPoolManagerRights = poolManagerRightsEl.getSelectedKeys(); + boolean poolAdminAllowedToEditMetadata = selectedPoolManagerRights.contains(POOL_MANAGER_EDIT_METADATA); + qpoolModule.setPoolAdminAllowedToEditMetadata(poolAdminAllowedToEditMetadata); + boolean poolAdminAllowedToEditStatus = selectedPoolManagerRights.contains(POOL_MANAGER_EDIT_STATUS); + qpoolModule.setPoolAdminAllowedToEditStatus(poolAdminAllowedToEditStatus); + boolean poolAdminAllowedToConfigReviewProcess = selectedPoolManagerRights.contains(POOL_MANAGER_REVIEW_PROCESS); + qpoolModule.setPoolAdminAllowedToConfigReviewProcess(poolAdminAllowedToConfigReviewProcess ); + boolean poolAdminAllowedToConfigTaxonomy = selectedPoolManagerRights.contains(POOL_MANAGER_TAXONOMY); + qpoolModule.setPoolAdminAllowedToConfigTaxonomy(poolAdminAllowedToConfigTaxonomy); + boolean poolAdminAllowedToConfigPools = selectedPoolManagerRights.contains(POOL_MANAGER_POOLS); + qpoolModule.setPoolAdminAllowedToConfigPools(poolAdminAllowedToConfigPools); + boolean poolAdminAllowedToConfigItemTypes = selectedPoolManagerRights.contains(POOL_MANAGER_ITEM_TYPES); + qpoolModule.setPoolAdminAllowedToConfigItemTypes(poolAdminAllowedToConfigItemTypes); + boolean poolAdminAllowedToConfigEducationalContext = selectedPoolManagerRights.contains(POOL_MANAGER_EDUCATIONAL_CONTEXT); + qpoolModule.setPoolAdminAllowedToConfigEducationalContext(poolAdminAllowedToConfigEducationalContext); + boolean poolAdminAllowedToConfigLicenses = selectedPoolManagerRights.contains(POOL_MANAGER_LICENSES); + qpoolModule.setPoolAdminAllowedToConfigLicenses(poolAdminAllowedToConfigLicenses); } @Override diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_content/admin_config.html b/src/main/java/org/olat/modules/qpool/ui/admin/_content/admin_config.html new file mode 100644 index 0000000000000000000000000000000000000000..52ad99a800482094facc61bda418bbc826ff059d --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_content/admin_config.html @@ -0,0 +1,3 @@ +$r.render("module") +$r.render("poolManagerRights") +$r.render("buttonsWrapper") \ No newline at end of file diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties index cd9572d6d1299f9c1bbe549dc500c9a08cf973fc..88dfd21e4d39026ad22209b12bb5ac9406552c1b 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties @@ -3,6 +3,7 @@ add.taxonomyLevel=Fachbereich erstellen admin.configuration.title=Fragenpool admin.levels.intro=Erstellen Sie die verf\u00FCgbaren Stufen die f\u00FCr Ihr Ausbildungslevel Sinn machen. Beispiele f\u00FCr Stufen im schulischen Kontext sind\: Unterstufe, Oberstufe, Gymnasium, Bachelor, Master. In einem Unternehmenskontext k\u00F6nnten Stufen so aussehen\: ohne Berufsausbildung, mit Berufsausbildung, F\u00FChrungsfunktion, Administration, Kader, Management admin.licenses.intro=Erstellen Sie zus\u00E4tzliche Lizenztypen wenn die Standard Lizenztypen von OpenOLAT nicht gen\u00FCgen. Die Standard Lizenztypen k\u00F6nnen nicht gel\u00F6scht werden. +admin.pool.manager.title=Rechte Poolverwalter admin.pools.intro=Erstellen Sie einen oder mehrere Fragenpools. Ein Fragenpool ist eine Fragendatenbank die allen Autoren des Systems f\u00FCr den Austausch von Fragen zur Verf\u00FCgung steht (\u00D6ffentlich). Optional l\u00E4sst sich ein Fragenpool auch auf einige wenige Autoren einschr\u00E4nken, z.B. die Mitarbeiter einer Abteilung (Nicht \u00F6ffentlich). admin.review.process.decision.type=Beurteilungsmethode admin.review.process.title=Beurteilungsprozess @@ -43,6 +44,15 @@ license.key=Lizenz lower.limit=Untergrenze f\u00FCr positive Beurteilung lower.limit.provider.name=Untergrenze number.of.ratings=Anzahl Beurteilungen pro Frage +pool.manager.allowed=Der Poolverwalter darf +pool.manager.edit.matadata=alle Fragen sehen und die Metadaten bearbeiten +pool.manager.edit.status=den Status einer Frage beliebig \u00E4ndern +pool.manager.educational.context=die Einstellungen "$:\segment.educational.context" bearbeiten +pool.manager.licenses=die Einstellungen "$:\segment.licenses" bearbeiten +pool.manager.item.types=die Einstellungen "$:\segment.item.types" bearbeiten +pool.manager.pools=die Einstellungen "$:\segment.pools" bearbeiten +pool.manager.review.process=die Einstellungen "$:\segment.review.process" bearbeiten +pool.manager.taxonomy=die Einstellungen "$:\segment.taxonomy" bearbeiten pools.enabled=Pools reset.status=Alle Fragen in den Status "draft" zur\u00FCcksetzen. review.process.confirm.enable.button=Einschalten diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties index b1813d49432ee392d6e91612bc1d9fd275619aa7..dc4a4e4e2bfaa67a254896e9910002da2dd29efc 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties @@ -3,6 +3,7 @@ add.taxonomyLevel=Create subject admin.configuration.title=Question bank admin.levels.intro=Create those levels that apply to your organisations educational level. Examples for levels in an academic context could be elementary school, middle school, high school, bachelor, master. Within a corporation context, levels could be the following\: without apprenticeship, with vocational training, administration, middle management, CO admin.licenses.intro=You can create more license types if the default license types are not sufficient. Please note that the default licenses cannot be deleted. +admin.pool.manager.title=Rights pool manager admin.pools.intro=Create one or more question pools. A pool is an question bank that allows all users with author rights the exchange of question items (public access). You can also opt for a pool with only a select few authors, e.g. a departments' staff (private access). admin.review.process.decision.type=Decision method admin.review.process.title=Review process @@ -42,6 +43,15 @@ license.id=ID license.key=License lower.limit=Lower limit for positive decision number.of.ratings=Number of ratings per question +pool.manager.allowed=The pool manager is allowed to +pool.manager.edit.matadata=see all questions and edit the metadata +pool.manager.edit.status=change the status of a question +pool.manager.educational.context=edit the settings "$:\segment.educational.context" +pool.manager.licenses=edit the settings "$:\segment.licenses" +pool.manager.item.types=edit the settings "$:\segment.item.types" +pool.manager.pools=edit the settings "$:\segment.pools" +pool.manager.review.process=edit the settings "$:\segment.review.process" +pool.manager.taxonomy=edit the settings "$:\segment.taxonomy" pools.enabled=Pools reset.status=Reset all questions to state "draft". review.process.confirm.enable.button=Enable diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java b/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java index 4a1c9da945596f8f40bdbec40e9d07940fa176da..7db4e1da0effe70d2a7826b4fd4e5dc82a7dc96c 100644 --- a/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java +++ b/src/main/java/org/olat/modules/qpool/ui/metadata/ExtendedSearchController.java @@ -68,6 +68,7 @@ public class ExtendedSearchController extends FormBasicController implements Ext private ExtendedSearchPrefs prefs; private boolean enabled = true; + @Autowired private QPoolService qpoolService; @Autowired diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/QuestionPoolMenuTreeModel.java b/src/main/java/org/olat/modules/qpool/ui/tree/QuestionPoolMenuTreeModel.java index beab2655ca09da7f910e9e56fa562d18d2275131..602a8ded9352716f489f933ff3b143e98aebfb47 100644 --- a/src/main/java/org/olat/modules/qpool/ui/tree/QuestionPoolMenuTreeModel.java +++ b/src/main/java/org/olat/modules/qpool/ui/tree/QuestionPoolMenuTreeModel.java @@ -231,11 +231,14 @@ public class QuestionPoolMenuTreeModel extends GenericTreeModel implements DnDTr } //administration - if(securityCallback.canAdmin()) { - TreeNode adminNode = new AdministrationTreeNode(translator.translate("menu.admin")); - rootNode.addChild(adminNode); - buildAdminSubTreeModel(adminNode); + TreeNode adminNode = new AdministrationTreeNode(translator.translate("menu.admin")); + rootNode.addChild(adminNode); + buildAdminSubTreeModel(adminNode); + if (adminNode.getChildCount() > 0) { setFirstChildAsDelegate(adminNode); + } else { + // Admin tree node should not be visible if user has no particular admin rights. + rootNode.remove(adminNode); } } @@ -343,23 +346,40 @@ public class QuestionPoolMenuTreeModel extends GenericTreeModel implements DnDTr private void buildAdminSubTreeModel(TreeNode adminNode) { adminNode.removeAllChildren(); - TreeNode node = new AllQuestionsTreeNode(stackPanel, securityCallback, translator.translate("menu.all.questions")); - adminNode.addChild(node); - - node = new TaxonomyAdminTreeNode(translator.translate("menu.admin.studyfields")); - adminNode.addChild(node); + if (securityCallback.canEditAllQuestions()) { + TreeNode node = new AllQuestionsTreeNode(stackPanel, securityCallback, translator.translate("menu.all.questions")); + adminNode.addChild(node); + } - node = new PoolsAdminTreeNode(translator.translate("menu.admin.pools")); - adminNode.addChild(node); + if (securityCallback.canConfigReviewProcess()) { + TreeNode node = new ReviewProcessAdminTreeNode(translator.translate("menu.admin.review.process")); + adminNode.addChild(node); + } - node = new QItemTypesAdminTreeNode(translator.translate("menu.admin.types")); - adminNode.addChild(node); + if (securityCallback.canConfigTaxonomies()) { + TreeNode node = new TaxonomyAdminTreeNode(translator.translate("menu.admin.studyfields")); + adminNode.addChild(node); + } - node = new QEducationalContextsAdminTreeNode(translator.translate("menu.admin.levels")); - adminNode.addChild(node); + if (securityCallback.canConfigPools()) { + TreeNode node = new PoolsAdminTreeNode(translator.translate("menu.admin.pools")); + adminNode.addChild(node); + } + + if (securityCallback.canConfigItemTypes()) { + TreeNode node = new QItemTypesAdminTreeNode(translator.translate("menu.admin.types")); + adminNode.addChild(node); + } + + if (securityCallback.canConfigEducationalContext()) { + TreeNode node = new QEducationalContextsAdminTreeNode(translator.translate("menu.admin.levels")); + adminNode.addChild(node); + } - node = new QLicensesAdminTreeNode(translator.translate("menu.admin.licenses")); - adminNode.addChild(node); + if (securityCallback.canConfigLicences()) { + TreeNode node = new QLicensesAdminTreeNode(translator.translate("menu.admin.licenses")); + adminNode.addChild(node); + } } private void setFirstChildAsDelegate(INode node) { diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/ReviewProcessAdminTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewProcessAdminTreeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..65cecc2f51b894f89c9b60a42f2e74743a2d4468 --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewProcessAdminTreeNode.java @@ -0,0 +1,59 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.qpool.ui.tree; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.tree.GenericTreeNode; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.util.resource.OresHelper; +import org.olat.modules.qpool.ui.admin.ReviewProcessAdminController; + +/** + * + * Initial date: 09.01.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class ReviewProcessAdminTreeNode extends GenericTreeNode implements ControllerTreeNode { + + private static final long serialVersionUID = -2738148565868342086L; + + public static final OLATResourceable ORES = OresHelper.createOLATResourceableType("ReviewProcess"); + + private ReviewProcessAdminController controller; + + public ReviewProcessAdminTreeNode(String title) { + super(); + this.setTitle(title); + } + + @Override + public Controller getController(UserRequest ureq, WindowControl wControl) { + if(controller == null) { + WindowControl swControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ORES, null, + wControl, true); + controller = new ReviewProcessAdminController(ureq, swControl); + } + return controller; + } +}