diff --git a/studydesign/build.gradle b/studydesign/build.gradle deleted file mode 100644 index 8188c8b0bdb..00000000000 --- a/studydesign/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -import org.labkey.gradle.util.BuildUtils - -plugins { - id 'org.labkey.build.module' -} - -dependencies { - BuildUtils.addLabKeyDependency(project: project, config: "implementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "apiJarFile") - BuildUtils.addLabKeyDependency(project: project, config: "jspImplementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "apiJarFile") - BuildUtils.addLabKeyDependency(project: project, config: "modules", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "published", depExtension: "module") -} diff --git a/studydesign/module.properties b/studydesign/module.properties deleted file mode 100644 index d600824fe51..00000000000 --- a/studydesign/module.properties +++ /dev/null @@ -1,5 +0,0 @@ -ModuleClass: org.labkey.studydesign.StudyDesignModule -License: Apache 2.0 -LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: pgsql -ManageVersion: true diff --git a/studydesign/src/org/labkey/studydesign/StudyDesignController.java b/studydesign/src/org/labkey/studydesign/StudyDesignController.java deleted file mode 100644 index 12b5224afff..00000000000 --- a/studydesign/src/org/labkey/studydesign/StudyDesignController.java +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright (c) 2014-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign; - -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.Nullable; -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.action.ApiJsonForm; -import org.labkey.api.action.ApiResponse; -import org.labkey.api.action.ApiSimpleResponse; -import org.labkey.api.action.MutatingApiAction; -import org.labkey.api.action.ReadOnlyApiAction; -import org.labkey.api.action.ReturnUrlForm; -import org.labkey.api.action.SimpleViewAction; -import org.labkey.api.action.SpringActionController; -import org.labkey.api.data.Container; -import org.labkey.api.data.DbScope; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.Table; -import org.labkey.api.query.FieldKey; -import org.labkey.api.query.ValidationException; -import org.labkey.api.security.ActionNames; -import org.labkey.api.security.RequiresPermission; -import org.labkey.api.security.User; -import org.labkey.api.security.permissions.ReadPermission; -import org.labkey.api.security.permissions.UpdatePermission; -import org.labkey.api.study.Cohort; -import org.labkey.api.study.Study; -import org.labkey.api.study.StudyService; -import org.labkey.api.study.StudyUrls; -import org.labkey.api.study.Visit; -import org.labkey.api.study.model.CohortService; -import org.labkey.api.study.security.permissions.ManageStudyPermission; -import org.labkey.api.studydesign.StudyDesignUrls; -import org.labkey.api.studydesign.query.StudyDesignSchema; -import org.labkey.api.util.JsonUtil; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.HttpView; -import org.labkey.api.view.JspView; -import org.labkey.api.view.NavTree; -import org.labkey.studydesign.model.AssaySpecimenConfigImpl; -import org.labkey.studydesign.model.AssaySpecimenVisitImpl; -import org.labkey.studydesign.model.DoseAndRoute; -import org.labkey.studydesign.model.ProductAntigenImpl; -import org.labkey.studydesign.model.ProductImpl; -import org.labkey.studydesign.model.StudyAssaySchedule; -import org.labkey.studydesign.model.StudyDesignCohort; -import org.labkey.studydesign.model.StudyTreatmentSchedule; -import org.labkey.studydesign.model.TreatmentImpl; -import org.labkey.studydesign.model.TreatmentManager; -import org.labkey.studydesign.model.TreatmentProductImpl; -import org.labkey.studydesign.model.TreatmentVisitMapImpl; -import org.springframework.validation.BindException; -import org.springframework.validation.Errors; -import org.springframework.web.servlet.ModelAndView; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -public class StudyDesignController extends SpringActionController -{ - private static final SpringActionController.ActionResolver ACTION_RESOLVER = new SpringActionController.DefaultActionResolver(StudyDesignController.class); - - public StudyDesignController() - { - setActionResolver(ACTION_RESOLVER); - } - - public static class StudyDesignUrlsImpl implements StudyDesignUrls - { - @Override - public ActionURL getManageAssayScheduleURL(Container container, boolean useAlternateLookupFields) - { - ActionURL url = new ActionURL(ManageAssayScheduleAction.class, container); - url.addParameter("useAlternateLookupFields", useAlternateLookupFields); - return url; - } - - @Override - public ActionURL getManageStudyProductsURL(Container container) - { - return new ActionURL(ManageStudyProductsAction.class, container); - } - - @Override - public ActionURL getManageTreatmentsURL(Container container, boolean useSingleTableEditor) - { - ActionURL url = new ActionURL(ManageTreatmentsAction.class, container); - url.addParameter("singleTable", useSingleTableEditor); - return url; - } - } - - @Nullable - private Study getStudy(Container container) - { - return StudyService.get().getStudy(container); - } - - @ActionNames("manageAssaySchedule, manageAssaySpecimen") - @RequiresPermission(UpdatePermission.class) - public static class ManageAssayScheduleAction extends SimpleViewAction - { - @Override - public ModelAndView getView(AssayScheduleForm form, BindException errors) - { - return new JspView<>("/org/labkey/studydesign/view/manageAssaySchedule.jsp", form); - } - - @Override - public void addNavTrail(NavTree root) - { - setHelpTopic("manageAssaySchedule"); - if (getContainer().hasPermission(getUser(), ManageStudyPermission.class)) - root.addChild("Manage Study", PageFlowUtil.urlProvider(StudyUrls.class).getManageStudyURL(getContainer())); - root.addChild("Manage Assay Schedule"); - } - } - - public static class AssayScheduleForm extends ReturnUrlForm - { - private boolean useAlternateLookupFields; - - public boolean isUseAlternateLookupFields() - { - return useAlternateLookupFields; - } - - public void setUseAlternateLookupFields(boolean useAlternateLookupFields) - { - this.useAlternateLookupFields = useAlternateLookupFields; - } - } - - @RequiresPermission(UpdatePermission.class) - public static class ManageStudyProductsAction extends SimpleViewAction - { - @Override - public ModelAndView getView(ReturnUrlForm form, BindException errors) - { - return new JspView<>("/org/labkey/studydesign/view/manageStudyProducts.jsp", form); - } - - @Override - public void addNavTrail(NavTree root) - { - setHelpTopic("studyProducts"); - if (getContainer().hasPermission(getUser(), ManageStudyPermission.class)) - root.addChild("Manage Study", PageFlowUtil.urlProvider(StudyUrls.class).getManageStudyURL(getContainer())); - root.addChild("Manage Study Products"); - } - } - - public static class ManageTreatmentsBean extends ReturnUrlForm - { - private boolean _singleTable; - - public boolean isSingleTable() - { - return _singleTable; - } - - public void setSingleTable(boolean singleTable) - { - _singleTable = singleTable; - } - } - - @RequiresPermission(UpdatePermission.class) - public static class ManageTreatmentsAction extends SimpleViewAction - { - @Override - public ModelAndView getView(ManageTreatmentsBean form, BindException errors) - { - // if the singleTable param is not explicitly set, do a container check - if (getViewContext().getRequest().getParameter("singleTable") == null) - form.setSingleTable(getContainer().hasActiveModuleByName("viscstudies")); - - return new JspView<>("/org/labkey/studydesign/view/manageTreatments.jsp", form); - } - - @Override - public void addNavTrail(NavTree root) - { - setHelpTopic("manageTreatments"); - if (getContainer().hasPermission(getUser(), ManageStudyPermission.class)) - root.addChild("Manage Study", PageFlowUtil.urlProvider(StudyUrls.class).getManageStudyURL(getContainer())); - root.addChild("Manage Treatments"); - } - } - - @RequiresPermission(ReadPermission.class) - public class GetStudyProducts extends ReadOnlyApiAction - { - private Study _study; - - @Override - public void validateForm(GetStudyProductsForm form, Errors errors) - { - _study = getStudy(getContainer()); - if (_study == null) - errors.reject(SpringActionController.ERROR_MSG, "A study does not exist in this folder"); - } - - @Override - public ApiResponse execute(GetStudyProductsForm form, BindException errors) - { - ApiSimpleResponse resp = new ApiSimpleResponse(); - - List> productList = new ArrayList<>(); - List studyProducts = TreatmentManager.getInstance().getStudyProducts(getContainer(), getUser(), form.getRole(), form.getRowId()); - for (ProductImpl product : studyProducts) - { - // note: we are currently only including the base fields for this extensible table - Map productProperties = product.serialize(); - - List> productAntigenList = new ArrayList<>(); - List studyProductAntigens = TreatmentManager.getInstance().getStudyProductAntigens(getContainer(), getUser(), product.getRowId()); - for (ProductAntigenImpl antigen : studyProductAntigens) - { - // note: we are currently only including the base fields for this extensible table - productAntigenList.add(antigen.serialize()); - } - productProperties.put("Antigens", productAntigenList); - - // get dose and route information associated with this product - List> doseAndRoutes = TreatmentManager.getInstance().getStudyProductsDoseAndRoute(getContainer(), getUser(), product.getRowId()) - .stream() - .map(DoseAndRoute::serialize) - .collect(Collectors.toList()); - productProperties.put("DoseAndRoute", doseAndRoutes); - productList.add(productProperties); - } - - resp.put("success", true); - resp.put("products", productList); - - return resp; - } - } - - public static class GetStudyProductsForm - { - private Integer _rowId; - private String _role; - - public Integer getRowId() - { - return _rowId; - } - - public void setRowId(Integer rowId) - { - _rowId = rowId; - } - - public String getRole() - { - return _role; - } - - public void setRole(String role) - { - _role = role; - } - } - - @RequiresPermission(ReadPermission.class) - public class GetStudyTreatments extends ReadOnlyApiAction - { - private Study _study; - - @Override - public void validateForm(GetStudyTreatmentsForm form, Errors errors) - { - _study = getStudy(getContainer()); - if (_study == null) - errors.reject(SpringActionController.ERROR_MSG, "A study does not exist in this folder"); - } - - @Override - public ApiResponse execute(GetStudyTreatmentsForm form, BindException errors) - { - ApiSimpleResponse resp = new ApiSimpleResponse(); - - List> treatmentList = new ArrayList<>(); - List studyTreatments = TreatmentManager.getInstance().getStudyTreatments(getContainer(), getUser()); - for (TreatmentImpl treatment : studyTreatments) - { - if (form.getTreatmentId() > 0 && form.getTreatmentId() != treatment.getRowId()) - continue; - - Map treatmentProperties = treatment.serialize(); - - List> treatmentProductList = new ArrayList<>(); - List studyTreatmentProducts = TreatmentManager.getInstance().getStudyTreatmentProducts(getContainer(), getUser(), treatment.getRowId(), treatment.getProductSort()); - for (TreatmentProductImpl treatmentProduct : studyTreatmentProducts) - { - // note: we are currently only including the base fields for this extensible table - Map treatmentProductProperties = treatmentProduct.serialize(); - - // add the product label and role for convenience, to prevent the need for another round trip to the server - List products = TreatmentManager.getInstance().getStudyProducts(getContainer(), getUser(), null, treatmentProduct.getProductId()); - if (products.size() == 1) - { - treatmentProductProperties.put("ProductId/Label", products.get(0).getLabel()); - treatmentProductProperties.put("ProductId/Role", products.get(0).getRole()); - } - - treatmentProductList.add(treatmentProductProperties); - } - - if (!form.isSplitByRole()) - { - treatmentProperties.put("Products", treatmentProductList); - } - else - { - Map>> treatmentProductsListByRole = new HashMap<>(); - for (Map productProperties : treatmentProductList) - { - String role = productProperties.get("ProductId/Role").toString(); - if (!treatmentProductsListByRole.containsKey(role)) - treatmentProductsListByRole.put(role, new ArrayList<>()); - - treatmentProductsListByRole.get(role).add(productProperties); - } - - for (Map.Entry>> entry : treatmentProductsListByRole.entrySet()) - treatmentProperties.put(entry.getKey(), entry.getValue()); - } - - treatmentList.add(treatmentProperties); - } - - resp.put("success", true); - resp.put("treatments", treatmentList); - - return resp; - } - } - - private static class GetStudyTreatmentsForm - { - private boolean _splitByRole; - - private int treatmentId; - - public boolean isSplitByRole() - { - return _splitByRole; - } - - public void setSplitByRole(boolean splitByRole) - { - _splitByRole = splitByRole; - } - - public int getTreatmentId() - { - return treatmentId; - } - - public void setTreatmentId(int treatmentId) - { - this.treatmentId = treatmentId; - } - } - - @RequiresPermission(ReadPermission.class) - public class GetStudyTreatmentSchedule extends ReadOnlyApiAction - { - private Study _study; - - @Override - public void validateForm(Object form, Errors errors) - { - _study = getStudy(getContainer()); - if (_study == null) - errors.reject(SpringActionController.ERROR_MSG, "A study does not exist in this folder"); - } - - @Override - public ApiResponse execute(Object form, BindException errors) - { - ApiSimpleResponse resp = new ApiSimpleResponse(); - StudyTreatmentSchedule treatmentSchedule = new StudyTreatmentSchedule(getContainer()); - - // include all cohorts for the study, regardless of it they have associated visits or not - resp.put("cohorts", treatmentSchedule.serializeCohortMapping(_study.getCohorts(getUser()))); - - // include all visits from the study, ordered by visit display order - treatmentSchedule.setVisits(_study.getVisits(Visit.Order.DISPLAY)); - resp.put("visits", treatmentSchedule.serializeVisits()); - - resp.put("success", true); - return resp; - } - } - - @RequiresPermission(UpdatePermission.class) - public class UpdateStudyProductsAction extends MutatingApiAction - { - @Override - public void validateForm(StudyProductsForm form, Errors errors) - { - if (form.getProducts() == null) - errors.reject(SpringActionController.ERROR_MSG, "No study products provided."); - - // label field is required - for (ProductImpl product : form.getProducts()) - { - if (product.getLabel() == null || StringUtils.isEmpty(product.getLabel().trim())) - { - errors.reject(SpringActionController.ERROR_MSG, "Label is a required field for all study products."); - break; - } - } - } - - @Override - public ApiResponse execute(StudyProductsForm form, BindException errors) throws Exception - { - ApiSimpleResponse response = new ApiSimpleResponse(); - Study study = getStudy(getContainer()); - - if (study != null) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - updateProducts(form.getProducts()); - transaction.commit(); - } - - response.put("success", true); - return response; - } - else - throw new IllegalStateException("A study does not exist in this folder"); - } - - private void updateProducts(List products) throws Exception - { - // insert new study products and update any existing ones - List productRowIds = new ArrayList<>(); - for (ProductImpl product : products) - { - Integer updatedRowId = TreatmentManager.getInstance().saveStudyProduct(getContainer(), getUser(), product); - if (updatedRowId != null) - { - productRowIds.add(updatedRowId); - - updateProductAntigens(updatedRowId, product.getAntigens()); - updateProductDoseAndRoutes(updatedRowId, product.getDoseAndRoutes()); - } - } - - // delete any other study products, not included in the insert/update list, by RowId for this container - for (ProductImpl product : TreatmentManager.getInstance().getFilteredStudyProducts(getContainer(), getUser(), productRowIds)) - TreatmentManager.getInstance().deleteStudyProduct(getContainer(), getUser(), product.getRowId()); - } - - private void updateProductAntigens(int productId, List antigens) throws Exception - { - // insert new study products antigens and update any existing ones - List antigenRowIds = new ArrayList<>(); - for (ProductAntigenImpl antigen : antigens) - { - // make sure the productId is set based on the product rowId - antigen.setProductId(productId); - - Integer updatedRowId = TreatmentManager.getInstance().saveStudyProductAntigen(getContainer(), getUser(), antigen); - if (updatedRowId != null) - antigenRowIds.add(updatedRowId); - } - - // delete any other study products antigens, not included in the insert/update list, for the given productId - for (ProductAntigenImpl antigen : TreatmentManager.getInstance().getFilteredStudyProductAntigens(getContainer(), getUser(), productId, antigenRowIds)) - TreatmentManager.getInstance().deleteStudyProductAntigen(getContainer(), getUser(), antigen.getRowId()); - } - - private void updateProductDoseAndRoutes(int productId, List doseAndRoutes) - { - // get existing dose and routes - Set existingDoseAndRoutes = TreatmentManager.getInstance().getStudyProductsDoseAndRoute(getContainer(), getUser(), productId) - .stream() - .map(DoseAndRoute::getRowId) - .collect(Collectors.toSet()); - - try (DbScope.Transaction transaction = StudyDesignSchema.getInstance().getScope().ensureTransaction()) - { - for (DoseAndRoute doseAndRoute : doseAndRoutes) - { - // dose and route both can't be blank - if (doseAndRoute.getDose() != null || doseAndRoute.getRoute() != null) - { - doseAndRoute.setProductId(productId); - existingDoseAndRoutes.remove(doseAndRoute.getRowId()); - TreatmentManager.getInstance().saveStudyProductDoseAndRoute(getContainer(), getUser(), doseAndRoute); - } - } - - // remove deleted dose and routes - if (!existingDoseAndRoutes.isEmpty()) - { - SimpleFilter filter = new SimpleFilter(); - filter.addInClause(FieldKey.fromParts("RowId"), existingDoseAndRoutes); - Table.delete(StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), filter); - } - transaction.commit(); - } - } - } - - public static class StudyProductsForm implements ApiJsonForm - { - private List _products; - - public List getProducts() - { - return _products; - } - - public void setProducts(List products) - { - _products = products; - } - - @Override - public void bindJson(JSONObject json) - { - Container container = HttpView.currentContext().getContainer(); - - JSONArray productsJSON = json.optJSONArray("products"); - if (productsJSON != null) - { - _products = new ArrayList<>(); - for (JSONObject product : JsonUtil.toJSONObjectList(productsJSON)) - _products.add(ProductImpl.fromJSON(product, container)); - } - } - } - - @RequiresPermission(UpdatePermission.class) - public class UpdateTreatmentsAction extends MutatingApiAction - { - @Override - public ApiResponse execute(StudyTreatmentSchedule form, BindException errors) throws Exception - { - ApiSimpleResponse response = new ApiSimpleResponse(); - Study study = getStudy(getContainer()); - - if (study != null) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - List treatmentIds; - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - treatmentIds = updateTreatments(form.getTreatments()); - transaction.commit(); - } - - response.put("success", true); - response.put("treatmentIds", treatmentIds); - return response; - } - else - throw new IllegalStateException("A study does not exist in this folder"); - } - - private Integer getExistingTreatmentId(TreatmentImpl treatment) - { - if (treatment == null) - return -1; - List studyTreatments = TreatmentManager.getInstance().getStudyTreatments(getContainer(), getUser()); - for (TreatmentImpl existingTreatment : studyTreatments) - { - List studyTreatmentProducts = TreatmentManager.getInstance().getStudyTreatmentProducts(getContainer(), getUser(), existingTreatment.getRowId(), existingTreatment.getProductSort()); - for (TreatmentProductImpl product : studyTreatmentProducts) - { - product.serialize(); - } - existingTreatment.setTreatmentProducts(studyTreatmentProducts); - if (treatment.isSameTreatmentProductsWith(existingTreatment)) - return existingTreatment.getRowId(); - } - return -1; - } - - private List updateTreatments(List treatments) throws Exception - { - List updatedRowIds = new ArrayList<>(); - for (TreatmentImpl treatment : treatments) - { - Integer updatedRowId = getExistingTreatmentId(treatment); - if (updatedRowId == null || updatedRowId <= 0) - { - updatedRowId = TreatmentManager.getInstance().saveTreatment(getContainer(), getUser(), treatment); - if (updatedRowId != null) - { - TreatmentManager.getInstance().updateTreatmentProducts(updatedRowId, treatment.getTreatmentProducts(), getContainer(), getUser()); - } - } - updatedRowIds.add(updatedRowId); - } - return updatedRowIds; - } - } - - @RequiresPermission(UpdatePermission.class) - public class UpdateTreatmentScheduleAction extends MutatingApiAction - { - private final Map _tempTreatmentIdMap = new HashMap<>(); - private final Set usedTreatmentIds = new HashSet<>(); // treatmentIds referenced in single table Treatment Schedule UI - private final List treatmentRowIds = new ArrayList<>(); // treatmentIds defined in 2 table UI's Treatment section - private final List cohortRowIds = new ArrayList<>(); - - @Override - public void validateForm(StudyTreatmentSchedule form, Errors errors) - { - // validate that each treatment has a label - for (TreatmentImpl treatment : form.getTreatments()) - { - if (treatment.getLabel() == null || StringUtils.isEmpty(treatment.getLabel().trim())) - errors.reject(SpringActionController.ERROR_MSG, "Label is a required field for all treatments."); - - // validate that each treatment product mapping has a selected product - for (TreatmentProductImpl treatmentProduct : treatment.getTreatmentProducts()) - { - if (treatmentProduct.getProductId() <= 0) - errors.reject(SpringActionController.ERROR_MSG, "Each treatment product must have a selected study product."); - } - } - - // validate that each cohort has a label, is unique, and has a valid subject count value - for (StudyDesignCohort cohort : form.getCohorts()) - { - if (cohort.getLabel() == null || StringUtils.isEmpty(cohort.getLabel().trim())) - errors.reject(SpringActionController.ERROR_MSG, "Label is a required field for all cohorts."); - - Cohort cohortByLabel = CohortService.get().getCohortByLabel(getContainer(), getUser(), cohort.getLabel()); - if (cohort.getRowId() > 0) - { - Cohort cohortByRowId = CohortService.get().getCohortForRowId(getContainer(), getUser(), cohort.getRowId()); - if (cohortByRowId != null && cohortByLabel != null && cohortByRowId.getRowId() != cohortByLabel.getRowId()) - errors.reject(SpringActionController.ERROR_MSG, "A cohort with the label '" + cohort.getLabel() + "' already exists in this study."); - } - else if (cohortByLabel != null) - { - errors.reject(SpringActionController.ERROR_MSG, "A cohort with the label '" + cohort.getLabel() + "' already exists in this study."); - } - - if (cohort.getSubjectCount() != null) - { - if (cohort.getSubjectCount() < 0) - errors.reject(SpringActionController.ERROR_MSG, "Cohort subject count values must be a positive integer."); - if (cohort.getSubjectCount() == Integer.MAX_VALUE) - errors.reject(SpringActionController.ERROR_MSG, "Cohort subject count value larger than the max value allowed."); - } - } - } - - @Override - public ApiResponse execute(StudyTreatmentSchedule form, BindException errors) throws Exception - { - ApiSimpleResponse response = new ApiSimpleResponse(); - Study study = getStudy(getContainer()); - - if (study != null) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - updateTreatments(form.getTreatments()); - updateCohorts(form.getCohorts(), study); - cleanTreatments(); - cleanCohorts(); - transaction.commit(); - } - - response.put("success", true); - return response; - } - else - throw new IllegalStateException("A study does not exist in this folder"); - } - - private void cleanCohorts() throws ValidationException - { - // delete any other study cohorts, not included in the insert/update list, by RowId for this container - for (Cohort existingCohort : CohortService.get().getCohorts(getContainer(), getUser())) - { - if (!cohortRowIds.contains(existingCohort.getRowId())) - { - if (!existingCohort.isInUse()) - CohortService.get().deleteCohort(existingCohort); - else - throw new ValidationException("Unable to delete in-use cohort: " + existingCohort.getLabel()); - } - } - - } - - private void cleanTreatments() - { - // delete any other study treatments, not included in the insert/update list, by RowId for this container - for (TreatmentImpl treatment : TreatmentManager.getInstance().getFilteredTreatments(getContainer(), getUser(), treatmentRowIds, usedTreatmentIds)) - TreatmentManager.getInstance().deleteTreatment(getContainer(), getUser(), treatment.getRowId()); - - } - - private void updateTreatments(List treatments) throws Exception - { - // insert new study treatments and update any existing ones - - for (TreatmentImpl treatment : treatments) - { - Integer updatedRowId = TreatmentManager.getInstance().saveTreatment(getContainer(), getUser(), treatment); - if (updatedRowId != null) - { - treatmentRowIds.add(updatedRowId); - - if (treatment.getTempRowId() != null) - _tempTreatmentIdMap.put(treatment.getTempRowId(), updatedRowId); - - TreatmentManager.getInstance().updateTreatmentProducts(updatedRowId, treatment.getTreatmentProducts(), getContainer(), getUser()); - } - } - } - - private void updateCohorts(Collection cohorts, Study study) throws ValidationException - { - // insert new cohorts and update any existing ones - for (StudyDesignCohort cohort : cohorts) - { - int rowId = cohort.getRowId(); - if (rowId > 0) - { - CohortService.get().updateCohort(getContainer(), getUser(), rowId, cohort.getLabel(), cohort.getSubjectCount()); - cohortRowIds.add(rowId); - } - else - { - Cohort newCohort = CohortService.get().createCohort(study, getUser(), cohort.getLabel(), true, cohort.getSubjectCount(), null); - cohortRowIds.add(newCohort.getRowId()); - rowId = newCohort.getRowId(); - } - - updateTreatmentVisitMap(rowId, cohort.getTreatmentVisitMap()); - } - } - - private void updateTreatmentVisitMap(int cohortId, List treatmentVisitMaps) - { - for (TreatmentVisitMapImpl visitMap : treatmentVisitMaps) - { - usedTreatmentIds.add(visitMap.getTreatmentId()); - } - - // the mapping that is passed in will have all of the current treatment/visit maps, so we will compare - // this set with the set from the DB and if they are different, replace all - List existingVisitMaps = TreatmentManager.getInstance().getStudyTreatmentVisitMap(getContainer(), cohortId); - boolean visitMapsDiffer = existingVisitMaps.size() != treatmentVisitMaps.size(); - if (!visitMapsDiffer) - { - for (TreatmentVisitMapImpl newVisitMap : treatmentVisitMaps) - { - newVisitMap.setContainer(getContainer()); - newVisitMap.setCohortId(cohortId); - - if (!existingVisitMaps.contains(newVisitMap)) - { - visitMapsDiffer = true; - break; - } - } - } - - // if we have differences, replace all at this point - if (visitMapsDiffer) - { - TreatmentManager.getInstance().deleteTreatmentVisitMapForCohort(getContainer(), cohortId); - for (TreatmentVisitMapImpl newVisitMap : treatmentVisitMaps) - { - // if the treatmentId used here was from a treatment that was created as part of this transaction, - // lookup the new treatment record RowId from the tempRowId - if (newVisitMap.getTempTreatmentId() != null && _tempTreatmentIdMap.containsKey(newVisitMap.getTempTreatmentId())) - newVisitMap.setTreatmentId(_tempTreatmentIdMap.get(newVisitMap.getTempTreatmentId())); - - if (cohortId > 0 && newVisitMap.getVisitId() > 0 && newVisitMap.getTreatmentId() > 0) - TreatmentManager.getInstance().insertTreatmentVisitMap(getUser(), getContainer(), cohortId, newVisitMap.getVisitId(), newVisitMap.getTreatmentId()); - } - } - } - } - - @RequiresPermission(UpdatePermission.class) - public class UpdateAssayPlanAction extends MutatingApiAction - { - @Override - public ApiResponse execute(AssayPlanForm form, BindException errors) - { - ApiSimpleResponse response = new ApiSimpleResponse(); - Study study = StudyService.get().getStudy(getContainer()); - if (study != null) - { - updateAssayPlan(getUser(), study, form.getAssayPlan()); - response.put("success", true); - } - else - { - response.put("success", false); - } - - return response; - } - } - - private static class AssayPlanForm - { - private String _assayPlan; - - public AssayPlanForm() - {} - - public String getAssayPlan() - { - return _assayPlan; - } - - public void setAssayPlan(String assayPlan) - { - _assayPlan = assayPlan; - } - } - - @RequiresPermission(UpdatePermission.class) - public class UpdateAssayScheduleAction extends MutatingApiAction - { - @Override - public void validateForm(StudyAssaySchedule form, Errors errors) - { - // validate that each assay configuration has an AssayName - for (AssaySpecimenConfigImpl assay : form.getAssays()) - { - if (assay.getAssayName() == null || StringUtils.isEmpty(assay.getAssayName().trim())) - errors.reject(SpringActionController.ERROR_MSG, "Assay Name is a required field for all assay configurations."); - - if (assay.getSampleQuantity() != null && assay.getSampleQuantity() < 0) - errors.reject(SpringActionController.ERROR_MSG, "Assay sample quantity value must be a positive number."); - } - } - - @Override - public ApiResponse execute(StudyAssaySchedule form, BindException errors) throws Exception - { - ApiSimpleResponse response = new ApiSimpleResponse(); - Study study = getStudy(getContainer()); - - if (study != null) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - updateAssays(form.getAssays()); - updateAssayPlan(getUser(), study, form.getAssayPlan()); - transaction.commit(); - } - - response.put("success", true); - return response; - } - else - throw new IllegalStateException("A study does not exist in this folder"); - } - - private void updateAssays(List assays) throws Exception - { - // insert new assaySpecimens and update any existing ones - List assaySpecimenRowIds = new ArrayList<>(); - for (AssaySpecimenConfigImpl assay : assays) - { - Integer updatedRowId = TreatmentManager.getInstance().saveAssaySpecimen(getContainer(), getUser(), assay); - if (updatedRowId != null) - { - assaySpecimenRowIds.add(updatedRowId); - - updateAssayVisitMap(updatedRowId, assay.getAssayVisitMap()); - } - } - - // delete any other assaySpecimens, not included in the insert/update list, by RowId for this container - for (AssaySpecimenConfigImpl assaySpecimen : TreatmentManager.getInstance().getFilteredAssaySpecimens(getContainer(), assaySpecimenRowIds)) - TreatmentManager.getInstance().deleteAssaySpecimen(getContainer(), getUser(), assaySpecimen.getRowId()); - } - - private void updateAssayVisitMap(int assaySpecimenId, List assayVisitMaps) throws Exception - { - List assaySpecimenVisitIds = new ArrayList<>(); - if (assayVisitMaps != null && !assayVisitMaps.isEmpty()) - { - for (AssaySpecimenVisitImpl assaySpecimenVisit : assayVisitMaps) - { - assaySpecimenVisit.setAssaySpecimenId(assaySpecimenId); - - Integer updatedRowId = TreatmentManager.getInstance().saveAssaySpecimenVisit(getContainer(), getUser(), assaySpecimenVisit); - assaySpecimenVisitIds.add(updatedRowId); - } - } - - // delete any other assaySpecimenVisits, not included in the insert/update list, by RowId for this container and assaySpecimenId - for (AssaySpecimenVisitImpl assaySpecimenVisit : TreatmentManager.getInstance().getFilteredAssaySpecimenVisits(getContainer(), assaySpecimenId, assaySpecimenVisitIds)) - TreatmentManager.getInstance().deleteAssaySpecimenVisit(getContainer(), getUser(), assaySpecimenVisit.getRowId()); - } - } - - private void updateAssayPlan(User user, Study study, String assayPlan) - { - if (study != null) - { - StudyService.get().updateAssayPlan(user, study, assayPlan); - } - } -} \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/StudyDesignModule.java b/studydesign/src/org/labkey/studydesign/StudyDesignModule.java deleted file mode 100644 index 44aa8c8ba76..00000000000 --- a/studydesign/src/org/labkey/studydesign/StudyDesignModule.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.labkey.studydesign; - -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.labkey.api.module.ModuleContext; -import org.labkey.api.module.SpringModule; -import org.labkey.api.services.ServiceRegistry; -import org.labkey.api.studydesign.StudyDesignService; -import org.labkey.api.util.logging.LogHelper; -import org.labkey.api.view.WebPartFactory; -import org.labkey.studydesign.model.TreatmentManager; -import org.labkey.studydesign.view.AssayScheduleWebpartFactory; -import org.labkey.studydesign.view.ImmunizationScheduleWebpartFactory; -import org.labkey.studydesign.view.VaccineDesignWebpartFactory; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -public class StudyDesignModule extends SpringModule -{ - private static final Logger LOG = LogHelper.getLogger(StudyDesignModule.class, "Study Design"); - public static final String NAME = "StudyDesign"; - - @Override - public String getName() - { - return NAME; - } - - @Override - @NotNull - protected Collection createWebPartFactories() - { - return List.of( - new AssayScheduleWebpartFactory(), - new ImmunizationScheduleWebpartFactory(), - new VaccineDesignWebpartFactory() - ); - } - - @Override - public @Nullable Double getSchemaVersion() - { - return null; - } - - @Override - public boolean hasScripts() - { - return false; - } - - @Override - protected void init() - { - addController("study-design", StudyDesignController.class); - - ServiceRegistry.get().registerService(StudyDesignService.class, new StudyDesignServiceImpl()); - } - - @Override - protected void startupAfterSpringConfig(ModuleContext moduleContext) - { - } - - @Override - public @NotNull Collection getSchemaNames() - { - return Set.of(); - } - - @Override - public @NotNull Set> getIntegrationTests() - { - return Set.of( - TreatmentManager.TreatmentDataTestCase.class, - TreatmentManager.AssayScheduleTestCase.class - ); - } -} \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/StudyDesignServiceImpl.java b/studydesign/src/org/labkey/studydesign/StudyDesignServiceImpl.java deleted file mode 100644 index 151a0d71ea4..00000000000 --- a/studydesign/src/org/labkey/studydesign/StudyDesignServiceImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.labkey.studydesign; - -import org.labkey.api.data.Container; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.Table; -import org.labkey.api.data.TableSelector; -import org.labkey.api.query.FieldKey; -import org.labkey.api.security.User; -import org.labkey.api.study.AssaySpecimenConfig; -import org.labkey.api.study.Product; -import org.labkey.api.study.Treatment; -import org.labkey.api.study.Visit; -import org.labkey.api.studydesign.StudyDesignService; -import org.labkey.api.studydesign.query.StudyDesignSchema; -import org.labkey.studydesign.model.AssaySpecimenConfigImpl; -import org.labkey.studydesign.model.TreatmentManager; - -import java.util.Collection; -import java.util.List; - -public class StudyDesignServiceImpl implements StudyDesignService -{ - @Override - public List getStudyProducts(Container c, User user, String role) - { - return TreatmentManager.getInstance().getStudyProducts(c, user, role, null); - } - - @Override - public List getStudyTreatments(Container c, User user) - { - return TreatmentManager.getInstance().getStudyTreatments(c, user); - } - - @Override - public List getVisitsForTreatmentSchedule(Container c) - { - return TreatmentManager.getInstance().getVisitsForTreatmentSchedule(c); - } - - @Override - public Collection getAssaySpecimenConfigs(Container c) - { - return new TableSelector( - StudyDesignSchema.getInstance().getTableInfoAssaySpecimen(), - SimpleFilter.createContainerFilter(c), null).getCollection(AssaySpecimenConfigImpl.class); - } - - @Override - public void deleteTreatmentVisitMapForCohort(Container container, Integer cohortId) - { - TreatmentManager.getInstance().deleteTreatmentVisitMapForCohort(container, cohortId); - } - - @Override - public void deleteTreatmentVisitMapForVisit(Container container, Integer visitId) - { - TreatmentManager.getInstance().deleteTreatmentVisitMapForVisit(container, visitId); - } - - @Override - public void deleteAssaySpecimenVisits(Container container, int visitId) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("VisitId"), visitId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), filter); - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenConfigImpl.java b/studydesign/src/org/labkey/studydesign/model/AssaySpecimenConfigImpl.java deleted file mode 100644 index 44dcd314850..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenConfigImpl.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2013-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.study.AssaySpecimenConfig; -import org.labkey.api.util.JsonUtil; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.labkey.api.util.IntegerUtils.asIntegerElseNull; - -/** - * Represents an assay/specimen configuration for a study - */ -public class AssaySpecimenConfigImpl implements AssaySpecimenConfig -{ - private Container _container; - private int _rowId; - private String _assayName; - private Integer _dataset; - private String _description; - private String _source; - private Integer _locationId; - private Integer _primaryTypeId; - private Integer _derivativeTypeId; - private String _tubeType; - private String _lab; - private String _sampleType; - private Double _sampleQuantity; - private String _sampleUnits; - private List _assayVisitMap; - - public AssaySpecimenConfigImpl() - { - } - - public AssaySpecimenConfigImpl(Container container, String assayName, String description) - { - _container = container; - _assayName = assayName; - _description = description; - } - - public boolean isNew() - { - return _rowId == 0; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - @Override - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - @Override - public String getAssayName() - { - return _assayName; - } - - public void setAssayName(String assayName) - { - _assayName = assayName; - } - - @Override - public Integer getDataset() - { - return _dataset; - } - - public void setDataset(Integer dataset) - { - _dataset = dataset; - } - - @Override - public String getDescription() - { - return _description; - } - - public void setDescription(String description) - { - _description = description; - } - - @Override - public String getSource() - { - return _source; - } - - public void setSource(String source) - { - _source = source; - } - - @Override - public Integer getLocationId() - { - return _locationId; - } - - public void setLocationId(Integer locationId) - { - _locationId = locationId; - } - - @Override - public Integer getPrimaryTypeId() - { - return _primaryTypeId; - } - - public void setPrimaryTypeId(Integer primaryTypeId) - { - _primaryTypeId = primaryTypeId; - } - - @Override - public Integer getDerivativeTypeId() - { - return _derivativeTypeId; - } - - public void setDerivativeTypeId(Integer derivativeTypeId) - { - _derivativeTypeId = derivativeTypeId; - } - - @Override - public String getTubeType() - { - return _tubeType; - } - - public void setTubeType(String tubeType) - { - _tubeType = tubeType; - } - - public String getLab() - { - return _lab; - } - - public void setLab(String lab) - { - _lab = lab; - } - - public String getSampleType() - { - return _sampleType; - } - - public void setSampleType(String sampleType) - { - _sampleType = sampleType; - } - - public Double getSampleQuantity() - { - return _sampleQuantity; - } - - public void setSampleQuantity(Double sampleQuantity) - { - _sampleQuantity = sampleQuantity; - } - - public String getSampleUnits() - { - return _sampleUnits; - } - - public void setSampleUnits(String sampleUnits) - { - _sampleUnits = sampleUnits; - } - - public void setAssayVisitMap(List assayVisitMap) - { - _assayVisitMap = assayVisitMap; - } - - public List getAssayVisitMap() - { - return _assayVisitMap; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("AssayName", getAssayName()); - props.put("DataSet", getDataset()); - props.put("Description", getDescription()); - props.put("LocationId", getLocationId()); - props.put("Source", getSource()); - props.put("TubeType", getTubeType()); - props.put("PrimaryTypeId", getPrimaryTypeId()); - props.put("DerivativeTypeId", getDerivativeTypeId()); - props.put("Lab", getLab()); - props.put("SampleType", getSampleType()); - props.put("SampleQuantity", getSampleQuantity()); - props.put("SampleUnits", getSampleUnits()); - props.put("Container", getContainer().getId()); - return props; - } - - public static AssaySpecimenConfigImpl fromJSON(@NotNull JSONObject o, Container container) - { - AssaySpecimenConfigImpl assay = new AssaySpecimenConfigImpl(container, o.getString("AssayName"), o.getString("Description")); - - if (o.has("RowId")) - assay.setRowId(o.getInt("RowId")); - if (o.has("DataSet") && asIntegerElseNull(o.get("DataSet")) instanceof Integer dataset && dataset > 0) - assay.setDataset(dataset); - if (o.has("Source") && !StringUtils.isEmpty(o.getString("Source"))) - assay.setSource(o.getString("Source")); - if (o.has("LocationId") && asIntegerElseNull(o.get("LocationId")) instanceof Integer locationId && locationId > 0) - assay.setLocationId(o.getInt("LocationId")); - if (o.has("TubeType") && !StringUtils.isEmpty(o.getString("TubeType"))) - assay.setTubeType(o.getString("TubeType")); - if (o.has("Lab") && !StringUtils.isEmpty(o.getString("Lab"))) - assay.setLab(o.getString("Lab")); - if (o.has("SampleType") && !StringUtils.isEmpty(o.getString("SampleType"))) - assay.setSampleType(o.getString("SampleType")); - if (o.has("SampleQuantity") && o.get("SampleQuantity") instanceof Number sampleQuantity && sampleQuantity.doubleValue() > 0) - assay.setSampleQuantity(sampleQuantity.doubleValue()); - if (o.has("SampleUnits") && !StringUtils.isEmpty(o.getString("SampleUnits"))) - assay.setSampleUnits(o.getString("SampleUnits")); - if (o.has("PrimaryTypeId") && asIntegerElseNull(o.get("PrimaryTypeId")) instanceof Integer primaryTypeId) - assay.setPrimaryTypeId(primaryTypeId); - if (o.has("DerivativeTypeId") && asIntegerElseNull(o.get("DerivativeTypeId")) instanceof Integer derivativeTypeId) - assay.setDerivativeTypeId(derivativeTypeId); - - JSONArray visitMapJSON = o.optJSONArray("VisitMap"); - if (visitMapJSON != null) - { - List assayVisitMap = new ArrayList<>(); - for (JSONObject assaySpecimen : JsonUtil.toJSONObjectList(visitMapJSON)) - assayVisitMap.add(AssaySpecimenVisitImpl.fromJSON(assaySpecimen, container)); - - assay.setAssayVisitMap(assayVisitMap); - } - - return assay; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - AssaySpecimenConfigImpl that = (AssaySpecimenConfigImpl) o; - return _rowId == that._rowId && Objects.equals(_assayName, that._assayName) && Objects.equals(_dataset, that._dataset) && Objects.equals(_description, that._description) && Objects.equals(_source, that._source) && Objects.equals(_locationId, that._locationId) && Objects.equals(_primaryTypeId, that._primaryTypeId) && Objects.equals(_derivativeTypeId, that._derivativeTypeId) && Objects.equals(_tubeType, that._tubeType) && Objects.equals(_lab, that._lab) && Objects.equals(_sampleType, that._sampleType) && Objects.equals(_sampleQuantity, that._sampleQuantity) && Objects.equals(_sampleUnits, that._sampleUnits); - } - - @Override - public int hashCode() - { - return Objects.hash(_rowId, _assayName, _dataset, _description, _source, _locationId, _primaryTypeId, _derivativeTypeId, _tubeType, _lab, _sampleType, _sampleQuantity, _sampleUnits); - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java b/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java deleted file mode 100644 index 4c8eee28671..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2014-2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.study.AssaySpecimenVisit; - -import java.util.HashMap; -import java.util.Map; - -public class AssaySpecimenVisitImpl implements AssaySpecimenVisit -{ - private int _assaySpecimenId; - private int _visitId; - private int _rowId; - private Container _container; - - public AssaySpecimenVisitImpl() - { - } - - public AssaySpecimenVisitImpl(Container container, int assaySpecimenId, int visitId) - { - _container = container; - _assaySpecimenId = assaySpecimenId; - _visitId = visitId; - } - - public boolean isNew() - { - return _rowId == 0; - } - - @Override - public int getAssaySpecimenId() - { - return _assaySpecimenId; - } - - public void setAssaySpecimenId(int assaySpecimenId) - { - _assaySpecimenId = assaySpecimenId; - } - - @Override - public int getVisitId() - { - return _visitId; - } - - public void setVisitId(int visitId) - { - _visitId = visitId; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("VisitId", getVisitId()); - props.put("AssaySpecimenId", getAssaySpecimenId()); - props.put("Container", getContainer().getId()); - return props; - } - - public static AssaySpecimenVisitImpl fromJSON(@NotNull JSONObject o, Container container) - { - // AssaySpecimenId may not be specified in JSON - int assaySpecimenId = o.has("AssaySpecimenId") ? o.getInt("AssaySpecimenId") : 0; - AssaySpecimenVisitImpl assaySpecimenVisit = new AssaySpecimenVisitImpl(container, assaySpecimenId, o.getInt("VisitId")); - - if (o.has("RowId")) - assaySpecimenVisit.setRowId(o.getInt("RowId")); - - return assaySpecimenVisit; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/DoseAndRoute.java b/studydesign/src/org/labkey/studydesign/model/DoseAndRoute.java deleted file mode 100644 index 838d6007cb2..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/DoseAndRoute.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.util.Pair; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by klum on 9/23/2016. - */ -public class DoseAndRoute -{ - private Integer _rowId; - private String _dose; - private String _route; - private int _productId; - private Container _container; - - public enum keys - { - RowId, - Dose, - Route, - ProductId - } - - public boolean isNew() - { - return _rowId == null; - } - - public Integer getRowId() - { - return _rowId; - } - - public void setRowId(Integer rowId) - { - _rowId = rowId; - } - - public DoseAndRoute(){} - - public DoseAndRoute(String dose, String route, int productId, Container container) - { - _dose = dose; - _route = route; - _productId = productId; - _container = container; - } - - public @Nullable String getLabel() - { - if (_dose != null || _route != null) - return String.format("%s : %s", StringUtils.trimToEmpty(_dose), StringUtils.trimToEmpty(_route)); - else - return null; - } - - public String getDose() - { - return StringUtils.trimToNull(_dose); - } - - public void setDose(String dose) - { - _dose = dose; - } - - public String getRoute() - { - return StringUtils.trimToNull(_route); - } - - public void setRoute(String route) - { - _route = route; - } - - public int getProductId() - { - return _productId; - } - - public void setProductId(int productId) - { - _productId = productId; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public static DoseAndRoute fromJSON(@NotNull JSONObject o, Container container, int productId) - { - String dose = null; - String route = null; - if (o.has(keys.Dose.name())) - dose = String.valueOf(o.get(keys.Dose.name())); - if (o.has(keys.Route.name())) - route = String.valueOf(o.get(keys.Route.name())); - - DoseAndRoute doseAndRoute = new DoseAndRoute(dose, route, productId, container); - if (o.has(keys.RowId.name())) - doseAndRoute.setRowId(o.getInt(keys.RowId.name())); - return doseAndRoute; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put(keys.RowId.name(), getRowId()); - props.put(keys.ProductId.name(), getProductId()); - props.put(keys.Dose.name(), getDose()); - props.put(keys.Route.name(), getRoute()); - - return props; - } - - /** - * Helper to convert the concatenated label into a dose and/or route portion - * @return Pair object where the key is the dose and the value is the route - */ - public static @Nullable - Pair parseFromLabel(String label) - { - // need to keep the label generation in sync with code in DoseAndRouteTable label expr column - if (label != null) - { - if (label.contains(":")) - { - String[] parts = label.split(":"); - if (parts.length == 2) - { - return new Pair<>( - StringUtils.trimToNull(parts[0]), - StringUtils.trimToNull(parts[1])); - } - } - } - return null; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java b/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java deleted file mode 100644 index 9c10e2a7695..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2013-2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.study.ProductAntigen; - -import java.util.HashMap; -import java.util.Map; - -/** - * User: cnathe - * Date: 12/26/13 - */ -public class ProductAntigenImpl implements ProductAntigen -{ - private Container _container; - private int _rowId; - private int _productId; - private String _gene; - private String _subType; - private String _genBankId; - private String _sequence; - - public ProductAntigenImpl() - {} - - public ProductAntigenImpl(Container container, int productId, String gene, String subType) - { - _container = container; - _productId = productId; - _gene = gene; - _subType = subType; - } - - public ProductAntigenImpl(Container container, String gene, String subType, String genBankId, String sequence) - { - this(container, 0, gene, subType); - _genBankId = genBankId; - _sequence = sequence; - } - - public boolean isNew() - { - return _rowId == 0; - } - - public Object getPrimaryKey() - { - return getRowId(); - } - - @Override - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - @Override - public int getProductId() - { - return _productId; - } - - public void setProductId(int productId) - { - _productId = productId; - } - - @Override - public String getGene() - { - return _gene; - } - - public void setGene(String gene) - { - _gene = gene; - } - - @Override - public String getSubType() - { - return _subType; - } - - public void setSubType(String subType) - { - _subType = subType; - } - - @Override - public String getGenBankId() - { - return _genBankId; - } - - public void setGenBankId(String genBankId) - { - _genBankId = genBankId; - } - - @Override - public String getSequence() - { - return _sequence; - } - - public void setSequence(String sequence) - { - _sequence = sequence; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("ProductId", getProductId()); - props.put("Gene", getGene()); - props.put("SubType", getSubType()); - props.put("GenBankId", getGenBankId()); - props.put("Sequence", getSequence()); - return props; - } - - public static ProductAntigenImpl fromJSON(@NotNull JSONObject o, Container container) - { - ProductAntigenImpl antigen = new ProductAntigenImpl( - container, o.getString("Gene"), o.getString("SubType"), - o.getString("GenBankId"), o.getString("Sequence") - ); - - if (o.has("RowId")) - antigen.setRowId(o.getInt("RowId")); - - if (o.has("ProductId")) - antigen.setProductId(o.getInt("ProductId")); - - return antigen; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/ProductImpl.java b/studydesign/src/org/labkey/studydesign/model/ProductImpl.java deleted file mode 100644 index e81aec33fa0..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/ProductImpl.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2013-2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.study.Product; -import org.labkey.api.util.JsonUtil; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * User: cnathe - * Date: 12/26/13 - */ -public class ProductImpl implements Product -{ - private Container _container; - private int _rowId; - private String _label; - private String _role; - private String _type; - private List _antigens; - private List _doseAndRoutes; - - // from TreatmentProductMap (not serialized with product) - private String _dose; - private String _route; - - public ProductImpl() - {} - - public ProductImpl(Container container, String label, String role) - { - _container = container; - _label = label; - _role = role; - } - - public ProductImpl(Container container, String label, String role, String type) - { - this(container, label, role); - _type = type; - } - - public boolean isNew() - { - return _rowId == 0; - } - - public Object getPrimaryKey() - { - return getRowId(); - } - - @Override - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - @Override - public String getLabel() - { - return _label; - } - - public void setLabel(String label) - { - _label = label; - } - - @Override - public String getRole() - { - return _role; - } - - public void setRole(String role) - { - _role = role; - } - - @Override - public String getType() - { - return _type; - } - - public void setType(String type) - { - _type = type; - } - - public List getAntigens() - { - return _antigens; - } - - public void setAntigens(List antigens) - { - _antigens = antigens; - } - - public String getDose() - { - return _dose; - } - - public void setDose(String dose) - { - _dose = dose; - } - - public String getRoute() - { - return _route; - } - - public void setRoute(String route) - { - _route = route; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public List getDoseAndRoutes() - { - return _doseAndRoutes; - } - - public void setDoseAndRoutes(List doseAndRoutes) - { - _doseAndRoutes = doseAndRoutes; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("Label", getLabel()); - props.put("Role", getRole()); - props.put("Type", getType()); - return props; - } - - public static ProductImpl fromJSON(@NotNull JSONObject o, Container container) - { - ProductImpl product = new ProductImpl(container, o.getString("Label"), o.getString("Role"), o.getString("Type")); - - if (o.has("RowId")) - product.setRowId(o.getInt("RowId")); - - if (o.has("Antigens") && o.get("Antigens") instanceof JSONArray antigensJSON) - { - List antigens = new ArrayList<>(); - for (JSONObject productAntigen : JsonUtil.toJSONObjectList(antigensJSON)) - antigens.add(ProductAntigenImpl.fromJSON(productAntigen, container)); - - product.setAntigens(antigens); - } - - if (o.has("DoseAndRoute") && o.get("DoseAndRoute") instanceof JSONArray doseJSON) - { - List doseAndRoutes = new ArrayList<>(); - for (JSONObject doseAndRoute : JsonUtil.toJSONObjectList(doseJSON)) - doseAndRoutes.add(DoseAndRoute.fromJSON(doseAndRoute, container, product.getRowId())); - - product.setDoseAndRoutes(doseAndRoutes); - } - - return product; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/StudyAssaySchedule.java b/studydesign/src/org/labkey/studydesign/model/StudyAssaySchedule.java deleted file mode 100644 index 9128f5d11e2..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/StudyAssaySchedule.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.action.ApiJsonForm; -import org.labkey.api.data.Container; -import org.labkey.api.util.JsonUtil; -import org.labkey.api.view.HttpView; - -import java.util.ArrayList; -import java.util.List; - -public class StudyAssaySchedule implements ApiJsonForm -{ - Container _container; - List _assays; - String _assayPlan; - - public StudyAssaySchedule() - {} - - public StudyAssaySchedule(Container container) - { - _container = container; - } - - public void setAssays(List assays) - { - _assays = assays; - } - - public List getAssays() - { - return _assays; - } - - public void setAssayPlan(String assayPlan) - { - _assayPlan = assayPlan; - } - - public String getAssayPlan() - { - return _assayPlan; - } - - @Override - public void bindJson(JSONObject json) - { - _container = HttpView.currentContext().getContainer(); - - JSONArray assaysJSON = json.optJSONArray("assays"); - if (assaysJSON != null) - { - _assays = new ArrayList<>(); - for (JSONObject assayJSON : JsonUtil.toJSONObjectList(assaysJSON)) - _assays.add(AssaySpecimenConfigImpl.fromJSON(assayJSON, _container)); - } - - _assayPlan = json.optString("assayPlan", null); - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/StudyDesignCohort.java b/studydesign/src/org/labkey/studydesign/model/StudyDesignCohort.java deleted file mode 100644 index d040fa74247..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/StudyDesignCohort.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.study.Cohort; -import org.labkey.api.util.JsonUtil; - -import java.util.ArrayList; -import java.util.List; - -/** - * Used as a bean in the treatment schedule to map to actual study cohorts - */ -public class StudyDesignCohort -{ - private int _rowId; - private String _label; - private Integer _subjectCount; - List _treatmentVisitMap = new ArrayList<>(); - - public StudyDesignCohort() - { - } - - public StudyDesignCohort(Cohort cohort) - { - _rowId = cohort.getRowId(); - _label = cohort.getLabel(); - _subjectCount = cohort.getSubjectCount(); - } - - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - public String getLabel() - { - return _label; - } - - public void setLabel(String label) - { - _label = label; - } - - public Integer getSubjectCount() - { - return _subjectCount; - } - - public void setSubjectCount(Integer subjectCount) - { - _subjectCount = subjectCount; - } - - public List getTreatmentVisitMap() - { - return _treatmentVisitMap; - } - - public void setTreatmentVisitMap(List treatmentVisitMap) - { - _treatmentVisitMap = treatmentVisitMap; - } - - public static StudyDesignCohort fromJSON(@NotNull JSONObject o) - { - StudyDesignCohort cohort = new StudyDesignCohort(); - cohort.setLabel(o.getString("Label")); - if (o.has("SubjectCount") && !"".equals(o.getString("SubjectCount"))) - cohort.setSubjectCount(o.getInt("SubjectCount")); - if (o.has("RowId")) - cohort.setRowId(o.getInt("RowId")); - - JSONArray visitMapJSON = o.optJSONArray("VisitMap"); - if (visitMapJSON != null) - { - List treatmentVisitMap = new ArrayList<>(); - for (JSONObject json : JsonUtil.toJSONObjectList(visitMapJSON)) - treatmentVisitMap.add(TreatmentVisitMapImpl.fromJSON(json)); - - cohort.setTreatmentVisitMap(treatmentVisitMap); - } - - return cohort; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/StudyTreatmentSchedule.java b/studydesign/src/org/labkey/studydesign/model/StudyTreatmentSchedule.java deleted file mode 100644 index f9afc6e79fc..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/StudyTreatmentSchedule.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2014-2018 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.action.ApiJsonForm; -import org.labkey.api.data.Container; -import org.labkey.api.study.Cohort; -import org.labkey.api.study.Visit; -import org.labkey.api.util.JsonUtil; -import org.labkey.api.view.HttpView; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Represents a study's cohort/treatment/visit mapping information. Used to serialize JSON to the treatment schedule. - */ -public class StudyTreatmentSchedule implements ApiJsonForm -{ - Container _container; - - // treatment schedule properties - List _treatments; - Collection _visits; - Collection _cohorts; - - public StudyTreatmentSchedule() - {} - - public StudyTreatmentSchedule(Container container) - { - _container = container; - } - - public void setTreatments(List treatments) - { - _treatments = treatments; - } - - public List getTreatments() - { - return _treatments; - } - - public List> serializeTreatments() - { - List> treatmentList = new ArrayList<>(); - for (TreatmentImpl treatment : _treatments) - { - treatmentList.add(treatment.serialize()); - } - return treatmentList; - } - - public void setVisits(Collection visits) - { - _visits = visits; - } - - public Collection getVisits() - { - return _visits; - } - - public List> serializeVisits() - { - List> visitList = new ArrayList<>(); - List includedIds = getIncludedVisitIds(); - for (Visit v : _visits) - { - Map visitProperties = new HashMap<>(); - visitProperties.put("RowId", v.getId()); - visitProperties.put("Label", v.getDisplayString()); - visitProperties.put("DisplayOrder", v.getDisplayOrder()); - visitProperties.put("SequenceNumMin", v.getSequenceNumMin()); - - // tag those visits that are used in the treatment schedule - visitProperties.put("Included", includedIds.contains(v.getId())); - - visitList.add(visitProperties); - } - return visitList; - } - - private List getIncludedVisitIds() - { - List ids = new ArrayList<>(); - for (StudyDesignCohort cohort : _cohorts) - { - for (TreatmentVisitMapImpl tvm : TreatmentManager.getInstance().getStudyTreatmentVisitMap(_container, cohort.getRowId())) - { - if (!ids.contains(tvm.getVisitId())) - ids.add(tvm.getVisitId()); - } - } - - return ids; - } - - public Collection getCohorts() - { - return _cohorts; - } - - public List> serializeCohortMapping(Collection cohorts) - { - List> cohortMappingList = new ArrayList<>(); - _cohorts = new ArrayList<>(); - for (Cohort cohort : cohorts) - { - _cohorts.add(new StudyDesignCohort(cohort)); - - Map mapProperties = new HashMap<>(); - mapProperties.put("RowId", cohort.getRowId()); - mapProperties.put("Label", cohort.getLabel()); - mapProperties.put("SubjectCount", cohort.getSubjectCount()); - mapProperties.put("CanDelete", !cohort.isInUse()); - - List> treatmentVisitMap = new ArrayList<>(); - for (TreatmentVisitMapImpl mapping : TreatmentManager.getInstance().getStudyTreatmentVisitMap(_container, cohort.getRowId())) - { - Map visitMapping = new HashMap<>(); - visitMapping.put("CohortId", mapping.getCohortId()); - visitMapping.put("TreatmentId", mapping.getTreatmentId()); - visitMapping.put("VisitId", mapping.getVisitId()); - treatmentVisitMap.add(visitMapping); - } - mapProperties.put("VisitMap", treatmentVisitMap); - - cohortMappingList.add(mapProperties); - } - return cohortMappingList; - } - - @Override - public void bindJson(JSONObject json) - { - _container = HttpView.currentContext().getContainer(); - - JSONArray treatmentsJSON = json.optJSONArray("treatments"); - if (treatmentsJSON != null) - { - _treatments = new ArrayList<>(); - for (JSONObject treatment : JsonUtil.toJSONObjectList(treatmentsJSON)) - _treatments.add(TreatmentImpl.fromJSON(treatment, _container)); - } - - JSONArray cohortsJSON = json.optJSONArray("cohorts"); - if (cohortsJSON != null) - { - _cohorts = new ArrayList<>(); - for (JSONObject cohortJSON : JsonUtil.toJSONObjectList(cohortsJSON)) - _cohorts.add(StudyDesignCohort.fromJSON(cohortJSON)); - } - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentImpl.java b/studydesign/src/org/labkey/studydesign/model/TreatmentImpl.java deleted file mode 100644 index b060adc0065..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentImpl.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2013-2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONArray; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.data.Sort; -import org.labkey.api.query.FieldKey; -import org.labkey.api.study.Treatment; -import org.labkey.api.util.JsonUtil; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.labkey.api.util.IntegerUtils.asIntegerElseNull; - -/** - * User: cnathe - * Date: 12/27/13 - */ -public class TreatmentImpl implements Treatment -{ - private Container _container; - private int _rowId; - private String _tempRowId; // used to map new treatment records being inserted to their usage in TreatmentVisitMapImpl - private String _label; - private String _description; - private List _treatmentProducts; - private List _products; - - public TreatmentImpl() - {} - - public TreatmentImpl(Container container, String label, String description) - { - _container = container; - _label = label; - _description = description; - } - - public boolean isNew() - { - return _rowId == 0; - } - - public Object getPrimaryKey() - { - return getRowId(); - } - - @Override - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - private void setTempRowId(String tempRowId) - { - _tempRowId = tempRowId; - } - - public String getTempRowId() - { - return _tempRowId; - } - - @Override - public String getLabel() - { - return _label; - } - - public void setLabel(String label) - { - _label = label; - } - - @Override - public String getDescription() - { - return _description; - } - - public void setDescription(String description) - { - _description = description; - } - - public List getTreatmentProducts() - { - return _treatmentProducts; - } - - public void setTreatmentProducts(List treatmentProducts) - { - _treatmentProducts = treatmentProducts; - } - - public List getProducts() - { - return _products; - } - - public void setProducts(List products) - { - _products = products; - } - - public void addProduct(ProductImpl product) - { - if (_products == null) - _products = new ArrayList<>(); - - _products.add(product); - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public Map serialize() - { - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("Label", getLabel()); - props.put("Description", getDescription()); - return props; - } - - public Sort getProductSort() - { - // sort the product list to match the manage study products page (i.e. Immunogens before Adjuvants) - Sort sort = new Sort(); - sort.appendSortColumn(FieldKey.fromParts("ProductId", "Role"), Sort.SortDirection.DESC, false); - sort.appendSortColumn(FieldKey.fromParts("ProductId", "RowId"), Sort.SortDirection.ASC, false); - return sort; - } - - public static TreatmentImpl fromJSON(@NotNull JSONObject o, Container container) - { - TreatmentImpl treatment = new TreatmentImpl(container, o.getString("Label"), o.optString("Description", null)); - - if (o.has("RowId")) - { - if (asIntegerElseNull(o.get("RowId")) instanceof Integer rowId) - treatment.setRowId(rowId); - else - treatment.setTempRowId(o.getString("RowId")); - } - - if (o.has("Products") && o.get("Products") instanceof JSONArray productsJSON) - { - List treatmentProducts = new ArrayList<>(); - for (JSONObject productJson : JsonUtil.toJSONObjectList(productsJSON)) - treatmentProducts.add(TreatmentProductImpl.fromJSON(productJson, container)); - - treatment.setTreatmentProducts(treatmentProducts); - } - - return treatment; - } - - public boolean isSameTreatmentProductsWith(TreatmentImpl other) - { - if (other == null) - return false; - if (this.getTreatmentProducts() == null) - { - return other.getTreatmentProducts() == null; - } - else - { - if (other.getTreatmentProducts() == null) - return false; - - if (this.getTreatmentProducts().size() != other.getTreatmentProducts().size()) - return false; - - boolean hasMismatch = false; - for (TreatmentProductImpl product : this.getTreatmentProducts()) - { - boolean foundMatch =false; - for (TreatmentProductImpl otherProduct : other.getTreatmentProducts()) - { - if (product.isSameTreatmentProductWith(otherProduct)) - { - foundMatch = true; - break; - } - } - if (!foundMatch) - { - hasMismatch = true; - break; - } - } - return !hasMismatch; - } - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentManager.java b/studydesign/src/org/labkey/studydesign/model/TreatmentManager.java deleted file mode 100644 index 34637a8c886..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentManager.java +++ /dev/null @@ -1,1153 +0,0 @@ -/* - * Copyright (c) 2014-2018 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.junit.Assert; -import org.junit.Test; -import org.labkey.api.data.ColumnInfo; -import org.labkey.api.data.CompareType; -import org.labkey.api.data.Container; -import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.DbScope; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.Sort; -import org.labkey.api.data.Table; -import org.labkey.api.data.TableInfo; -import org.labkey.api.data.TableSelector; -import org.labkey.api.module.Module; -import org.labkey.api.module.ModuleLoader; -import org.labkey.api.query.BatchValidationException; -import org.labkey.api.query.FieldKey; -import org.labkey.api.query.FilteredTable; -import org.labkey.api.query.QueryService; -import org.labkey.api.query.QueryUpdateService; -import org.labkey.api.query.UserSchema; -import org.labkey.api.query.ValidationException; -import org.labkey.api.security.User; -import org.labkey.api.study.AssaySpecimenConfig; -import org.labkey.api.study.Cohort; -import org.labkey.api.study.Study; -import org.labkey.api.study.StudyService; -import org.labkey.api.study.TimepointType; -import org.labkey.api.study.Visit; -import org.labkey.api.study.model.CohortService; -import org.labkey.api.study.model.VisitService; -import org.labkey.api.studydesign.StudyDesignService; -import org.labkey.api.studydesign.query.StudyDesignQuerySchema; -import org.labkey.api.studydesign.query.StudyDesignSchema; -import org.labkey.api.test.TestWhen; -import org.labkey.api.util.GUID; -import org.labkey.api.util.JunitUtil; -import org.labkey.api.util.TestContext; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.labkey.api.util.IntegerUtils.asInteger; - -/** - * Created by cnathe on 1/24/14. - */ -public class TreatmentManager -{ - private static final TreatmentManager _instance = new TreatmentManager(); - - public static final String ASSAY_SPECIMEN_TABLE_NAME = "AssaySpecimen"; - public static final String ASSAY_SPECIMEN_VISIT_TABLE_NAME = "AssaySpecimenVisit"; - - private TreatmentManager() - { - } - - public static TreatmentManager getInstance() - { - return _instance; - } - - public List getStudyProducts(Container container, User user) - { - return getStudyProducts(container, user, null, null); - } - - public List getStudyProducts(Container container, User user, @Nullable String role, @Nullable Integer rowId) - { - //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter(); - if (role != null) - filter.addCondition(FieldKey.fromParts("Role"), role); - if (rowId != null) - filter.addCondition(FieldKey.fromParts("RowId"), rowId); - - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(ProductImpl.class); - } - - public List getFilteredStudyProducts(Container container, User user, List filterRowIds) - { - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - - //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter(); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(ProductImpl.class); - } - - public List getStudyProductAntigens(Container container, User user, int productId) - { - SimpleFilter filter = new SimpleFilter(); - filter.addCondition(FieldKey.fromParts("ProductId"), productId); - - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(ProductAntigenImpl.class); - } - - public List getFilteredStudyProductAntigens(Container container, User user, @NotNull Integer productId, List filterRowIds) - { - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - - //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter(); - filter.addCondition(FieldKey.fromParts("ProductId"), productId); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(ProductAntigenImpl.class); - } - - public Integer saveTreatment(Container container, User user, TreatmentImpl treatment) throws Exception - { - TableInfo treatmentTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - return saveStudyDesignRow(container, user, treatmentTable, treatment.serialize(), treatment.isNew() ? null : treatment.getRowId(), "RowId"); - } - - public List getStudyTreatments(Container container, User user) - { - SimpleFilter filter = new SimpleFilter(); - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(TreatmentImpl.class); - } - - public TreatmentImpl getStudyTreatmentByRowId(Container container, User user, int rowId) - { - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("RowId"), rowId); - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - TreatmentImpl treatment = new TableSelector(ti, filter, null).getObject(TreatmentImpl.class); - - // attach the associated study products to the treatment object - if (treatment != null) - { - List treatmentProducts = getStudyTreatmentProducts(container, user, treatment.getRowId(), treatment.getProductSort()); - for (TreatmentProductImpl treatmentProduct : treatmentProducts) - { - List products = getStudyProducts(container, user, null, treatmentProduct.getProductId()); - for (ProductImpl product : products) - { - product.setDose(treatmentProduct.getDose()); - product.setRoute(treatmentProduct.getRoute()); - treatment.addProduct(product); - } - } - } - - return treatment; - } - - public List getFilteredTreatments(Container container, User user, List definedTreatmentIds, Set usedTreatmentIds) - { - List filterRowIds = new ArrayList<>(); - filterRowIds.addAll(definedTreatmentIds); - filterRowIds.addAll(usedTreatmentIds); - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - - //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter().addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(TreatmentImpl.class); - } - - public Integer saveTreatmentProductMapping(Container container, User user, TreatmentProductImpl treatmentProduct) throws Exception - { - TableInfo treatmentProductTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - return saveStudyDesignRow(container, user, treatmentProductTable, treatmentProduct.serialize(), treatmentProduct.isNew() ? null : treatmentProduct.getRowId(), "RowId"); - } - - public List getStudyTreatmentProducts(Container container, User user, int treatmentId) - { - return getStudyTreatmentProducts(container, user, treatmentId, new Sort("RowId")); - } - - public List getStudyTreatmentProducts(Container container, User user, int treatmentId, Sort sort) - { - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("TreatmentId"), treatmentId); - - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - return new TableSelector(ti, filter, sort).getArrayList(TreatmentProductImpl.class); - } - - public List getFilteredTreatmentProductMappings(Container container, User user, @NotNull Integer treatmentId, List filterRowIds) - { - TableInfo ti = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - - //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter(); - filter.addCondition(FieldKey.fromParts("TreatmentId"), treatmentId); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(TreatmentProductImpl.class); - } - - public List getStudyTreatmentVisitMap(Container container, @Nullable Integer cohortId) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - if (cohortId != null) - filter.addCondition(FieldKey.fromParts("CohortId"), cohortId); - - TableInfo ti = StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(); - return new TableSelector(ti, filter, new Sort("CohortId")).getArrayList(TreatmentVisitMapImpl.class); - } - - public List getVisitsForTreatmentSchedule(Container container) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - List visitRowIds = new TableSelector(StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(), - Collections.singleton("VisitId"), filter, new Sort("VisitId")).getArrayList(Integer.class); - - Study study = StudyService.get().getStudy(container); - List visits = new ArrayList<>(); - if (study != null) - { - for (Visit visit : study.getVisits(Visit.Order.DISPLAY)) - { - if (visitRowIds.contains(visit.getId())) - visits.add(visit); - } - } - return visits; - } - - public TreatmentVisitMapImpl insertTreatmentVisitMap(User user, Container container, int cohortId, int visitId, int treatmentId) - { - TreatmentVisitMapImpl newMapping = new TreatmentVisitMapImpl(); - newMapping.setContainer(container); - newMapping.setCohortId(cohortId); - newMapping.setVisitId(visitId); - newMapping.setTreatmentId(treatmentId); - - return Table.insert(user, StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(), newMapping); - } - - public void deleteTreatmentVisitMapForCohort(Container container, int rowId) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("CohortId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(), filter); - } - - public void deleteTreatmentVisitMapForVisit(Container container, int rowId) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("VisitId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(), filter); - } - - public void deleteTreatment(Container container, User user, int rowId) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - // delete the usages of this treatment in the TreatmentVisitMap - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("TreatmentId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoTreatmentVisitMap(), filter); - - // delete the associated treatment study product mappings (provision table) - filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("TreatmentId"), rowId); - deleteTreatmentProductMap(container, user, filter); - - // finally delete the record from the Treatment (provision table) - TableInfo treatmentTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - if (treatmentTable != null) - { - QueryUpdateService qus = treatmentTable.getUpdateService(); - List> keys = new ArrayList<>(); - ColumnInfo treatmentPk = treatmentTable.getColumn(FieldKey.fromParts("RowId")); - keys.add(Collections.singletonMap(treatmentPk.getName(), rowId)); - qus.deleteRows(user, container, keys, null, null); - } - - transaction.commit(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - public void deleteStudyProduct(Container container, User user, int rowId) - { - StudyDesignSchema schema = StudyDesignSchema.getInstance(); - - try (DbScope.Transaction transaction = schema.getSchema().getScope().ensureTransaction()) - { - // delete the usages of this study product in the ProductAntigen table (provision table) - deleteProductAntigens(container, user, rowId); - - // delete the associated doses and routes for this product - Table.delete(StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), new SimpleFilter(FieldKey.fromParts("ProductId"), rowId)); - - // delete the associated treatment study product mappings (provision table) - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("ProductId"), rowId); - deleteTreatmentProductMap(container, user, filter); - - // finally delete the record from the Products (provision table) - TableInfo productTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - if (productTable != null) - { - QueryUpdateService qus = productTable.getUpdateService(); - List> keys = new ArrayList<>(); - ColumnInfo productPk = productTable.getColumn(FieldKey.fromParts("RowId")); - keys.add(Collections.singletonMap(productPk.getName(), rowId)); - qus.deleteRows(user, container, keys, null, null); - } - else - throw new IllegalStateException("Could not find table: " + StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - - transaction.commit(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - public Integer saveStudyProduct(Container container, User user, ProductImpl product) throws Exception - { - TableInfo productTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - return saveStudyDesignRow(container, user, productTable, product.serialize(), product.isNew() ? null : product.getRowId(), "RowId"); - } - - public Integer saveStudyProductAntigen(Container container, User user, ProductAntigenImpl antigen) throws Exception - { - TableInfo productAntigenTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - return saveStudyDesignRow(container, user, productAntigenTable, antigen.serialize(), antigen.isNew() ? null : antigen.getRowId(), "RowId"); - } - - public DoseAndRoute saveStudyProductDoseAndRoute(Container container, User user, DoseAndRoute doseAndRoute) - { - if (doseAndRoute.isNew()) - return Table.insert(user, StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), doseAndRoute); - else - return Table.update(user, StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), doseAndRoute, doseAndRoute.getRowId()); - } - - public Collection getStudyProductsDoseAndRoute(Container container, User user, int productId) - { - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("ProductId"), productId); - return new TableSelector(StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), filter, null).getCollection(DoseAndRoute.class); - } - - @Nullable - public DoseAndRoute getDoseAndRoute(Container container, String dose, String route, int productId) - { - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("ProductId"), productId); - if (dose != null) - filter.addCondition(FieldKey.fromParts("Dose"), dose); - else - filter.addCondition(FieldKey.fromParts("Dose"), null, CompareType.ISBLANK); - if (route != null) - filter.addCondition(FieldKey.fromParts("Route"), route); - else - filter.addCondition(FieldKey.fromParts("Route"), null, CompareType.ISBLANK); - Collection doseAndRoutes = new TableSelector(StudyDesignSchema.getInstance().getTableInfoDoseAndRoute(), filter, null).getCollection(DoseAndRoute.class); - - if (!doseAndRoutes.isEmpty()) - { - return doseAndRoutes.iterator().next(); - } - return null; - } - - public Integer saveAssaySpecimen(Container container, User user, AssaySpecimenConfigImpl assaySpecimen) throws Exception - { - TableInfo assaySpecimenTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(ASSAY_SPECIMEN_TABLE_NAME); - Integer ret = saveStudyDesignRow(container, user, assaySpecimenTable, assaySpecimen.serialize(), assaySpecimen.isNew() ? null : assaySpecimen.getRowId(), "RowId", true); - return ret; - } - - public Integer saveAssaySpecimenVisit(Container container, User user, AssaySpecimenVisitImpl assaySpecimenVisit) throws Exception - { - TableInfo assaySpecimenVIsitTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(ASSAY_SPECIMEN_VISIT_TABLE_NAME); - return saveStudyDesignRow(container, user, assaySpecimenVIsitTable, assaySpecimenVisit.serialize(), assaySpecimenVisit.isNew() ? null : assaySpecimenVisit.getRowId(), "RowId", true); - } - - public List getFilteredAssaySpecimens(Container container, List filterRowIds) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(StudyDesignSchema.getInstance().getTableInfoAssaySpecimen(), filter, new Sort("RowId")).getArrayList(AssaySpecimenConfigImpl.class); - } - - public List getFilteredAssaySpecimenVisits(Container container, int assaySpecimenId, List filterRowIds) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("AssaySpecimenId"), assaySpecimenId); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); - - return new TableSelector(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), filter, new Sort("RowId")).getArrayList(AssaySpecimenVisitImpl.class); - } - - public Integer saveStudyDesignRow(Container container, User user, TableInfo tableInfo, Map row, Integer key, String pkColName) throws Exception - { - return saveStudyDesignRow(container, user, tableInfo, row, key, pkColName, false); - } - - public Integer saveStudyDesignRow(Container container, User user, TableInfo tableInfo, Map row, Integer key, String pkColName, boolean includeContainerKey) throws Exception - { - QueryUpdateService qus = tableInfo != null ? tableInfo.getUpdateService() : null; - if (qus != null) - { - BatchValidationException errors = new BatchValidationException(); - List> updatedRows; - - if (key == null) - { - updatedRows = qus.insertRows(user, container, Collections.singletonList(row), errors, null, null); - } - else - { - Map oldKey = new HashMap<>(); - oldKey.put(pkColName, key); - if (includeContainerKey) - oldKey.put("Container", container.getId()); - - updatedRows = qus.updateRows(user, container, Collections.singletonList(row), Collections.singletonList(oldKey), errors, null, null); - } - - if (errors.hasErrors()) - throw errors.getLastRowError(); - - if (updatedRows.size() == 1) - return asInteger(updatedRows.get(0).get(pkColName)); - } - - return null; - } - - public void deleteStudyProductAntigen(Container container, User user, int rowId) throws Exception - { - TableInfo productAntigenTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - if (productAntigenTable != null) - { - QueryUpdateService qus = productAntigenTable.getUpdateService(); - if (qus != null) - { - List> keys = Collections.singletonList(Collections.singletonMap("RowId", rowId)); - qus.deleteRows(user, container, keys, null, null); - } - else - throw new IllegalStateException("Could not find query update service for table: " + StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - } - else - throw new IllegalStateException("Could not find table: " + StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - } - - public void deleteProductAntigens(Container container, User user, int productId) throws Exception - { - TableInfo productAntigenTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - if (productAntigenTable != null) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("ProductId"), productId); - TableSelector selector = new TableSelector(productAntigenTable, Collections.singleton("RowId"), filter, null); - Integer[] productAntigenIds = selector.getArray(Integer.class); - - QueryUpdateService qus = productAntigenTable.getUpdateService(); - if (qus != null) - { - List> keys = new ArrayList<>(); - ColumnInfo productAntigenPk = productAntigenTable.getColumn(FieldKey.fromParts("RowId")); - for (Integer productAntigenId : productAntigenIds) - { - keys.add(Collections.singletonMap(productAntigenPk.getName(), productAntigenId)); - } - - qus.deleteRows(user, container, keys, null, null); - } - else - throw new IllegalStateException("Could not find query update service for table: " + StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - } - else - throw new IllegalStateException("Could not find table: " + StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - } - - public void deleteTreatmentProductMap(Container container, User user, SimpleFilter filter) throws Exception - { - TableInfo productMapTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - if (productMapTable != null) - { - TableSelector selector = new TableSelector(productMapTable, Collections.singleton("RowId"), filter, null); - deleteTreatmentProductMap(container, user, selector.getArrayList(Integer.class)); - } - else - throw new IllegalStateException("Could not find table: " + StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - } - - public void deleteTreatmentProductMap(Container container, User user, List rowIds) throws Exception - { - TableInfo productMapTable = QueryService.get().getUserSchema(user, container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME).getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - if (productMapTable != null) - { - QueryUpdateService qus = productMapTable.getUpdateService(); - if (qus != null) - { - List> keys = new ArrayList<>(); - ColumnInfo productMapPk = productMapTable.getColumn(FieldKey.fromParts("RowId")); - for (Integer rowId : rowIds) - keys.add(Collections.singletonMap(productMapPk.getName(), rowId)); - - qus.deleteRows(user, container, keys, null, null); - } - else - throw new IllegalStateException("Could not find query update service for table: " + StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - } - else - throw new IllegalStateException("Could not find table: " + StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - } - - public void deleteAssaySpecimen(Container container, User user, int rowId) - { - // first delete any usages of the AssaySpecimenId in the AssaySpecimenVisit table - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("AssaySpecimenId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), filter); - - // delete the AssaySpecimen record by RowId - filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("RowId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoAssaySpecimen(), filter); - } - - public void deleteAssaySpecimenVisit(Container container, User user, int rowId) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("RowId"), rowId); - Table.delete(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), filter); - } - - public String getStudyDesignRouteLabelByName(Container container, String name) - { - return getStudyDesignLabelByName(container, StudyDesignSchema.getInstance().getTableInfoStudyDesignRoutes(), name); - } - - public String getStudyDesignImmunogenTypeLabelByName(Container container, String name) - { - return getStudyDesignLabelByName(container, StudyDesignSchema.getInstance().getTableInfoStudyDesignImmunogenTypes(), name); - } - - public String getStudyDesignGeneLabelByName(Container container, String name) - { - return getStudyDesignLabelByName(container, StudyDesignSchema.getInstance().getTableInfoStudyDesignGenes(), name); - } - - public String getStudyDesignSubTypeLabelByName(Container container, String name) - { - return getStudyDesignLabelByName(container, StudyDesignSchema.getInstance().getTableInfoStudyDesignSubTypes(), name); - } - - public String getStudyDesignLabLabelByName(Container container, String name) - { - return getStudyDesignLabelByName(container, StudyDesignSchema.getInstance().getTableInfoStudyDesignLabs(), name); - } - - public String getStudyDesignLabelByName(Container container, TableInfo tableInfo, String name) - { - // first look in the current container for the StudyDesign record, then look for it at the project level - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("Name"), name); - String label = new TableSelector(tableInfo, Collections.singleton("Label"), filter, null).getObject(String.class); - if (label == null && !container.isProject()) - { - filter = SimpleFilter.createContainerFilter(container.getProject()); - filter.addCondition(FieldKey.fromParts("Name"), name); - label = new TableSelector(tableInfo, Collections.singleton("Label"), filter, null).getObject(String.class); - } - - return label; - } - - public void updateTreatmentProducts(int treatmentId, List treatmentProducts, Container container, User user) throws Exception - { - // insert new study treatment product mappings and update any existing ones - List treatmentProductRowIds = new ArrayList<>(); - for (TreatmentProductImpl treatmentProduct : treatmentProducts) - { - // make sure the treatmentId is set based on the treatment rowId - treatmentProduct.setTreatmentId(treatmentId); - - Integer updatedRowId = TreatmentManager.getInstance().saveTreatmentProductMapping(container, user, treatmentProduct); - if (updatedRowId != null) - treatmentProductRowIds.add(updatedRowId); - } - - // delete any other treatment product mappings, not included in the insert/update list, for the given treatmentId - for (TreatmentProductImpl treatmentProduct : TreatmentManager.getInstance().getFilteredTreatmentProductMappings(container, user, treatmentId, treatmentProductRowIds)) - TreatmentManager.getInstance().deleteTreatmentProductMap(container, user, Collections.singletonList(treatmentProduct.getRowId())); - } - - public List getAssaySpecimenVisitIds(Container container, AssaySpecimenConfig assaySpecimenConfig) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - filter.addCondition(FieldKey.fromParts("AssaySpecimenId"), assaySpecimenConfig.getRowId()); - - return new TableSelector(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), - Collections.singleton("VisitId"), filter, new Sort("VisitId")).getArrayList(Integer.class); - } - - public List getVisitsForAssaySchedule(Container container) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(container); - List visitRowIds = new TableSelector(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), - Collections.singleton("VisitId"), filter, new Sort("VisitId")).getArrayList(Integer.class); - - return getSortedVisitsByRowIds(container, visitRowIds); - } - - public List getSortedVisitsByRowIds(Container container, List visitRowIds) - { - List visits = new ArrayList<>(); - Study study = StudyService.get().getStudy(container); - if (study != null) - { - for (Visit v : study.getVisits(Visit.Order.DISPLAY)) - { - if (visitRowIds.contains(v.getId())) - visits.add(v); - } - } - return visits; - } - - public AssaySpecimenConfigImpl addAssaySpecimenConfig(User user, AssaySpecimenConfigImpl config) - { - return Table.insert(user, StudyDesignSchema.getInstance().getTableInfoAssaySpecimen(), config); - } - - /**** - * - * - * - * TESTING - * - * - */ - - @TestWhen(TestWhen.When.BVT) - public static class TreatmentDataTestCase extends Assert - { - TestContext _context = null; - User _user = null; - Container _container = null; - Study _junitStudy = null; - TreatmentManager _manager = TreatmentManager.getInstance(); - UserSchema _schema = null; - - Map _lookups = new HashMap<>(); - List _products = new ArrayList<>(); - List _treatments = new ArrayList<>(); - List _cohorts = new ArrayList<>(); - List _visits = new ArrayList<>(); - - @Test - public void test() throws Throwable - { - try - { - createStudy(); - _user = _context.getUser(); - _container = _junitStudy.getContainer(); - _schema = QueryService.get().getUserSchema(_user, _container, StudyDesignQuerySchema.STUDY_SCHEMA_NAME); - - populateLookupTables(); - populateStudyProducts(); - populateTreatments(); - populateTreatmentSchedule(); - - verifyStudyProducts(); - verifyTreatments(); - verifyTreatmentSchedule(); - verifyCleanUpTreatmentData(); - } - finally - { - tearDown(); - } - } - - private void verifyCleanUpTreatmentData() throws Exception - { - // remove cohort and verify delete of TreatmentVisitMap - CohortService.get().deleteCohort(_cohorts.get(0)); - verifyTreatmentVisitMapRecords(4); - - // remove visit and verify delete of TreatmentVisitMap - VisitService.get().deleteVisit(_junitStudy, _user, _visits.get(0)); - verifyTreatmentVisitMapRecords(2); - - // we should still have all of our treatments and study products - verifyTreatments(); - verifyStudyProducts(); - - // remove treatment visit map records via visit - _manager.deleteTreatmentVisitMapForVisit(_container, _visits.get(1).getId()); - verifyTreatmentVisitMapRecords(0); - - // remove treatment and verify delete of TreatmentProductMap - _manager.deleteTreatment(_container, _user, _treatments.get(0).getRowId()); - verifyTreatmentProductMapRecords(_treatments.get(0).getRowId(), 0); - verifyTreatmentProductMapRecords(_treatments.get(1).getRowId(), 4); - - // remove product and verify delete of TreatmentProductMap and ProductAntigen - _manager.deleteStudyProduct(_container, _user, _products.get(0).getRowId()); - verifyTreatmentProductMapRecords(_treatments.get(1).getRowId(), 3); - verifyStudyProductAntigens(_products.get(0).getRowId(), 0); - verifyStudyProductAntigens(_products.get(1).getRowId(), 1); - - // directly delete product antigen - _manager.deleteProductAntigens(_container, _user, _products.get(1).getRowId()); - verifyStudyProductAntigens(_products.get(1).getRowId(), 0); - - // delete treatment product map by productId and then treatmentId - SimpleFilter filter = SimpleFilter.createContainerFilter(_container); - filter.addCondition(FieldKey.fromParts("ProductId"), _products.get(1).getRowId()); - _manager.deleteTreatmentProductMap(_container, _user, filter); - verifyTreatmentProductMapRecords(_treatments.get(1).getRowId(), 2); - filter = SimpleFilter.createContainerFilter(_container); - filter.addCondition(FieldKey.fromParts("TreatmentId"), _treatments.get(1).getRowId()); - _manager.deleteTreatmentProductMap(_container, _user, filter); - verifyTreatmentProductMapRecords(_treatments.get(1).getRowId(), 0); - } - - private void verifyTreatmentSchedule() - { - verifyTreatmentVisitMapRecords(8); - - _visits.add(VisitService.get().createVisit(_junitStudy, _user, BigDecimal.valueOf(3.0), "Visit 3", Visit.Type.FINAL_VISIT)); - assertEquals("Unexpected number of treatment schedule visits", 2, _manager.getVisitsForTreatmentSchedule(_container).size()); - } - - private void verifyTreatments() - { - List treatments = _manager.getStudyTreatments(_container, _user); - assertEquals("Unexpected study treatment count", 2, treatments.size()); - - for (TreatmentImpl treatment : treatments) - { - verifyTreatmentProductMapRecords(treatment.getRowId(), 4); - - treatment = _manager.getStudyTreatmentByRowId(_container, _user, treatment.getRowId()); - assertEquals("Unexpected number of treatment products", 4, treatment.getProducts().size()); - - for (ProductImpl product : treatment.getProducts()) - { - assertEquals("Unexpected product dose value", "Test Dose", product.getDose()); - assertEquals("Unexpected product route value", _lookups.get("Route"), product.getRoute()); - } - } - - } - - private void verifyStudyProducts() - { - List products = _manager.getStudyProducts(_container, _user); - assertEquals("Unexpected study product count", 4, products.size()); - - for (ProductImpl product : products) - verifyStudyProductAntigens(product.getRowId(), 1); - - assertEquals("Unexpected study product count by role", 2, _manager.getStudyProducts(_container, _user, "Immunogen", null).size()); - assertEquals("Unexpected study product count by role", 2, _manager.getStudyProducts(_container, _user, "Adjuvant", null).size()); - assertEquals("Unexpected study product count by role", 0, _manager.getStudyProducts(_container, _user, "UNK", null).size()); - - for (ProductImpl immunogen : _manager.getStudyProducts(_container, _user, "Immunogen", null)) - assertEquals("Unexpected product lookup value", _lookups.get("ImmunogenType"), immunogen.getType()); - } - - private void populateTreatmentSchedule() throws ValidationException - { - _cohorts.add(CohortService.get().createCohort(_junitStudy, _user, "Cohort1", true, 10, null)); - _cohorts.add(CohortService.get().createCohort(_junitStudy, _user, "Cohort2", true, 20, null)); - assertEquals(2, _cohorts.size()); - - _visits.add(VisitService.get().createVisit(_junitStudy, _user, BigDecimal.valueOf(1.0), "Visit 1", Visit.Type.BASELINE)); - _visits.add(VisitService.get().createVisit(_junitStudy, _user, BigDecimal.valueOf(2.0), "Visit 2", Visit.Type.SCHEDULED_FOLLOWUP)); - assertEquals(2, _visits.size()); - - for (Cohort cohort : _cohorts) - { - for (Visit visit : _visits) - { - for (TreatmentImpl treatment : _treatments) - { - _manager.insertTreatmentVisitMap(_user, _container, cohort.getRowId(), visit.getId(), treatment.getRowId()); - } - } - } - - verifyTreatmentVisitMapRecords(_cohorts.size() * _visits.size() * _treatments.size()); - } - - private void populateTreatments() - { - TableInfo treatmentTable = _schema.getTable(StudyDesignQuerySchema.TREATMENT_TABLE_NAME); - if (treatmentTable != null) - { - TableInfo ti = ((FilteredTable)treatmentTable).getRealTable(); - - TreatmentImpl treatment1 = new TreatmentImpl(_container, "Treatment1", "Treatment1 description"); - treatment1 = Table.insert(_user, ti, treatment1); - addProductsForTreatment(treatment1.getRowId()); - _treatments.add(treatment1); - - TreatmentImpl treatment2 = new TreatmentImpl(_container, "Treatment2", "Treatment2 description"); - treatment2 = Table.insert(_user, ti, treatment2); - addProductsForTreatment(treatment2.getRowId()); - _treatments.add(treatment2); - } - - assertEquals(2, _treatments.size()); - } - - private void addProductsForTreatment(int treatmentId) - { - TableInfo treatmentProductTable = _schema.getTable(StudyDesignQuerySchema.TREATMENT_PRODUCT_MAP_TABLE_NAME); - if (treatmentProductTable != null) - { - TableInfo ti = ((FilteredTable)treatmentProductTable).getRealTable(); - - for (ProductImpl product : _products) - { - TreatmentProductImpl tp = new TreatmentProductImpl(_container, treatmentId, product.getRowId()); - tp.setDose("Test Dose"); - tp.setRoute(_lookups.get("Route")); - Table.insert(_user, ti, tp); - } - } - - verifyTreatmentProductMapRecords(treatmentId, _products.size()); - } - - private void populateStudyProducts() - { - TableInfo productTable = _schema.getTable(StudyDesignQuerySchema.PRODUCT_TABLE_NAME); - if (productTable != null) - { - TableInfo ti = ((FilteredTable)productTable).getRealTable(); - - ProductImpl product1 = new ProductImpl(_container, "Immunogen1", "Immunogen"); - product1.setType(_lookups.get("ImmunogenType")); - _products.add(Table.insert(_user, ti, product1)); - - ProductImpl product2 = new ProductImpl(_container, "Immunogen2", "Immunogen"); - product2.setType(_lookups.get("ImmunogenType")); - _products.add(Table.insert(_user, ti, product2)); - - ProductImpl product3 = new ProductImpl(_container, "Adjuvant1", "Adjuvant"); - _products.add(Table.insert(_user, ti, product3)); - - ProductImpl product4 = new ProductImpl(_container, "Adjuvant2", "Adjuvant"); - _products.add(Table.insert(_user, ti, product4)); - } - - assertEquals(4, _products.size()); - - for (ProductImpl product : _products) - addAntigenToProduct(product.getRowId()); - } - - private void addAntigenToProduct(int productId) - { - TableInfo productAntigenTable = _schema.getTable(StudyDesignQuerySchema.PRODUCT_ANTIGEN_TABLE_NAME); - if (productAntigenTable != null) - { - TableInfo ti = ((FilteredTable)productAntigenTable).getRealTable(); - - ProductAntigenImpl productAntigen = new ProductAntigenImpl(_container, productId, _lookups.get("Gene"), _lookups.get("SubType")); - Table.insert(_user, ti, productAntigen); - } - - verifyStudyProductAntigens(productId, 1); - } - - private void populateLookupTables() - { - String name, label; - - Map data = new HashMap<>(); - data.put("Container", _container.getId()); - - data.put("Name", name = "Test Immunogen Type"); - data.put("Label", label = "Test Immunogen Type Label"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignImmunogenTypes(), data); - assertEquals("Unexpected study design lookup label", label, _manager.getStudyDesignImmunogenTypeLabelByName(_container, name)); - assertNull("Unexpected study design lookup label", _manager.getStudyDesignImmunogenTypeLabelByName(_container, "UNK")); - _lookups.put("ImmunogenType", name); - - data.put("Name", name = "Test Gene"); - data.put("Label", label = "Test Gene Label"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignGenes(), data); - assertEquals("Unexpected study design lookup label", label, _manager.getStudyDesignGeneLabelByName(_container, name)); - assertNull("Unexpected study design lookup label", _manager.getStudyDesignGeneLabelByName(_container, "UNK")); - _lookups.put("Gene", name); - - data.put("Name", name = "Test SubType"); - data.put("Label", label = "Test SubType Label"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignSubTypes(), data); - assertEquals("Unexpected study design lookup label", label, _manager.getStudyDesignSubTypeLabelByName(_container, name)); - assertNull("Unexpected study design lookup label", _manager.getStudyDesignSubTypeLabelByName(_container, "UNK")); - _lookups.put("SubType", name); - - data.put("Name", name = "Test Route"); - data.put("Label", label = "Test Route Label"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignRoutes(), data); - assertEquals("Unexpected study design lookup label", label, _manager.getStudyDesignRouteLabelByName(_container, name)); - assertNull("Unexpected study design lookup label", _manager.getStudyDesignRouteLabelByName(_container, "UNK")); - _lookups.put("Route", name); - - assertEquals(4, _lookups.keySet().size()); - } - - private void verifyTreatmentVisitMapRecords(int expectedCount) - { - List rows = _manager.getStudyTreatmentVisitMap(_container, null); - assertEquals("Unexpected number of study.TreatmentVisitMap rows", expectedCount, rows.size()); - } - - private void verifyTreatmentProductMapRecords(int treatmentId, int expectedCount) - { - List rows = _manager.getStudyTreatmentProducts(_container, _user, treatmentId); - assertEquals("Unexpected number of study.TreatmentProductMap rows", expectedCount, rows.size()); - } - - private void verifyStudyProductAntigens(int productId, int expectedCount) - { - List rows = _manager.getStudyProductAntigens(_container, _user, productId); - assertEquals("Unexpected number of study.ProductAntigen rows", expectedCount, rows.size()); - - for (ProductAntigenImpl row : rows) - { - assertEquals("Unexpected antigen lookup value", _lookups.get("Gene"), row.getGene()); - assertEquals("Unexpected antigen lookup value", _lookups.get("SubType"), row.getSubType()); - } - } - - private void createStudy() - { - _context = TestContext.get(); - Container junit = JunitUtil.getTestContainer(); - - String name = GUID.makeHash(); - Container c = ContainerManager.createContainer(junit, name, _context.getUser()); - Set modules = new HashSet<>(c.getActiveModules()); - modules.add(ModuleLoader.getInstance().getModule("studydesign")); - c.setActiveModules(modules); - _junitStudy = StudyService.get().createStudy(c, _context.getUser(), "Junit Study", TimepointType.VISIT, true); - } - - private void tearDown() - { - if (null != _junitStudy) - { - assertTrue(ContainerManager.delete(_junitStudy.getContainer(), _context.getUser())); - } - } - } - - @TestWhen(TestWhen.When.BVT) - public static class AssayScheduleTestCase extends Assert - { - TestContext _context = null; - User _user = null; - Container _container = null; - Study _junitStudy = null; - - Map _lookups = new HashMap<>(); - List _assays = new ArrayList<>(); - List _visits = new ArrayList<>(); - - @Test - public void test() - { - try - { - createStudy(); - _user = _context.getUser(); - _container = _junitStudy.getContainer(); - - populateLookupTables(); - populateAssayConfigurations(); - populateAssaySchedule(); - - verifyAssayConfigurations(); - verifyAssaySchedule(); - verifyCleanUpAssayConfigurations(); - } - finally - { - tearDown(); - } - } - - private void verifyCleanUpAssayConfigurations() - { - StudyDesignService.get().deleteAssaySpecimenVisits(_container, _visits.get(0).getId()); - verifyAssayScheduleRowCount(2); - assertEquals(1, TreatmentManager.getInstance().getAssaySpecimenVisitIds(_container, _assays.get(0)).size()); - assertEquals(1, TreatmentManager.getInstance().getVisitsForAssaySchedule(_container).size()); - - StudyDesignService.get().deleteAssaySpecimenVisits(_container, _visits.get(1).getId()); - verifyAssayScheduleRowCount(0); - assertEquals(0, TreatmentManager.getInstance().getAssaySpecimenVisitIds(_container, _assays.get(0)).size()); - assertEquals(0, TreatmentManager.getInstance().getVisitsForAssaySchedule(_container).size()); - } - - private void verifyAssaySchedule() - { - verifyAssayScheduleRowCount(4); - - List visits = TreatmentManager.getInstance().getVisitsForAssaySchedule(_container); - assertEquals("Unexpected assay schedule visit count", 2, visits.size()); - - for (AssaySpecimenConfig assay : StudyDesignService.get().getAssaySpecimenConfigs(_container)) - { - List visitIds = TreatmentManager.getInstance().getAssaySpecimenVisitIds(_container, assay); - for (Visit visit : _visits) - assertTrue("Assay schedule does not contain expected visitId", visitIds.contains(visit.getId())); - } - } - - private void verifyAssayScheduleRowCount(int expectedCount) - { - TableSelector selector = new TableSelector(StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), SimpleFilter.createContainerFilter(_container), null); - assertEquals("Unexpected number of assay schedule visit records", expectedCount, selector.getRowCount()); - } - - private void verifyAssayConfigurations() - { - Collection assays = StudyDesignService.get().getAssaySpecimenConfigs(_container); - assertEquals("Unexpected assay configuration count", 2, assays.size()); - - for (AssaySpecimenConfig assay : assays) - { - if (assay instanceof AssaySpecimenConfigImpl assayConfig) - { - assertEquals("Unexpected assay configuration lookup value", _lookups.get("Lab"), assayConfig.getLab()); - assertEquals("Unexpected assay configuration lookup value", _lookups.get("SampleType"), assayConfig.getSampleType()); - } - } - } - - private void populateAssaySchedule() - { - _visits.add(VisitService.get().createVisit(_junitStudy, _user, BigDecimal.valueOf(1.0), "Visit 1", Visit.Type.BASELINE)); - _visits.add(VisitService.get().createVisit(_junitStudy, _user, BigDecimal.valueOf(2.0), "Visit 2", Visit.Type.SCHEDULED_FOLLOWUP)); - assertEquals(2, _visits.size()); - - for (AssaySpecimenConfigImpl assay : _assays) - { - for (Visit visit : _visits) - { - AssaySpecimenVisitImpl asv = new AssaySpecimenVisitImpl(_container, assay.getRowId(), visit.getId()); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoAssaySpecimenVisit(), asv); - } - } - - verifyAssayScheduleRowCount(_assays.size() * _visits.size()); - } - - private void populateAssayConfigurations() - { - AssaySpecimenConfigImpl assay1 = new AssaySpecimenConfigImpl(_container, "Assay1", "Assay 1 description"); - assay1.setLab(_lookups.get("Lab")); - assay1.setSampleType(_lookups.get("SampleType")); - _assays.add(TreatmentManager.getInstance().addAssaySpecimenConfig(_user, assay1)); - - AssaySpecimenConfigImpl assay2 = new AssaySpecimenConfigImpl(_container, "Assay2", "Assay 2 description"); - assay2.setLab(_lookups.get("Lab")); - assay2.setSampleType(_lookups.get("SampleType")); - _assays.add(TreatmentManager.getInstance().addAssaySpecimenConfig(_user, assay2)); - - assertEquals(2, _assays.size()); - } - - private void populateLookupTables() - { - String name, label; - - Map data = new HashMap<>(); - data.put("Container", _container.getId()); - - data.put("Name", name = "Test Lab"); - data.put("Label", label = "Test Lab Label"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignLabs(), data); - assertEquals("Unexpected study design lookup label", label, TreatmentManager.getInstance().getStudyDesignLabLabelByName(_container, name)); - assertNull("Unexpected study design lookup label", TreatmentManager.getInstance().getStudyDesignLabLabelByName(_container, "UNK")); - _lookups.put("Lab", name); - - data.put("Name", name = "Test Sample Type"); - data.put("Label", "Test Sample Type Label"); - data.put("PrimaryType", "Test Primary Type"); - data.put("ShortSampleCode", "TP"); - Table.insert(_user, StudyDesignSchema.getInstance().getTableInfoStudyDesignSampleTypes(), data); - _lookups.put("SampleType", name); - } - - private void createStudy() - { - _context = TestContext.get(); - Container junit = JunitUtil.getTestContainer(); - - String name = GUID.makeHash(); - Container c = ContainerManager.createContainer(junit, name, _context.getUser()); - _junitStudy = StudyService.get().createStudy(c, _context.getUser(), "Junit Study", TimepointType.VISIT, true); - } - - private void tearDown() - { - if (null != _junitStudy) - { - assertTrue(ContainerManager.delete(_junitStudy.getContainer(), _context.getUser())); - } - } - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java b/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java deleted file mode 100644 index 1d51c690124..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2013-2018 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONObject; -import org.labkey.api.data.Container; -import org.labkey.api.study.TreatmentProduct; -import org.labkey.api.util.Pair; - -import java.util.HashMap; -import java.util.Map; - -import static org.labkey.api.util.IntegerUtils.asIntegerElseNull; - -/** - * User: cnathe - * Date: 12/27/13 - */ -public class TreatmentProductImpl implements TreatmentProduct -{ - public static final String PRODUCT_DOSE_DELIMITER = "-#-"; - private Container _container; - private int _rowId; - private int _treatmentId; - private int _productId; - private String _dose; - private String _route; - private String _doseAndRoute; - private String _productDoseRoute; - - public TreatmentProductImpl() - {} - - public TreatmentProductImpl(Container container, int treatmentId, int productId) - { - _container = container; - _treatmentId = treatmentId; - _productId = productId; - } - - public boolean isNew() - { - return _rowId == 0; - } - - public Object getPrimaryKey() - { - return getRowId(); - } - - @Override - public int getRowId() - { - return _rowId; - } - - public void setRowId(int rowId) - { - _rowId = rowId; - } - - @Override - public int getTreatmentId() - { - return _treatmentId; - } - - public void setTreatmentId(int treatmentId) - { - _treatmentId = treatmentId; - } - - @Override - public int getProductId() - { - return _productId; - } - - public void setProductId(int productId) - { - _productId = productId; - } - - @Override - public String getDose() - { - return _dose; - } - - public void setDose(String dose) - { - _dose = dose; - } - - @Override - public String getRoute() - { - return _route; - } - - public void setRoute(String route) - { - _route = route; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - public String getDoseAndRoute() - { - return _doseAndRoute; - } - - public void setDoseAndRoute(String doseAndRoute) - { - _doseAndRoute = doseAndRoute; - } - - public Map serialize() - { - syncDoseAndRoute(); - Map props = new HashMap<>(); - props.put("RowId", getRowId()); - props.put("TreatmentId", getTreatmentId()); - props.put("ProductId", getProductId()); - props.put("Dose", getDose()); - props.put("Route", getRoute()); - props.put("DoseAndRoute", getDoseAndRoute()); - props.put("ProductDoseRoute", getProductDoseRoute()); - - return props; - } - - /** - * Keeps the dose, route, and doseAndRoute fields synchronized - */ - private void syncDoseAndRoute() - { - if (getDoseAndRoute() == null && (getDose() != null || getRoute() != null) && getProductId() > 0) - { - // get the entry from the DoseAndRoute table so we can serialize the label - DoseAndRoute doseAndRoute = TreatmentManager.getInstance().getDoseAndRoute(getContainer(), getDose(), getRoute(), getProductId()); - if (doseAndRoute != null) - { - setDoseAndRoute(doseAndRoute.getLabel()); - setProductDoseRoute(String.valueOf(getProductId() + PRODUCT_DOSE_DELIMITER + doseAndRoute.getLabel())); - } - } - else if (getDoseAndRoute() != null && getDose() == null && getRoute() == null) - { - Pair parts = DoseAndRoute.parseFromLabel(getDoseAndRoute()); - if (parts != null) - { - DoseAndRoute doseAndRoute = TreatmentManager.getInstance().getDoseAndRoute(getContainer(), parts.getKey(), parts.getValue(), getProductId()); - if (doseAndRoute != null) - { - setDose(doseAndRoute.getDose()); - setRoute(doseAndRoute.getRoute()); - } - } - } - else if (getDoseAndRoute() == null && getDose() == null && getRoute() == null && getProductId() > 0) - { - setProductDoseRoute(String.valueOf(getProductId() + PRODUCT_DOSE_DELIMITER)); - } - } - - public static TreatmentProductImpl fromJSON(@NotNull JSONObject o, Container container) - { - TreatmentProductImpl treatmentProduct = new TreatmentProductImpl(); - //treatmentProduct.setDose(o.getString("Dose")); - //treatmentProduct.setRoute(o.getString("Route")); - treatmentProduct.setContainer(container); - if (o.has("ProductId") && asIntegerElseNull(o.get("ProductId")) instanceof Integer productId) - treatmentProduct.setProductId(productId); - if (o.has("TreatmentId") && asIntegerElseNull(o.get("TreatmentId")) instanceof Integer treatmentId) - treatmentProduct.setTreatmentId(treatmentId); - if (o.has("RowId")) - treatmentProduct.setRowId(o.getInt("RowId")); - if (o.has("DoseAndRoute")) - treatmentProduct.setDoseAndRoute(o.getString("DoseAndRoute")); - if (o.has("ProductDoseRoute")) - treatmentProduct.populateProductDoseRoute(o.getString("ProductDoseRoute")); - - return treatmentProduct; - } - - public void setProductDoseRoute(String productDoseRoute) - { - _productDoseRoute = productDoseRoute; - } - - public String getProductDoseRoute() - { - return _productDoseRoute; - } - - private void populateProductDoseRoute(String productDoseRoute) - { - if (productDoseRoute == null) - return; - setProductDoseRoute(productDoseRoute); - String[] parts = productDoseRoute.split(PRODUCT_DOSE_DELIMITER); - setProductId(Integer.parseInt(parts[0])); - if (parts.length > 1) - setDoseAndRoute(parts[1]); - } - - public boolean isSameTreatmentProductWith(TreatmentProductImpl other) - { - if (other == null) - return false; - if (this.getProductId() != other.getProductId()) - return false; - if (this.getProductDoseRoute() != null && other.getProductDoseRoute() != null) - return this.getProductDoseRoute().equals(other.getProductDoseRoute()); - - if (this.getDose() != null) - { - if (other.getDose() == null || !this.getDose().equals(other.getDose())) - return false; - } - else if (other.getDose() != null) - return false; - - if (this.getRoute() != null) - { - if (other.getRoute() == null || !this.getRoute().equals(other.getRoute())) - return false; - } - else if (other.getRoute() != null) - return false; - - return true; - } -} diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMap.java b/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMap.java deleted file mode 100644 index 3c5107c5ab9..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMap.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2014 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -/** - * User: cnathe - * Date: 12/30/13 - */ -public interface TreatmentVisitMap -{ - int getCohortId(); - int getTreatmentId(); - int getVisitId(); -} diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMapImpl.java b/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMapImpl.java deleted file mode 100644 index 838893b46dd..00000000000 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentVisitMapImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2014-2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.model; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONObject; -import org.labkey.api.data.Container; - -import static org.labkey.api.util.IntegerUtils.asIntegerElseNull; - -/** - * User: cnathe - * Date: 12/30/13 - */ -public class TreatmentVisitMapImpl implements TreatmentVisitMap -{ - private int _cohortId; - private int _treatmentId; - private String _tempTreatmentId; // used to map new treatment records used in mappings to the tempRowId in TreatmentImpl - private int _visitId; - private Container _container; - - public TreatmentVisitMapImpl() - { - } - - @Override - public int getCohortId() - { - return _cohortId; - } - - public void setCohortId(int cohortId) - { - _cohortId = cohortId; - } - - @Override - public int getTreatmentId() - { - return _treatmentId; - } - - public void setTreatmentId(int treatmentId) - { - _treatmentId = treatmentId; - } - - public String getTempTreatmentId() - { - return _tempTreatmentId; - } - - private void setTempTreatmentId(String tempTreatmentId) - { - _tempTreatmentId = tempTreatmentId; - } - - @Override - public int getVisitId() - { - return _visitId; - } - - public void setVisitId(int visitId) - { - _visitId = visitId; - } - - public Container getContainer() - { - return _container; - } - - public void setContainer(Container container) - { - _container = container; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - final TreatmentVisitMapImpl o = (TreatmentVisitMapImpl) obj; - - return o.getCohortId() == getCohortId() - && o.getTreatmentId() == getTreatmentId() - && o.getVisitId() == getVisitId() - && ((o.getContainer() == null && getContainer() == null) || o.getContainer().equals(getContainer())); - } - - public static TreatmentVisitMapImpl fromJSON(@NotNull JSONObject o) - { - TreatmentVisitMapImpl visitMap = new TreatmentVisitMapImpl(); - visitMap.setVisitId(o.getInt("VisitId")); - if (o.has("CohortId")) - visitMap.setCohortId(o.getInt("CohortId")); - if (o.has("TreatmentId")) - { - if (asIntegerElseNull(o.get("TreatmentId")) instanceof Integer treatmentId) - visitMap.setTreatmentId(treatmentId); - else - visitMap.setTempTreatmentId(o.getString("TreatmentId")); - } - - return visitMap; - } -} diff --git a/studydesign/src/org/labkey/studydesign/view/AssayScheduleWebpartFactory.java b/studydesign/src/org/labkey/studydesign/view/AssayScheduleWebpartFactory.java deleted file mode 100644 index 60dfbfe746a..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/AssayScheduleWebpartFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013-2014 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.view; - -import org.jetbrains.annotations.NotNull; -import org.labkey.api.data.Container; -import org.labkey.api.study.Study; -import org.labkey.api.study.StudyService; -import org.labkey.api.study.StudyUrls; -import org.labkey.api.study.TimepointType; -import org.labkey.api.study.security.permissions.ManageStudyPermission; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.view.JspView; -import org.labkey.api.view.NavTree; -import org.labkey.api.view.Portal; -import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; - -/** - * User: cnathe - * Date: 12/16/13 - */ -public class AssayScheduleWebpartFactory extends StudyDesignWebpartFactory -{ - public static String NAME = "Assay Schedule"; - - public AssayScheduleWebpartFactory() - { - super(NAME); - } - - @Override - public WebPartView getWebPartView(@NotNull ViewContext portalCtx, @NotNull Portal.WebPart webPart) - { - if (!canShow(portalCtx.getContainer())) - return null; - - JspView view = new JspView<>("/org/labkey/studydesign/view/assayScheduleWebpart.jsp", webPart); - view.setTitle(NAME); - view.setFrame(WebPartView.FrameType.PORTAL); - - Container c = portalCtx.getContainer(); - Study study = StudyService.get().getStudy(c); - if (c.hasPermission(portalCtx.getUser(), ManageStudyPermission.class)) - { - String timepointMenuName; - if (study != null && study.getTimepointType() == TimepointType.DATE) - timepointMenuName = "Manage Timepoints"; - else - timepointMenuName = "Manage Visits"; - - NavTree menu = new NavTree(); - menu.addChild(timepointMenuName, PageFlowUtil.urlProvider(StudyUrls.class).getManageVisitsURL(c)); - view.setNavMenu(menu); - } - - return view; - } -} diff --git a/studydesign/src/org/labkey/studydesign/view/ImmunizationScheduleWebpartFactory.java b/studydesign/src/org/labkey/studydesign/view/ImmunizationScheduleWebpartFactory.java deleted file mode 100644 index 946a00eefda..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/ImmunizationScheduleWebpartFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2013-2014 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.view; - -import org.jetbrains.annotations.NotNull; -import org.labkey.api.data.Container; -import org.labkey.api.study.Study; -import org.labkey.api.study.StudyService; -import org.labkey.api.study.StudyUrls; -import org.labkey.api.study.TimepointType; -import org.labkey.api.study.security.permissions.ManageStudyPermission; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.view.JspView; -import org.labkey.api.view.NavTree; -import org.labkey.api.view.Portal; -import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; - -/** - * User: cnathe - * Date: 12/30/13 - */ -public class ImmunizationScheduleWebpartFactory extends StudyDesignWebpartFactory -{ - public static String NAME = "Immunization Schedule"; - - public ImmunizationScheduleWebpartFactory() - { - super(NAME); - } - - @Override - public WebPartView getWebPartView(@NotNull ViewContext portalCtx, @NotNull Portal.WebPart webPart) - { - if (!canShow(portalCtx.getContainer())) - return null; - - JspView view = new JspView<>("/org/labkey/studydesign/view/immunizationScheduleWebpart.jsp", webPart); - view.setTitle(NAME); - view.setFrame(WebPartView.FrameType.PORTAL); - - Container c = portalCtx.getContainer(); - Study study = StudyService.get().getStudy(c); - if (c.hasPermission(portalCtx.getUser(), ManageStudyPermission.class)) - { - String timepointMenuName; - if (study != null && study.getTimepointType() == TimepointType.DATE) - timepointMenuName = "Manage Timepoints"; - else - timepointMenuName = "Manage Visits"; - - NavTree menu = new NavTree(); - menu.addChild("Manage Cohorts", PageFlowUtil.urlProvider(StudyUrls.class).getManageCohortsURL(c)); - menu.addChild(timepointMenuName, PageFlowUtil.urlProvider(StudyUrls.class).getManageVisitsURL(c)); - view.setNavMenu(menu); - } - - return view; - } -} diff --git a/studydesign/src/org/labkey/studydesign/view/StudyDesignConfigureMenuItem.java b/studydesign/src/org/labkey/studydesign/view/StudyDesignConfigureMenuItem.java deleted file mode 100644 index b0b96d8e3de..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/StudyDesignConfigureMenuItem.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.view; - -import org.labkey.api.data.Container; -import org.labkey.api.query.QueryUrls; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.NavTree; - -public class StudyDesignConfigureMenuItem extends NavTree -{ - public StudyDesignConfigureMenuItem(String text, String schemaName, String queryName, Container container) - { - super(text); - - ActionURL url = new ActionURL(); - url.setContainer(container); - url.addParameter("schemaName", schemaName); - url.addParameter("query.queryName", queryName); - setHref(PageFlowUtil.urlProvider(QueryUrls.class).urlExecuteQuery(url).toString()); - setTarget("_blank"); // issue 19493 - } -} diff --git a/studydesign/src/org/labkey/studydesign/view/StudyDesignWebpartFactory.java b/studydesign/src/org/labkey/studydesign/view/StudyDesignWebpartFactory.java deleted file mode 100644 index b4cfa04c1be..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/StudyDesignWebpartFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.labkey.studydesign.view; - -import org.labkey.api.data.Container; -import org.labkey.api.studydesign.StudyDesignManager; -import org.labkey.api.view.BaseWebPartFactory; - -public abstract class StudyDesignWebpartFactory extends BaseWebPartFactory -{ - public StudyDesignWebpartFactory(String name) - { - super(name); - } - - protected boolean canShow(Container c) - { - return StudyDesignManager.get().isModuleActive(c); - } - - @Override - public boolean isAvailable(Container c, String scope, String location) - { - return canShow(c) ? super.isAvailable(c, scope, location) : false; - } -} \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/view/VaccineDesignWebpartFactory.java b/studydesign/src/org/labkey/studydesign/view/VaccineDesignWebpartFactory.java deleted file mode 100644 index 22588e2e316..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/VaccineDesignWebpartFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013-2014 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.studydesign.view; - -import org.jetbrains.annotations.NotNull; -import org.labkey.api.view.JspView; -import org.labkey.api.view.Portal; -import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; - -/** - * User: cnathe - * Date: 12/27/13 - */ -public class VaccineDesignWebpartFactory extends StudyDesignWebpartFactory -{ - public static String NAME = "Vaccine Design"; - - public VaccineDesignWebpartFactory() - { - super(NAME); - } - - @Override - public WebPartView getWebPartView(@NotNull ViewContext portalCtx, @NotNull Portal.WebPart webPart) - { - if (!canShow(portalCtx.getContainer())) - return null; - - JspView view = new JspView<>("/org/labkey/studydesign/view/vaccineDesignWebpart.jsp", webPart); - view.setTitle(NAME); - view.setFrame(WebPartView.FrameType.PORTAL); - return view; - } -} diff --git a/studydesign/src/org/labkey/studydesign/view/assayScheduleWebpart.jsp b/studydesign/src/org/labkey/studydesign/view/assayScheduleWebpart.jsp deleted file mode 100644 index 8cb641ccf77..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/assayScheduleWebpart.jsp +++ /dev/null @@ -1,88 +0,0 @@ -<% -/* - * Copyright (c) 2013-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.module.ModuleLoader" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.security.permissions.UpdatePermission" %> -<%@ page import="org.labkey.api.study.Study" %> -<%@ page import="org.labkey.api.study.StudyService" %> -<%@ page import="org.labkey.api.util.HtmlString" %> -<%@ page import="org.labkey.api.view.ActionURL" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.studydesign.StudyDesignController" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/vaccineDesign.lib.xml"); - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - Container c = getContainer(); - boolean useAlternateLookupFields = getContainer().getActiveModules().contains(ModuleLoader.getInstance().getModule("rho")); - - Study study = StudyService.get().getStudy(c); - - User user = getUser(); - boolean canEdit = c.hasPermission(user, UpdatePermission.class); - - String assayPlan = ""; - if (study != null && study.getAssayPlan() != null) - assayPlan = study.getAssayPlan(); -%> -<% - if (study != null) - { - %>This section shows the assay schedule for this study.
<% - - if (canEdit) - { - ActionURL editUrl = new ActionURL(StudyDesignController.ManageAssayScheduleAction.class, getContainer()); - if (useAlternateLookupFields) - editUrl.addParameter("useAlternateLookupFields", true); - editUrl.addReturnUrl(getActionURL()); -%> - <%=link("Manage Assay Schedule", editUrl)%>
-<% - } - -%> -

<%=HtmlString.unsafe(h(assayPlan).toString().replaceAll("\n", "
"))%>

-
-<% - } - else - { -%> -

The folder must contain a study in order to display an assay schedule.

-<% - } -%> - - \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/view/immunizationScheduleWebpart.jsp b/studydesign/src/org/labkey/studydesign/view/immunizationScheduleWebpart.jsp deleted file mode 100644 index 5e4f5363edf..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/immunizationScheduleWebpart.jsp +++ /dev/null @@ -1,175 +0,0 @@ -<% -/* - * Copyright (c) 2013-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.security.permissions.UpdatePermission" %> -<%@ page import="org.labkey.api.study.Cohort" %> -<%@ page import="org.labkey.api.study.Study" %> -<%@ page import="org.labkey.api.study.StudyService" %> -<%@ page import="org.labkey.api.study.Visit" %> -<%@ page import="org.labkey.api.studydesign.StudyDesignUrls" %> -<%@ page import="org.labkey.api.util.HtmlString" %> -<%@ page import="org.labkey.api.view.ActionURL" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.studydesign.model.ProductImpl" %> -<%@ page import="org.labkey.studydesign.model.TreatmentImpl" %> -<%@ page import="org.labkey.studydesign.model.TreatmentManager" %> -<%@ page import="org.labkey.studydesign.model.TreatmentVisitMap" %> -<%@ page import="java.util.Collection" %> -<%@ page import="java.util.HashMap" %> -<%@ page import="java.util.List" %> -<%@ page import="java.util.Map" %> -<%@ page import="org.labkey.api.collections.IntHashMap" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - Container c = getContainer(); - Study study = StudyService.get().getStudy(c); - - User user = getUser(); - boolean canEdit = c.hasPermission(user, UpdatePermission.class); - - String subjectNoun = "Subject"; - if (study != null) - subjectNoun = study.getSubjectNounSingular(); -%> - - - -<% - if (study != null) - { - if (!StudyService.get().showCohorts(c, user)) - { - %>

You do not have permissions to see this data.

<% - } - else - { - Collection cohorts = study.getCohorts(user); - %>This section shows the immunization schedule for this study. Each treatment may consist of one or more study products.
<% - - if (canEdit) - { - ActionURL editUrl = urlProvider(StudyDesignUrls.class).getManageTreatmentsURL(c, c.hasActiveModuleByName("viscstudies")); - editUrl.addReturnUrl(getActionURL()); -%> - <%=link("Manage Treatments", editUrl)%>
-<% - } - - List visits = TreatmentManager.getInstance().getVisitsForTreatmentSchedule(getContainer()); -%> -
-
-
Immunization Schedule
- - - - -<% - for (Visit visit : visits) - { -%> - -<% - } -%> - -<% - if (cohorts.isEmpty()) - { - %><% - } - - int index = 0; - for (Cohort cohort : cohorts) - { - index++; - List mapping = TreatmentManager.getInstance().getStudyTreatmentVisitMap(c, cohort.getRowId()); - Map visitTreatments = new IntHashMap<>(); - for (TreatmentVisitMap treatmentVisitMap : mapping) - { - visitTreatments.put(treatmentVisitMap.getVisitId(), treatmentVisitMap.getTreatmentId()); - } -%> - " outer-index="<%=index-1%>"> - - -<% - for (Visit visit : visits) - { - Integer treatmentId = visitTreatments.get(visit.getId()); - TreatmentImpl treatment = null; - if (treatmentId != null) - treatment = TreatmentManager.getInstance().getStudyTreatmentByRowId(c, user, treatmentId); - - // show the list of study products for the treatment as a hover - String productHover = ""; - if (treatment != null && treatment.getProducts() != null) - { - productHover += "
Group / Cohort<%=h(subjectNoun)%> Count - <%=h(visit.getDisplayString())%> - <%=(visit.getDescription() != null ? helpPopup("Description", visit.getDescription()) : HtmlString.EMPTY_STRING)%> -
No data to show.
<%=h(cohort.getLabel())%><%=h(cohort.getSubjectCount())%>
" - + "" - + "" - + ""; - - for (ProductImpl product : treatment.getProducts()) - { - String routeLabel = TreatmentManager.getInstance().getStudyDesignRouteLabelByName(c, product.getRoute()); - - productHover += "" - + "" - + ""; - } - - productHover += "
LabelDose and unitsRoute
" + h(product.getLabel()) + "" + h(product.getDose()) + "" + h(routeLabel != null ? routeLabel : product.getRoute()) + "
"; - } -%> - - <%=h(treatment != null ? treatment.getLabel() : "")%> - <%=(!productHover.isEmpty() ? helpPopup("Treatment Products", HtmlString.unsafe(productHover), 500) : HtmlString.EMPTY_STRING)%> - -<% - } -%> - -<% - } -%> - - -<% - } - } - else - { - %>

The folder must contain a study in order to display an immunization schedule.

<% - } -%> diff --git a/studydesign/src/org/labkey/studydesign/view/manageAssaySchedule.jsp b/studydesign/src/org/labkey/studydesign/view/manageAssaySchedule.jsp deleted file mode 100644 index 3c2c1ee3d7c..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/manageAssaySchedule.jsp +++ /dev/null @@ -1,128 +0,0 @@ -<% -/* - * Copyright (c) 2014-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.portal.ProjectUrls" %> -<%@ page import="org.labkey.api.study.Study" %> -<%@ page import="org.labkey.api.study.StudyService" %> -<%@ page import="org.labkey.api.study.StudyUrls" %> -<%@ page import="org.labkey.api.study.TimepointType" %> -<%@ page import="org.labkey.api.util.PageFlowUtil" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.api.view.NavTree" %> -<%@ page import="org.labkey.api.view.PopupMenuView" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.studydesign.StudyDesignController" %> -<%@ page import="org.labkey.studydesign.view.StudyDesignConfigureMenuItem" %> -<%@ page import="java.lang.Override" %> -<%@ page import="java.lang.String" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/vaccineDesign.lib.xml"); - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - JspView me = HttpView.currentView(); - StudyDesignController.AssayScheduleForm form = me.getModelBean(); - - Container c = getContainer(); - Study study = StudyService.get().getStudy(getContainer()); - - // assay schedule is editable for the individual studies in a Dataspace project - boolean disableEdit = c.isProject() && c.isDataspace(); - - String visitNoun = "Visit"; - if (study != null && study.getTimepointType() == TimepointType.DATE) - visitNoun = "Timepoint"; - - String returnUrl = form.getReturnUrl() != null ? form.getReturnUrl() : urlProvider(ProjectUrls.class).getBeginURL(c).toString(); -%> - - - -Enter assay schedule information in the grids below. -
-
    -
  • > - Configure dropdown options for assays, labs, sample types, and units at the project - level to be shared across study designs or within this folder for - study specific properties: - -
  • -
  • - Select the <%=h(visitNoun.toLowerCase())%>s for each assay in the schedule - portion of the grid to define the expected assay schedule for the study. -
  • -
  • > - Use the manage locationss page to further configure information about the locations for this study. - <%= link("Manage Locations", PageFlowUtil.urlProvider(StudyUrls.class).getManageLocationsURL(getContainer())) %> -
  • -
  • - Use the manage <%=h(visitNoun.toLowerCase())%>s page to further configure - information about the <%=h(visitNoun.toLowerCase())%>s for this study or to change - the <%=h(visitNoun.toLowerCase())%> display order. - <%=link("Manage " + visitNoun + "s", PageFlowUtil.urlProvider(StudyUrls.class).getManageVisitsURL(getContainer()))%> -
  • -
-
-
-
diff --git a/studydesign/src/org/labkey/studydesign/view/manageStudyProducts.jsp b/studydesign/src/org/labkey/studydesign/view/manageStudyProducts.jsp deleted file mode 100644 index d88d0739138..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/manageStudyProducts.jsp +++ /dev/null @@ -1,135 +0,0 @@ -<% -/* - * Copyright (c) 2013-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.action.ReturnUrlForm" %> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.portal.ProjectUrls" %> -<%@ page import="org.labkey.api.studydesign.StudyDesignUrls" %> -<%@ page import="org.labkey.api.view.ActionURL" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.api.view.NavTree" %> -<%@ page import="org.labkey.api.view.PopupMenuView" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.studydesign.view.StudyDesignConfigureMenuItem" %> -<%@ page import="org.labkey.studydesign.StudyDesignController" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/vaccineDesign.lib.xml"); - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - JspView me = HttpView.currentView(); - ReturnUrlForm bean = me.getModelBean(); - Container c = getContainer(); - - // study products are editable at the project level for Dataspace projects - boolean isDataspaceProject = c.getProject() != null && c.getProject().isDataspace() && !c.isDataspace(); - - String returnUrl = bean.getReturnUrl() != null ? bean.getReturnUrl() : urlProvider(ProjectUrls.class).getBeginURL(c).toString(); -%> - - - -<% -if (isDataspaceProject) -{ - ActionURL projectManageProductsURL = new ActionURL(StudyDesignController.ManageStudyProductsAction.class, getContainer().getProject()); - projectManageProductsURL.addReturnUrl(getActionURL()); -%> -Vaccine design information is defined at the project level for Dataspace projects. The grids below are read-only. -
-
    -
  • - Use the manage study products page at the project level to make changes to the information listed below. - <%=link("Manage Study Products", projectManageProductsURL)%> -
  • -<% -} -else -{ -%> -Enter vaccine design information in the grids below. -
    -
      -
    • Each immunogen, adjuvant and challenge in the study should be listed on one row of the grids below.
    • -
    • Immunogens, adjuvants and challenges should have unique labels.
    • -
    • If possible, the immunogen description should include specific sequences of HIV Antigens included in the immunogen.
    • -
    • - Use the manage treatments page to describe the schedule of treatments and combinations of study products administered at each timepoint. - <% - ActionURL manageTreatmentsURL = urlProvider(StudyDesignUrls.class).getManageTreatmentsURL(c, c.hasActiveModuleByName("viscstudies")); - manageTreatmentsURL.addReturnUrl(getActionURL()); - %> - <%=link("Manage Treatments", manageTreatmentsURL)%> -
    • -<% -} -%> -
    • - Configure dropdown options for challenge types, immunogen types, genes, subtypes and routes at the project level to be shared across study designs or within this folder for - study specific properties: - -
    • -
    -
    - -
    diff --git a/studydesign/src/org/labkey/studydesign/view/manageTreatments.jsp b/studydesign/src/org/labkey/studydesign/view/manageTreatments.jsp deleted file mode 100644 index b92b00f9420..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/manageTreatments.jsp +++ /dev/null @@ -1,169 +0,0 @@ -<% -/* - * Copyright (c) 2014-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.portal.ProjectUrls" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.study.Study" %> -<%@ page import="org.labkey.api.study.StudyService" %> -<%@ page import="org.labkey.api.study.StudyUrls" %> -<%@ page import="org.labkey.api.study.TimepointType" %> -<%@ page import="org.labkey.api.study.Visit" %> -<%@ page import="org.labkey.api.study.security.permissions.ManageStudyPermission" %> -<%@ page import="org.labkey.api.util.PageFlowUtil" %> -<%@ page import="org.labkey.api.view.ActionURL" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="java.lang.Override" %> -<%@ page import="java.lang.String" %> -<%@ page import="org.labkey.studydesign.StudyDesignController" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/vaccineDesign.lib.xml"); - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - JspView me = HttpView.currentView(); - StudyDesignController.ManageTreatmentsBean bean = me.getModelBean(); - - Container c = getContainer(); - User user = getUser(); - - Study study = StudyService.get().getStudy(c); - boolean canManageStudy = c.hasPermission(user, ManageStudyPermission.class); - - // treatment schedule is editable for the individual studies in a Dataspace project - boolean isDataspaceProject = c.isProject() && c.isDataspace(); - - String visitNoun = "Visit"; - if (study != null && study.getTimepointType() == TimepointType.DATE) - visitNoun = "Timepoint"; - - String subjectNoun = "Subject"; - if (study != null) - subjectNoun = study.getSubjectNounSingular(); - - String returnUrl = bean.getReturnUrl() != null ? bean.getReturnUrl() : urlProvider(ProjectUrls.class).getBeginURL(c).toString(); -%> - - - -<% -if (isDataspaceProject) -{ -%> -Treatment information is defined at the individual study level for Dataspace projects. The grids below are read-only. -

    -<% -} -else -{ -%> -Enter treatment information in the grids below. -
    -
      - <% - if (bean.isSingleTable()) - { - %> -
    • - Click on time point to define its treatment products by selecting a combination of study products. -
    • - <% - } - else - { - %> -
    • - Each treatment label must be unique and must consist of at least one study products. -
    • - <% - } - %> -
    • - Use the manage study products page to change or update the set of available values. - <% - ActionURL manageStudyProductsURL = new ActionURL(StudyDesignController.ManageStudyProductsAction.class, getContainer()); - manageStudyProductsURL.addReturnUrl(getActionURL()); - %> - <%=link("Manage Study Products", manageStudyProductsURL)%> -
    • -
    • - Each cohort label must be unique. Enter the number of <%=h(study.getSubjectNounPlural().toLowerCase())%> for - the cohort in the count column.
    • -
    • - Use the manage cohorts page to further configuration information about the cohorts for this study. - <%=link("Manage Cohorts", PageFlowUtil.urlProvider(StudyUrls.class).getManageCohortsURL(getContainer()))%> -
    • -
    • - Use the manage <%=h(visitNoun.toLowerCase())%>s page to further configure - information about the <%=h(visitNoun.toLowerCase())%>s for this study or to change - the <%=h(visitNoun.toLowerCase())%> display order. - <%=link("Manage " + visitNoun + "s", PageFlowUtil.urlProvider(StudyUrls.class).getManageVisitsURL(getContainer()))%> -
    • -<% - if (canManageStudy) - { - if (study != null && study.getTimepointType() == TimepointType.VISIT && study.getVisits(Visit.Order.DISPLAY).size() > 1) - { -%> -
    • Use the change visit order page to adjust the display order of visits in the treatment schedule table. - <%= link("Change Visit Order", PageFlowUtil.urlProvider(StudyUrls.class).getVisitOrderURL(c).addReturnUrl(getActionURL())) %> -
    • -<% - } - } -%> -
    -
    -<% -} -%> - -
    \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/view/vaccineDesignWebpart.jsp b/studydesign/src/org/labkey/studydesign/view/vaccineDesignWebpart.jsp deleted file mode 100644 index b4deb509677..00000000000 --- a/studydesign/src/org/labkey/studydesign/view/vaccineDesignWebpart.jsp +++ /dev/null @@ -1,89 +0,0 @@ -<% -/* - * Copyright (c) 2013-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.security.permissions.UpdatePermission" %> -<%@ page import="org.labkey.api.study.Study" %> -<%@ page import="org.labkey.api.study.StudyService" %> -<%@ page import="org.labkey.api.view.ActionURL" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.studydesign.StudyDesignController" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("study/vaccineDesign/vaccineDesign.lib.xml"); - dependencies.add("study/vaccineDesign/VaccineDesign.css"); - } -%> -<% - User user = getUser(); - Container container = getContainer(); - Study study = StudyService.get().getStudy(container); - - if (study != null) - { - %>This section describes the study products evaluated in the study.
    <% - if (container.hasPermission(user, UpdatePermission.class)) - { - ActionURL editUrl = new ActionURL(StudyDesignController.ManageStudyProductsAction.class, getContainer()); - editUrl.addReturnUrl(getActionURL()); -%> - <%=link("Manage Study Products", editUrl)%>
    -<% - } -%> -
    -
    -
    -
    -
    -
    -<% - } - else - { -%> -

    The folder must contain a study in order to display a vaccine design.

    -<% - } -%> - - \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/AssaySchedule.js b/studydesign/webapp/study/vaccineDesign/AssaySchedule.js deleted file mode 100644 index 48c9c968ab3..00000000000 --- a/studydesign/webapp/study/vaccineDesign/AssaySchedule.js +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.AssaySchedulePanel', { - extend : 'Ext.panel.Panel', - - width: 750, - - border : false, - - bodyStyle : 'background-color: transparent;', - - disableEdit : true, - - dirty : false, - - returnUrl : null, - - initComponent : function() - { - this.items = [this.getAssaysGrid()]; - - this.callParent(); - - this.queryAssayPlan(); - - window.onbeforeunload = LABKEY.beforeunload(this.beforeUnload, this); - }, - - getAssaysGrid : function() - { - if (!this.assaysGrid) - { - this.assaysGrid = Ext4.create('LABKEY.VaccineDesign.AssaysGrid', { - disableEdit: this.disableEdit, - visitNoun: this.visitNoun, - useAlternateLookupFields: this.useAlternateLookupFields - }); - - this.assaysGrid.on('dirtychange', this.enableSaveButton, this); - this.assaysGrid.on('celledited', this.enableSaveButton, this); - } - - return this.assaysGrid; - }, - - queryAssayPlan : function() - { - // query the StudyProperties table for the initial assay plan value - LABKEY.Query.selectRows({ - schemaName: 'study', - queryName: 'StudyProperties', - columns: 'AssayPlan', - scope: this, - success: function(data) - { - var text = (data.rows.length == 1) ? data.rows[0]["AssayPlan"] : ''; - - this.add(this.getAssayPlanPanel(text)); - this.add(this.getButtonBar()); - } - }); - - }, - - getAssayPlanPanel : function(initValue) - { - if (!this.assayPlanPanel) - { - this.assayPlanPanel = Ext4.create('Ext.form.Panel', { - cls: 'study-vaccine-design', - padding: '20px 0', - border: false, - items: [ - Ext4.create('Ext.Component', { - html: '
    Assay Plan
    ' - }), - this.getAssayPlanTextArea(initValue) - ] - }); - } - - return this.assayPlanPanel; - }, - - getAssayPlanTextArea : function(initValue) - { - if (!this.assayPlanTextArea) - { - this.assayPlanTextArea = Ext4.create('Ext.form.field.TextArea', { - name: 'assayPlan', - readOnly: this.disableEdit, - value: initValue, - width: 500, - height: 100 - }); - - this.assayPlanTextArea.on('change', this.enableSaveButton, this, {buffer: 500}); - } - - return this.assayPlanTextArea; - }, - - getButtonBar : function() - { - if (!this.buttonBar) - { - this.buttonBar = Ext4.create('Ext.toolbar.Toolbar', { - dock: 'bottom', - ui: 'footer', - padding: 0, - style : 'background-color: transparent;', - defaults: {width: 75}, - items: [this.getSaveButton(), this.getCancelButton()] - }); - } - - return this.buttonBar; - }, - - getSaveButton : function() - { - if (!this.saveButton) - { - this.saveButton = Ext4.create('Ext.button.Button', { - text: 'Save', - disabled: true, - hidden: this.disableEdit, - handler: this.saveAssaySchedule, - scope: this - }); - } - - return this.saveButton; - }, - - enableSaveButton : function() - { - this.setDirty(true); - this.getSaveButton().enable(); - }, - - getCancelButton : function() - { - if (!this.cancelButton) - { - this.cancelButton = Ext4.create('Ext.button.Button', { - text: this.disableEdit ? 'Done' : 'Cancel', - handler: this.goToReturnURL, - scope: this - }); - } - - return this.cancelButton; - }, - - saveAssaySchedule : function() - { - this.getEl().mask('Saving...'); - - var assays = [], errorMsg = []; - Ext4.each(this.getAssaysGrid().getStore().getRange(), function(record) - { - var recData = Ext4.clone(record.data); - - // drop any empty treatment rows that were just added - var hasData = LABKEY.VaccineDesign.Utils.modelHasData(recData, LABKEY.VaccineDesign.Assay.getFields()); - if (hasData) - { - var sampleQuantity = Number(recData['SampleQuantity']); - if (isNaN(sampleQuantity) || sampleQuantity < 0) - errorMsg.push('Assay sample quantity value must be a positive number: ' + recData['SampleQuantity'] + '.'); - else - assays.push(recData); - } - }, this); - - if (errorMsg.length > 0) - { - this.onFailure(errorMsg.join('
    ')); - return; - } - - LABKEY.Ajax.request({ - url : LABKEY.ActionURL.buildURL('study-design', 'updateAssaySchedule.api'), - method : 'POST', - jsonData: { - assays: assays, - assayPlan: this.getAssayPlanTextArea().getValue() - }, - scope: this, - success: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.success) - this.goToReturnURL(); - else - this.onFailure(); - }, - failure: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.errors) - this.onFailure(Ext4.Array.pluck(resp.errors, 'message').join('
    ')); - else - this.onFailure(resp.exception); - } - }); - }, - - goToReturnURL : function() - { - this.setDirty(false); - window.location = this.returnUrl; - }, - - onFailure : function(text) - { - Ext4.Msg.show({ - title: 'Error', - msg: text || 'Unknown error occurred.', - icon: Ext4.Msg.ERROR, - buttons: Ext4.Msg.OK - }); - - this.getEl().unmask(); - }, - - setDirty : function(dirty) - { - this.dirty = dirty; - LABKEY.Utils.signalWebDriverTest("treatmentScheduleDirty", dirty); - }, - - isDirty : function() - { - return this.dirty; - }, - - beforeUnload : function() - { - if (!this.disableEdit && this.isDirty()) - return 'Please save your changes.'; - } -}); - -Ext4.define('LABKEY.VaccineDesign.AssaysGrid', { - extend : 'LABKEY.VaccineDesign.BaseDataViewAddVisit', - - cls : 'study-vaccine-design vaccine-design-assays', - - mainTitle : 'Assay Schedule', - - width : 620, - - studyDesignQueryNames : ['StudyDesignAssays', 'StudyDesignLabs', 'StudyDesignSampleTypes', 'StudyDesignUnits', 'Location', 'DataSets'], - - visitNoun : 'Visit', - - useAlternateLookupFields : false, - - //Override - getStore : function() - { - if (!this.store) - { - this.store = Ext4.create('Ext.data.Store', { - storeId : 'AssaysGridStore', - pageSize : 100000, // need to explicitly set otherwise it defaults to 25 - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL('query', 'selectRows.api', null, { - 'schemaName' : 'study', - 'query.queryName' : 'assayspecimen' - }), - reader: { - type: 'json', - root: 'rows' - } - }, - sorters: [{ property: 'AssayName', direction: 'ASC' }], - autoLoad: true, - listeners: { - scope: this, - load: this.getVisitStore - } - }); - } - - return this.store; - }, - - getVisitStore : function() - { - if (!this.visitStore) - { - this.visitStore = Ext4.create('Ext.data.Store', { - model : 'LABKEY.VaccineDesign.Visit', - pageSize : 100000, // need to explicitly set otherwise it defaults to 25 - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL('query', 'selectRows.api', null, { - 'schemaName' : 'study', - 'query.queryName' : 'visit' - }), - reader: { - type: 'json', - root: 'rows' - } - }, - sorters: [{ property: 'DisplayOrder', direction: 'ASC' }, { property: 'SequenceNumMin', direction: 'ASC' }], - autoLoad: true, - listeners: { - scope: this, - load: this.getAssaySpecimenVisitStore - } - }); - } - - return this.visitStore; - }, - - getAssaySpecimenVisitStore : function() - { - if (!this.assaySpecimenVisitStore) - { - this.assaySpecimenVisitStore = Ext4.create('Ext4.data.Store', { - storeId : 'AssaySpecimenVisitStore', - model : 'LABKEY.VaccineDesign.AssaySpecimenVisit', - pageSize : 100000, // need to explicitly set otherwise it defaults to 25 - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL('query', 'selectRows.api', null, { - 'schemaName' : 'study', - 'query.queryName' : 'AssaySpecimenVisit' - }), - reader: { - type: 'json', - root: 'rows' - } - }, - autoLoad: true, - listeners: { - scope: this, - load: function (store, records) - { - var includedVisits = []; - - // stash the visit mapping information attached to each record in the assay store - Ext4.each(records, function(record) - { - var assayRecord = this.getStore().findRecord('RowId', record.get('AssaySpecimenId')); - if (assayRecord != null) - { - var visitMap = assayRecord.get('VisitMap') || []; - visitMap.push(Ext4.clone(record.data)); - assayRecord.set('VisitMap', visitMap); - - includedVisits.push(record.get('VisitId')); - } - }, this); - - var includedVisits = Ext4.Array.unique(includedVisits); - Ext4.each(this.getVisitStore().getRange(), function(visit) - { - var included = includedVisits.indexOf(visit.get('RowId')) > -1; - visit.set('Included', included); - }, this); - - this.add(this.getDataView()); - this.fireEvent('loadcomplete', this); - } - } - }); - } - - return this.assaySpecimenVisitStore; - }, - - //Override - loadDataViewStore : function() - { - // just call getStore here to initial the load, we will add the DataView - // and fire the loadcomplete event after all of the stores for this page are done loading - this.getStore(); - }, - - columnHasData : function(dataIndex) - { - var recordsDataArr = Ext4.Array.pluck(this.getStore().getRange(), 'data'), - colDataArr = Ext4.Array.pluck(recordsDataArr, dataIndex); - - for (var i = 0; i < colDataArr.length; i++) - { - if ((Ext4.isNumber(colDataArr[i]) && colDataArr[i] > 0) || (Ext4.isString(colDataArr[i]) && colDataArr[i] != '')) - return true; - } - - return false; - }, - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - var width = 0; // add to the running width as we go through which columns to show in the config - var columnConfigs = []; - - var assayNameEditorConfig = LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('AssayName', 185, 'StudyDesignAssays'); - assayNameEditorConfig.editable = true; // Rho use-case - - columnConfigs.push({ - label: 'Assay Name', - width: 200, - dataIndex: 'AssayName', - required: true, - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: assayNameEditorConfig - }); - width += 200; - - columnConfigs.push({ - label: 'Dataset', - width: 200, - dataIndex: 'DataSet', - queryName: 'DataSets', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('DataSet', 185, 'DataSets', undefined, 'Label', 'DataSetId') - }); - width += 200; - - var hidden = this.disableEdit && !this.columnHasData('Description'); - columnConfigs.push({ - label: 'Description', - width: 200, - hidden: hidden, - dataIndex: 'Description', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Description', 185) - }); - if (!hidden) { - width += 200; - } - - if (this.useAlternateLookupFields) - { - hidden = this.disableEdit && !this.columnHasData('Source'); - columnConfigs.push({ - label: 'Source', - width: 60, - hidden: hidden, - dataIndex: 'Source', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Source', 45) - }); - if (!hidden) { - width += 60; - } - - hidden = this.disableEdit && !this.columnHasData('LocationId'); - columnConfigs.push({ - label: 'Location', - width: 140, - hidden: hidden, - dataIndex: 'LocationId', - queryName: 'Location', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('LocationId', 125, 'Location', undefined, 'Label', 'RowId') - }); - if (!hidden) { - width += 140; - } - - hidden = this.disableEdit && !this.columnHasData('TubeType'); - columnConfigs.push({ - label: 'TubeType', - width: 200, - hidden: hidden, - dataIndex: 'TubeType', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('TubeType', 185) - }); - if (!hidden) { - width += 200; - } - } - else - { - hidden = this.disableEdit && !this.columnHasData('Lab'); - columnConfigs.push({ - label: 'Lab', - width: 140, - hidden: hidden, - dataIndex: 'Lab', - queryName: 'StudyDesignLabs', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Lab', 125, 'StudyDesignLabs') - }); - if (!hidden) { - width += 140; - } - - hidden = this.disableEdit && !this.columnHasData('SampleType'); - columnConfigs.push({ - label: 'Sample Type', - width: 140, - hidden: hidden, - dataIndex: 'SampleType', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('SampleType', 125, 'StudyDesignSampleTypes', undefined, 'Name') - }); - if (!hidden) { - width += 140; - } - - hidden = this.disableEdit && !this.columnHasData('SampleQuantity'); - columnConfigs.push({ - label: 'Sample Quantity', - width: 140, - hidden: hidden, - dataIndex: 'SampleQuantity', - editorType: 'Ext.form.field.Number', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignNumberConfig('SampleQuantity', 125, 2) - }); - if (!hidden) { - width += 140; - } - - hidden = this.disableEdit && !this.columnHasData('SampleUnits'); - columnConfigs.push({ - label: 'Sample Units', - width: 140, - hidden: hidden, - dataIndex: 'SampleUnits', - queryName: 'StudyDesignUnits', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('SampleUnits', 125, 'StudyDesignUnits') - }); - if (!hidden) { - width += 140; - } - } - - var visitConfigs = this.getVisitColumnConfigs(); - - // update the width based on the number of visit columns - width += (Math.max(2, visitConfigs.length) * 75); - this.setWidth(width); - - // update the outer panel width if necessary - var outerPanel = this.up('panel'); - if (outerPanel != null) - outerPanel.setWidth(Math.max(width, 750)); - - this.columnConfigs = columnConfigs.concat(visitConfigs); - } - - return this.columnConfigs; - }, - - getVisitColumnConfigs : function() - { - var visitConfigs = []; - - Ext4.each(this.getVisitStore().getRange(), function(visit) - { - if (visit.get('Included')) - { - visitConfigs.push({ - label: visit.get('Label') || visit.get('SequenceNumMin'), - width: 75, - dataIndex: 'VisitMap', - dataIndexArrFilterProp: 'VisitId', - dataIndexArrFilterValue: visit.get('RowId'), - editorType: 'Ext.form.field.Checkbox', - editorConfig: { - hideFieldLabel: true, - name: 'VisitMap' - } - }); - } - }, this); - - if (visitConfigs.length == 0 && !this.disableEdit) - { - visitConfigs.push({ - label: 'No ' + this.visitNoun + 's Defined', - displayValue: '', - width: 160 - }); - } - - return visitConfigs; - }, - - //Override - getCurrentCellValue : function(column, record, dataIndex, outerDataIndex, subgridIndex) - { - var value = this.callParent([column, record, dataIndex, outerDataIndex, subgridIndex]); - - if (dataIndex == 'VisitMap' && Ext4.isArray(value)) - { - var matchingIndex = LABKEY.VaccineDesign.Utils.getMatchingRowIndexFromArray(value, column.dataIndexArrFilterProp, column.dataIndexArrFilterValue); - return matchingIndex > -1; - } - else if ((dataIndex == 'SampleQuantity' || dataIndex == 'LocationId') || dataIndex == 'DataSet' && value == 0) - { - return null; - } - - return value; - }, - - //Override - updateStoreRecordValue : function(record, column, newValue, field) - { - // special case for editing the value of one of the pivot visit columns - if (column.dataIndex == 'VisitMap') - { - var visitMapArr = record.get(column.dataIndex); - if (!Ext4.isArray(visitMapArr)) - { - visitMapArr = []; - record.set(column.dataIndex, visitMapArr); - } - - var matchingIndex = LABKEY.VaccineDesign.Utils.getMatchingRowIndexFromArray(visitMapArr, column.dataIndexArrFilterProp, column.dataIndexArrFilterValue); - - if (newValue) - visitMapArr.push({VisitId: column.dataIndexArrFilterValue}); - else - Ext4.Array.splice(visitMapArr, matchingIndex, 1); - - this.fireEvent('celledited', this, 'VisitMap', visitMapArr); - } - else - { - this.callParent([record, column, newValue]); - } - }, - - //Override - getNewModelInstance : function() - { - var newAssay = LABKEY.VaccineDesign.Assay.create(); - newAssay.set('VisitMap', []); - return newAssay; - }, - - //Override - getDeleteConfirmationMsg : function() - { - return 'Are you sure you want to delete the selected assay configuration? ' - + 'Note: this will also delete all related visit mapping information.'; - } -}); diff --git a/studydesign/webapp/study/vaccineDesign/BaseDataView.js b/studydesign/webapp/study/vaccineDesign/BaseDataView.js deleted file mode 100644 index d01c5f92ea2..00000000000 --- a/studydesign/webapp/study/vaccineDesign/BaseDataView.js +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -Ext4.define('LABKEY.VaccineDesign.BaseDataView', { - - extend : 'Ext.panel.Panel', - - cls : 'study-vaccine-design', - - border : false, - - mainTitle : null, - - studyDesignQueryNames : null, - - // for a DataSpace project, some scenarios don't make sense to allow insert/update - disableEdit : false, - - DELETE_ICON_CLS : 'fa fa-trash', - ADD_ICON_CLS : 'fa fa-plus-circle', - - constructor : function(config) - { - this.callParent([config]); - this.addEvents('dirtychange', 'loadcomplete', 'celledited', 'beforerowdeleted', 'renderviewcomplete'); - }, - - initComponent : function() - { - this.items = [ - this.getMainTitle() - // Note: this.getDataView() will be added after the store loads in this.loadDataViewStore() - ]; - - // Pre-load the study design lookup queries that will be used in dropdowns for this page. - // Note: these stores are also used for getting display values in the data view XTempalte so don't - // bind the data view store until they are all loaded. - if (Ext4.isArray(this.studyDesignQueryNames) && this.studyDesignQueryNames.length > 0) - { - var loadCounter = 0; - Ext4.each(this.studyDesignQueryNames, function(queryName) - { - var studyDesignStore = LABKEY.VaccineDesign.Utils.getStudyDesignStore(queryName); - studyDesignStore.on('load', function() - { - loadCounter++; - - if (loadCounter == this.studyDesignQueryNames.length) - this.loadDataViewStore(); - }, this); - }, this); - } - else - { - this.loadDataViewStore(); - } - - this.fireRenderCompleteTask = new Ext4.util.DelayedTask(function() { - this.fireEvent('renderviewcomplete', this); - }, this); - - // add a single event listener to focus the first input field on the initial render - this.on('renderviewcomplete', function() { - this.giveCellInputFocus('table.outer tr.data-row:first td.cell-value:first input', true); - LABKEY.Utils.signalWebDriverTest("VaccineDesign_renderviewcomplete"); - }, this, {single: true}); - - this.callParent(); - }, - - getMainTitle : function() - { - if (!this.mainTitleCmp && this.mainTitle != null) - { - this.mainTitleCmp = Ext4.create('Ext.Component', { - html: '
    ' + Ext4.util.Format.htmlEncode(this.mainTitle) + '
    ' - }); - } - - return this.mainTitleCmp; - }, - - getDataView : function() - { - if (!this.dataView) - { - this.dataView = Ext4.create('Ext.view.View', { - tpl: this.getDataViewTpl(), - cls: 'table-responsive', - store: this.getStore(), - itemSelector: 'tr.data-row', - disableSelection: true, - setTemplate: function(newTpl) - { - this.tpl = newTpl; - this.refresh(); - } - }); - - this.dataView.on('itemclick', this.onDataViewItemClick, this); - this.dataView.on('refresh', this.onDataViewRefresh, this, {buffer: 250}); - } - - return this.dataView; - }, - - getDataViewTpl : function() - { - var showEdit = !this.disableEdit, - tdCls = !showEdit ? 'cell-display' : 'cell-value', - tplArr = [], - columns = this.getColumnConfigs(); - - tplArr.push(''); - tplArr = tplArr.concat(this.getTableHeaderRowTpl(columns)); - - // data rows - tplArr.push(''); - tplArr.push(''); - if (showEdit) - tplArr.push(''); - Ext4.each(columns, function(column) - { - if (Ext4.isString(column.dataIndex) && !column.hidden) - { - var checkMissingReqTpl = column.required ? ' {[this.checkMissingRequired(values, "' + column.dataIndex + '")]}' : '', - tdTpl = ''; - - if (Ext4.isDefined(column.dataIndexArrFilterValue)) - tdTpl = tdTpl.substring(0, tdTpl.length -1) + ' data-filter-value="' + column.dataIndexArrFilterValue + '">'; - - // decide which of the td tpls to use based on the column definition - if (Ext4.isObject(column.subgridConfig) && Ext4.isArray(column.subgridConfig.columns)) - { - tplArr = tplArr.concat(this.getSubGridTpl(column.dataIndex, column.subgridConfig.columns)); - } - else if (Ext4.isString(column.queryName)) - { - tplArr.push(tdTpl + (!showEdit ? '{[this.getLabelFromStore(values["' + column.dataIndex + '"], "' + column.queryName + '")]}' : '') + tdCloseTpl); - } - else if (Ext4.isString(column.lookupStoreId) && Ext4.isDefined(column.dataIndexArrFilterValue)) - { - var valTpl = ''; - if (!showEdit) - { - valTpl = '{[this.getDisplayValue(values["' + column.dataIndex + '"], ' - + '"' + column.dataIndexArrFilterProp + '", "' + column.dataIndexArrFilterValue + '", ' - + '"' + column.dataIndexArrValue + '", "' + column.lookupStoreId + '")]}'; - } - - tplArr.push(tdTpl + valTpl + tdCloseTpl); - } - else if (column.editorType == 'Ext.form.field.Checkbox') - { - var valTpl = ''; - if (!showEdit) - { - valTpl = '{[this.getDisplayValue(values["' + column.dataIndex + '"], ' - + '"' + column.dataIndexArrFilterProp + '", ' - + '"' + column.dataIndexArrFilterValue + '", ' - + '"checkbox")]}'; - } - - tdTpl = tdTpl.substring(0, tdTpl.length -1) + ' style="text-align: center;">'; - tplArr.push(tdTpl + valTpl + tdCloseTpl); - } - else - { - tplArr.push(tdTpl + (!showEdit ? '{[this.getDisplayValue(values["' + column.dataIndex + '"])]}' : '') + tdCloseTpl); - } - } - else if (Ext4.isString(column.displayValue)) - { - tplArr.push(''); - } - }, this); - tplArr.push(''); - tplArr.push(''); - - tplArr = tplArr.concat(this.getEmptyTableTpl(columns)); - tplArr = tplArr.concat(this.getAddNewRowTpl(columns)); - tplArr.push('
    ', - tdCloseTpl = '' + column.displayValue + '
    '); - - tplArr.push({ - getDisplayValue : function(val, arrPropFilterName, arrPropFilterVal, arrPropDisplayField, lookupStoreId) - { - // allow showing a certain filtered row from an array - if (Ext4.isDefined(arrPropDisplayField)) - { - var matchingIndex = LABKEY.VaccineDesign.Utils.getMatchingRowIndexFromArray(val, arrPropFilterName, arrPropFilterVal); - if (matchingIndex > -1 && Ext4.isObject(val[matchingIndex])) - { - if (arrPropDisplayField == 'checkbox') - return '✓'; - else - val = val[matchingIndex][arrPropDisplayField]; - } - else - val = ''; - } - - // if we have a specific lookupStoreId, get the label value from the matching RowId record in that store - if (Ext4.isDefined(lookupStoreId) && val != null && val != '') - { - var store = Ext4.getStore(lookupStoreId); - if (store != null) - { - var record = store.findRecord('RowId', val); - if (record != null) - val = record.get('Label'); - } - } - - if (Ext4.isNumber(val)) - { - return val == 0 ? '' : val; - } - else - { - // need to htmlEncode and then handle newlines in multiline text fields (i.e. Treatment/Description) - val = Ext4.util.Format.htmlEncode(val); - val = val.replace(/\n/g, '
    '); - } - - return val; - }, - - getLabelFromStore : function(val, queryName) - { - if (val != null && val != '') - val = LABKEY.VaccineDesign.Utils.getLabelFromStore(queryName, val); - - if (Ext4.isNumber(val)) - return val == 0 ? '' : val; - else - return Ext4.util.Format.htmlEncode(val); - }, - - checkMissingRequired : function(values, dataIndex) - { - if (values[dataIndex] == null || values[dataIndex] == '') - return ' missing-required'; - - return ''; - } - }); - - return new Ext4.XTemplate(tplArr); - }, - - getSubGridTpl : function(dataIndex, columns) - { - var showEdit = !this.disableEdit, - tdCls = showEdit ? 'cell-value' : 'cell-display', - tplArr = []; - - tplArr.push(''); - - // only show the subgrid if we are allowing edits of if it has at least one row - tplArr.push(''); - - tplArr.push(''); - tplArr = tplArr.concat(this.getTableHeaderRowTpl(columns)); - - // data rows - tplArr.push(''); - tplArr.push(''); - if (showEdit) - { - tplArr.push(''); - } - Ext4.each(columns, function(column) - { - if (Ext4.isString(column.dataIndex)) - { - var checkMissingReqTpl = column.required ? ' {[this.checkMissingRequired(values, "' + column.dataIndex + '")]}' : '', - tdTpl = ''; - - if (Ext4.isString(column.queryName)) - tplArr.push(tdTpl + (!showEdit ? '{[this.getLabelFromStore(values["' + column.dataIndex + '"], "' + column.queryName + '")]}' : '') + tdCloseTpl); - else - tplArr.push(tdTpl + (!showEdit ? '{' + column.dataIndex + ':htmlEncode}' : '') + tdCloseTpl); - } - }, this); - tplArr.push(''); - tplArr.push(''); - - tplArr = tplArr.concat(this.getAddNewRowTpl(columns, dataIndex)); - tplArr.push('
    '); - tplArr.push(''); - tplArr.push('', - tdCloseTpl = '
    '); - tplArr.push('
    '); - tplArr.push(''); - - return tplArr; - }, - - getTableHeaderRowTpl : function(columns) - { - var tplArr = []; - - tplArr.push(''); - if (!this.disableEdit) - tplArr.push(' '); - Ext4.each(columns, function(column) - { - if (!column.hidden) - tplArr.push('' + Ext4.util.Format.htmlEncode(column.label) + ''); - }, this); - tplArr.push(''); - - return tplArr; - }, - - getEmptyTableTpl : function(columns) - { - var tplArr = []; - - if (this.disableEdit) - { - tplArr.push(''); - tplArr.push(''); - tplArr.push('No data to show.'); - tplArr.push(''); - tplArr.push(''); - } - - return tplArr; - }, - - getAddNewRowTpl : function(columns, dataIndex) - { - var tplArr = []; - - if (!this.disableEdit) - { - tplArr.push(''); - tplArr.push(' '); - tplArr.push(''); - if (Ext4.isString(dataIndex)) - tplArr.push(' Add new row'); - else - tplArr.push(' Add new row'); - tplArr.push(''); - tplArr.push(''); - } - - return tplArr; - }, - - onDataViewItemClick : function(view, record, item, index, event) - { - if (!this.disableEdit) - { - // handle click on trashcan icon to delete row - if (event.target.getAttribute('class') == this.DELETE_ICON_CLS) - { - if (event.target.hasAttribute('outer-index')) - { - this.removeOuterRecord(this.mainTitle, record); - } - // handle click on trashcan icon for outer grid - else if (event.target.hasAttribute('subgrid-data-index') && event.target.hasAttribute('subgrid-index')) - { - this.confirmRemoveSubgridRecord(event.target, record); - } - } - } - }, - - createNewCellEditField : function(target, record, index) - { - var dataIndex = target.getAttribute('data-index'), - dataFilterValue = target.getAttribute('data-filter-value'), - outerDataIndex = target.getAttribute('outer-data-index'), - subgridIndex = Number(target.getAttribute('subgrid-index')), - column = this.getColumnConfig(dataIndex, dataFilterValue, outerDataIndex), - editor = this.getColumnEditorConfig(column); - - if (editor != null) - { - var config = { - renderTo: target, - required: column.required, - storeIndex: index, - dataFilterValue: dataFilterValue, - outerDataIndex: outerDataIndex, - subgridIndex: subgridIndex - }; - - var currentValue = this.getCurrentCellValue(column, record, dataIndex, outerDataIndex, subgridIndex); - if (editor.type == 'Ext.form.field.Checkbox') - config.checked = currentValue; - else - config.value = currentValue; - - if (column.isTreatmentLookup) { - var treatmentLabel = this.getTreatmentCellDisplayValue(currentValue, column.lookupStoreId); - config.value = treatmentLabel; - config.treatmentId = currentValue; - } - - // create a new form field to place in the td cell - var field = Ext4.create(editor.type, Ext4.apply(editor.config, config)); - - // add listeners for when to apply the updated value and clear the input field - field.on('change', this.updateStoreValueForCellEdit, this, {buffer: 500}); - } - }, - - getCurrentCellValue : function(column, record, dataIndex, outerDataIndex, subgridIndex) - { - return Ext4.isString(outerDataIndex) ? record.get(outerDataIndex)[subgridIndex][dataIndex] : record.get(dataIndex); - }, - - updateStoreValueForCellEdit : function(field) - { - var fieldName = field.getName(), - newValue = field.getValue(), - index = field.storeIndex, - record = this.getStore().getAt(index), - dataFilterValue = field.dataFilterValue, - outerDataIndex = field.outerDataIndex, - subgridIndex = Number(field.subgridIndex); - - // suspend events on cell update so that we don't re-render the dataview - this.getStore().suspendEvents(); - - if (Ext4.isString(outerDataIndex)) - { - if (!isNaN(subgridIndex) && Ext4.isArray(record.get(outerDataIndex))) - this.updateSubgridRecordValue(record, outerDataIndex, subgridIndex, fieldName, newValue); - } - else - { - var column = this.getColumnConfig(fieldName, dataFilterValue, outerDataIndex); - this.updateStoreRecordValue(record, column, newValue, field); - } - - // update the missing-required cls based on the new field value - if (field.required) - { - if (newValue == null || newValue == '') - Ext4.get(field.renderTo).addCls('missing-required'); - else - Ext4.get(field.renderTo).removeCls('missing-required'); - } - - // resume store events so that adding and deleting will re-render the dataview - this.getStore().resumeEvents(); - }, - - updateSubgridRecordValue : function(record, outerDataIndex, subgridIndex, fieldName, newValue) - { - if (Ext4.isString(newValue)) - newValue.trim(); - - record.get(outerDataIndex)[subgridIndex][fieldName] = newValue; - this.fireEvent('celledited', this, fieldName, newValue); - }, - - updateStoreRecordValue : function(record, column, newValue, field) - { - if (Ext4.isString(newValue)) - newValue.trim(); - - record.set(column.dataIndex, newValue); - this.fireEvent('celledited', this, column.dataIndex, newValue); - }, - - removeOuterRecord : function(title, record) - { - var msg = this.getDeleteConfirmationMsg() != null ? this.getDeleteConfirmationMsg() : 'Are you sure you want to delete the selected row?'; - - Ext4.Msg.confirm('Confirm Delete: ' + title, msg, function(btn) - { - if (btn == 'yes') - { - this.fireEvent('beforerowdeleted', this, record); - - // suspend events on remove so that we don't re-render the dataview twice - this.getStore().suspendEvents(); - this.getStore().remove(record); - this.getStore().resumeEvents(); - this.refresh(true); - } - }, this); - }, - - confirmRemoveSubgridRecord : function(target, record) - { - var subgridDataIndex = target.getAttribute('subgrid-data-index'), - subgridArr = record.get(subgridDataIndex); - - if (Ext4.isArray(subgridArr)) - { - Ext4.Msg.confirm('Confirm Delete: ' + subgridDataIndex, 'Are you sure you want to delete the selected row?', function(btn) - { - if (btn == 'yes') - { - this.removeSubgridRecord(target, record); - this.refresh(true); - } - }, this); - } - }, - - removeSubgridRecord : function(target, record) - { - var subgridDataIndex = target.getAttribute('subgrid-data-index'), - subgridArr = record.get(subgridDataIndex); - - subgridArr.splice(target.getAttribute('subgrid-index'), 1); - }, - - onDataViewRefresh : function(view) - { - this.attachCellEditors(view); - this.attachAddRowListeners(view); - this.doLayout(); - this.fireRenderCompleteTask.delay(250); - }, - - attachCellEditors : function(view) - { - // attach cell editors for each of the store records (i.e. tr.row elements in the table) - var index = 0; - Ext4.each(this.getStore().getRange(), function(record) - { - var targetCellEls = Ext4.DomQuery.select('tr.data-row:nth(' + (index+1) + ') td.cell-value', view.getEl().dom); - Ext4.each(targetCellEls, function(targetCell) - { - this.createNewCellEditField(targetCell, record, index); - }, this); - - index++; - }, this); - }, - - attachAddRowListeners : function(view) - { - var addIconEls = Ext4.DomQuery.select('i.add-new-row', view.getEl().dom); - - Ext4.each(addIconEls, function(addIconEl) - { - if (addIconEl.hasAttribute('data-index')) - Ext4.get(addIconEl).on('click', this.addNewSubgridRow, this); - else - Ext4.get(addIconEl).on('click', this.addNewOuterRow, this); - }, this); - }, - - addNewOuterRow : function() - { - // suspend events on insert so that we don't re-render the dataview twice - this.getStore().suspendEvents(); - this.getStore().insert(this.getStore().getCount(), this.getNewModelInstance()); - this.getStore().resumeEvents(); - - // on refresh, call to give focus to the first column of the new row - this.on('renderviewcomplete', function(){ - this.giveCellInputFocus('table.outer tr.data-row:last td.cell-value:first input'); - }, this, {single: true}); - - this.refresh(); - }, - - addNewSubgridRow : function(event, target) - { - var dataIndex = target.getAttribute('data-index'), - rowIndex = Number(target.getAttribute('outer-index')); - - if (Ext4.isString(dataIndex) && Ext4.isNumber(rowIndex)) - { - var record = this.getStore().getAt(rowIndex), - dataIndexArr = record.get(dataIndex); - - if (Ext4.isArray(dataIndexArr)) - record.set(dataIndex, dataIndexArr.concat([{}])); - - // on refresh, call to give focus to the first column of the new row - this.on('renderviewcomplete', function(){ - var selector = 'table.subgrid-' + dataIndex + ':nth(' + (rowIndex+1) + ') tr.subrow:last td.cell-value:first input'; - this.giveCellInputFocus(selector); - }, this, {single: true}); - - this.refresh(); - } - }, - - giveCellInputFocus : function(selector, queryFullPage) - { - var cellInputField = Ext4.DomQuery.selectNode(selector, queryFullPage ? undefined : this.getDataView().getEl().dom); - if (cellInputField) - cellInputField.focus(); - }, - - refresh : function(hasChanges) - { - this.getDataView().refresh(); - - if (hasChanges) - this.fireEvent('dirtychange', this); - }, - - getColumnConfig : function(dataIndex, dataFilterValue, parentDataIndex) - { - var columns = this.getColumnConfigs(), matchingColumn = null; - - // if the parentDataIndex is defined, then we are looking for the subgrid column editor config - if (Ext4.isString(parentDataIndex)) - { - var colIndex = Ext4.pluck(columns, 'dataIndex').indexOf(parentDataIndex); - if (colIndex > -1 && columns[colIndex].hasOwnProperty('subgridConfig') && Ext4.isArray(columns[colIndex].subgridConfig.columns)) - columns = columns[colIndex].subgridConfig.columns; - else - return null; - } - - Ext4.each(columns, function(column) - { - if (column.dataIndex == dataIndex && (!Ext4.isDefined(dataFilterValue) || column.dataIndexArrFilterValue == dataFilterValue)) - { - matchingColumn = column; - return false; // break; - } - }, this); - - return matchingColumn; - }, - - getColumnEditorConfig : function(column) - { - if (column != null && column.hasOwnProperty('editorType') && column.hasOwnProperty('editorConfig')) - { - return { - type: column.editorType, - config: Ext4.isFunction(column.editorConfig) ? column.editorConfig.call(this) : column.editorConfig - }; - } - - return null; - }, - - loadDataViewStore : function() - { - // since some tables might need information from the store, wait to add the data view until the store loads - this.getStore().on('load', function() { - this.add(this.getDataView()); - this.fireEvent('loadcomplete', this); - }, this, {single: true}); - }, - - getStore : function() - { - throw "getStore must be overridden in subclass"; - }, - - getNewModelInstance : function() - { - throw "getNewModelInstance must be overridden in subclass"; - }, - - getColumnConfigs : function() - { - throw "getColumnConfigs must be overridden in subclass"; - }, - - getDeleteConfirmationMsg : function() - { - return null; - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/BaseDataViewAddVisit.js b/studydesign/webapp/study/vaccineDesign/BaseDataViewAddVisit.js deleted file mode 100644 index dabfda02934..00000000000 --- a/studydesign/webapp/study/vaccineDesign/BaseDataViewAddVisit.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -Ext4.define('LABKEY.VaccineDesign.BaseDataViewAddVisit', { - extend: 'LABKEY.VaccineDesign.BaseDataView', - - getVisitStore : function() - { - throw new Error("getVisitStore must be overridden in subclass"); - }, - - //Override - getAddNewRowTpl : function(columns, dataIndex) - { - var tplArr = []; - - if (!this.disableEdit) - { - tplArr.push(''); - tplArr.push(' '); - tplArr.push(''); - tplArr.push(' Add new row   '); - tplArr.push(' Add new ' + this.visitNoun.toLowerCase() + ''); - tplArr.push(''); - tplArr.push(''); - } - - return tplArr; - }, - - //Override - attachAddRowListeners : function(view) - { - this.callParent([view]); - - var addIconEls = Ext4.DomQuery.select('i.add-visit-column', view.getEl().dom); - - Ext4.each(addIconEls, function(addIconEl) - { - Ext4.get(addIconEl).on('click', this.addNewVisitColumn, this); - }, this); - }, - - addNewVisitColumn : function() - { - var win = Ext4.create('LABKEY.VaccineDesign.VisitWindow', { - title: 'Add ' + this.visitNoun, - visitNoun: this.visitNoun, - visitStore: this.getVisitStore(), - listeners: { - scope: this, - closewindow: function(){ - win.close(); - }, - selectexistingvisit: function(w, visitId){ - win.close(); - - // if the 'ALL' option was selected, show all of the visits in the table - if (visitId == 'ALL') - { - Ext4.each(this.getVisitStore().getRange(), function(record) - { - record.set('Included', true); - }, this); - } - // set the selected visit to be included - else - { - this.getVisitStore().findRecord('RowId', visitId).set('Included', true); - } - - this.updateDataViewTemplate(); - }, - newvisitcreated: function(w, newVisitData){ - win.close(); - - // add the new visit to the store - var newVisitRec = LABKEY.VaccineDesign.Visit.create(newVisitData); - newVisitRec.set('Included', true); - this.getVisitStore().add(newVisitRec); - - this.updateDataViewTemplate(); - } - } - }); - - win.show(); - }, - - updateDataViewTemplate : function() - { - // explicitly clear the column configs so the new visit column will be added - this.columnConfigs = null; - this.getDataView().setTemplate(this.getDataViewTpl()); - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/Models.js b/studydesign/webapp/study/vaccineDesign/Models.js deleted file mode 100644 index 209772bdc2e..00000000000 --- a/studydesign/webapp/study/vaccineDesign/Models.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.Product', { - extend : 'Ext.data.Model', - idgen: 'sequential', - fields : [ - {name : 'RowId', defaultValue: undefined}, - {name : 'Label', type : 'string'}, - {name : 'Role', type : 'string'}, - {name : 'Type', type : 'string'}, - {name : 'Antigens', defaultValue: []}, - {name : 'DoseAndRoute', defaultValue: []} - ] -}); - -Ext4.define('LABKEY.VaccineDesign.Treatment', { - extend : 'Ext.data.Model', - idgen: 'sequential', - fields : [ - {name : 'RowId', defaultValue: undefined}, - {name : 'Label', type : 'string'}, - {name : 'Description', type : 'string'}, - {name : 'Immunogen', defaultValue: []}, - {name : 'Adjuvant', defaultValue: []}, - {name : 'Challenge', defaultValue: []} - ] -}); - -Ext4.define('LABKEY.VaccineDesign.Cohort', { - extend : 'Ext.data.Model', - idgen: 'sequential', - fields : [ - {name : 'RowId', defaultValue: undefined}, - {name : 'Label', type : 'string'}, - // the DataView XTemplate gets mad if this is defined as type 'int' - {name : 'SubjectCount', type : 'string'}, - {name : 'CanDelete', type : 'boolean'}, - {name : 'VisitMap', defaultValue: []} - ] -}); - -Ext4.define('LABKEY.VaccineDesign.Assay', { - extend : 'Ext.data.Model', - idgen: 'sequential', - fields : [ - {name : 'RowId', defaultValue: undefined}, - {name : 'AssayName', type : 'string'}, - {name : 'DataSet', type : 'int'}, - {name : 'Description', type : 'string'}, - {name : 'Lab', type : 'string'}, - {name : 'LocationId', type : 'int'}, - {name : 'SampleType', type : 'string'}, - {name : 'Source', type : 'string'}, - {name : 'TubeType', type : 'string'}, - {name : 'SampleQuantity', type : 'float'}, - {name : 'SampleUnits', type : 'string'}, - {name : 'VisitMap', defaultValue: []} - ] -}); - -Ext4.define('LABKEY.VaccineDesign.AssaySpecimenVisit', { - extend : 'Ext.data.Model', - fields : [ - {name : 'RowId', type : 'int'}, - {name : 'VisitId', type : 'int'}, - {name : 'AssaySpecimenId', type : 'int'} - ] -}); - -Ext4.define('LABKEY.VaccineDesign.Visit', { - extend : 'Ext.data.Model', - fields : [ - {name : 'RowId', type : 'int'}, - {name : 'Label', type : 'string'}, - {name : 'DisplayOrder', type : 'int'}, - {name : 'SequenceNumMin', type : 'numeric'}, - {name : 'Included', type : 'boolean'} - ] -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/StudyProducts.js b/studydesign/webapp/study/vaccineDesign/StudyProducts.js deleted file mode 100644 index 325173a94e3..00000000000 --- a/studydesign/webapp/study/vaccineDesign/StudyProducts.js +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.StudyProductsPanel', { - extend : 'Ext.panel.Panel', - - border : false, - - bodyStyle : 'background-color: transparent;', - - minWidth: 1350, - - disableEdit : true, - - dirty : false, - - returnUrl : null, - - initComponent : function() - { - this.items = [ - this.getImmunogensGrid(), - this.getAdjuvantGrid(), - this.getChallengesGrid(), - this.getButtonBar() - ]; - - this.callParent(); - - window.onbeforeunload = LABKEY.beforeunload(this.beforeUnload, this); - }, - - getImmunogensGrid : function() - { - if (!this.immunogenGrid) - { - this.immunogenGrid = Ext4.create('LABKEY.VaccineDesign.ImmunogensGrid', { - disableEdit: this.disableEdit - }); - - this.immunogenGrid.on('dirtychange', this.enableSaveButton, this); - this.immunogenGrid.on('celledited', this.enableSaveButton, this); - } - - return this.immunogenGrid; - }, - - getAdjuvantGrid : function() - { - if (!this.adjuvantGrid) - { - this.adjuvantGrid = Ext4.create('LABKEY.VaccineDesign.AdjuvantsGrid', { - padding: '20px 0', - disableEdit: this.disableEdit - }); - - this.adjuvantGrid.on('dirtychange', this.enableSaveButton, this); - this.adjuvantGrid.on('celledited', this.enableSaveButton, this); - } - - return this.adjuvantGrid; - }, - - getChallengesGrid : function() - { - if (!this.challengesGrid) - { - this.challengesGrid = Ext4.create('LABKEY.VaccineDesign.ChallengesGrid', { - padding: '20px 0', - disableEdit: this.disableEdit - }); - - this.challengesGrid.on('dirtychange', this.enableSaveButton, this); - this.challengesGrid.on('celledited', this.enableSaveButton, this); - } - - return this.challengesGrid; - }, - - getButtonBar : function() - { - if (!this.buttonBar) - { - this.buttonBar = Ext4.create('Ext.toolbar.Toolbar', { - dock: 'bottom', - ui: 'footer', - padding: 0, - style : 'background-color: transparent;', - defaults: {width: 75}, - items: [this.getSaveButton(), this.getCancelButton()] - }); - } - - return this.buttonBar; - }, - - getSaveButton : function() - { - if (!this.saveButton) - { - this.saveButton = Ext4.create('Ext.button.Button', { - text: 'Save', - disabled: true, - hidden: this.disableEdit, - handler: this.saveStudyProducts, - scope: this - }); - } - - return this.saveButton; - }, - - enableSaveButton : function() - { - this.setDirty(true); - this.getSaveButton().enable(); - }, - - getCancelButton : function() - { - if (!this.cancelButton) - { - this.cancelButton = Ext4.create('Ext.button.Button', { - text: this.disableEdit ? 'Done' : 'Cancel', - handler: this.goToReturnURL, - scope: this - }); - } - - return this.cancelButton; - }, - - saveStudyProducts : function() - { - var studyProducts = []; - - this.getEl().mask('Saving...'); - - Ext4.each(this.getImmunogensGrid().getStore().getRange(), function(record) - { - var recData = Ext4.clone(record.data); - - // drop any empty antigen rows that were just added - var antigenArr = []; - Ext4.each(recData['Antigens'], function(antigen) - { - if (Ext4.isDefined(antigen['RowId']) || LABKEY.VaccineDesign.Utils.objectHasData(antigen)) - antigenArr.push(antigen); - }, this); - recData['Antigens'] = antigenArr; - - // drop any empty rows that were just added - var hasData = recData['Label'] != '' || recData['Type'] != '' || recData['Antigens'].length > 0; - if (Ext4.isDefined(recData['RowId']) || hasData) - studyProducts.push(recData); - }, this); - - Ext4.each(this.getAdjuvantGrid().getStore().getRange(), function(record) - { - // drop any empty rows that were just added - if (Ext4.isDefined(record.get('RowId')) || record.get('Label') != '') - studyProducts.push(Ext4.clone(record.data)); - }, this); - - Ext4.each(this.getChallengesGrid().getStore().getRange(), function(record) - { - var hasData = record['Label'] != '' || record['Type'] != ''; - if (Ext4.isDefined(record.get('RowId')) || hasData) - studyProducts.push(Ext4.clone(record.data)); - }, this); - - LABKEY.Ajax.request({ - url : LABKEY.ActionURL.buildURL('study-design', 'updateStudyProducts.api'), - method : 'POST', - jsonData: { products: studyProducts }, - scope: this, - success: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.success) - this.goToReturnURL(); - else - this.onFailure(); - }, - failure: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.errors) - this.onFailure(Ext4.Array.pluck(resp.errors, 'message').join('
    ')); - else - this.onFailure(resp.exception); - } - }); - }, - - goToReturnURL : function() - { - this.setDirty(false); - window.location = this.returnUrl; - }, - - onFailure : function(text) - { - Ext4.Msg.show({ - title: 'Error', - msg: text || 'Unknown error occurred.', - icon: Ext4.Msg.ERROR, - buttons: Ext4.Msg.OK - }); - - this.getEl().unmask(); - }, - - setDirty : function(dirty) - { - this.dirty = dirty; - LABKEY.Utils.signalWebDriverTest("studyProductsDirty", dirty); - }, - - isDirty : function() - { - return this.dirty; - }, - - beforeUnload : function() - { - if (!this.disableEdit && this.isDirty()) - return 'Please save your changes.'; - } -}); - -Ext4.define('LABKEY.VaccineDesign.StudyProductsGrid', { - - extend : 'LABKEY.VaccineDesign.BaseDataView', - - filterRole : null, - - showDoseRoute : true, - - //Override - getStore : function() - { - if (!this.store) - { - this.store = Ext4.create('Ext.data.Store', { - model : 'LABKEY.VaccineDesign.Product', - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL("study-design", "getStudyProducts", null, {role: this.filterRole}), - reader: { - type: 'json', - root: 'products' - } - }, - sorters: [{ property: 'RowId', direction: 'ASC' }], - autoLoad: true - }); - } - - return this.store; - }, - - //Override - getNewModelInstance : function() - { - return LABKEY.VaccineDesign.Product.create({Role: this.filterRole}); - }, - - //Override - getDeleteConfirmationMsg : function() - { - return 'Are you sure you want to delete the selected study product? ' - + 'Note: if this study product is being used by any treatment definitions, ' - + 'those associations will also be deleted upon save.'; - } -}); - -Ext4.define('LABKEY.VaccineDesign.ImmunogensGrid', { - extend : 'LABKEY.VaccineDesign.StudyProductsGrid', - - cls : 'study-vaccine-design vaccine-design-immunogens', - - mainTitle : 'Immunogens', - - filterRole : 'Immunogen', - - studyDesignQueryNames : ['StudyDesignImmunogenTypes', 'StudyDesignGenes', 'StudyDesignSubTypes', 'StudyDesignRoutes'], - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - var width = 0; // add to the running width as we go through which columns to show in the config - - this.columnConfigs = [{ - label: 'Label', - width: 200, - dataIndex: 'Label', - required: true, - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Label', 185) - }, { - label: 'Type', - width: 200, - dataIndex: 'Type', - queryName: 'StudyDesignImmunogenTypes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Type', 185, 'StudyDesignImmunogenTypes') - },{ - label: 'HIV Antigens', - width: 600, - dataIndex: 'Antigens', - subgridConfig: { - columns: [{ - label: 'Gene', - width: 140, - dataIndex: 'Gene', - queryName: 'StudyDesignGenes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Gene', 125, 'StudyDesignGenes') - },{ - label: 'Subtype', - width: 140, - dataIndex: 'SubType', - queryName: 'StudyDesignSubTypes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('SubType', 125, 'StudyDesignSubTypes') - },{ - label: 'GenBank Id', - width: 150, - dataIndex: 'GenBankId', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('GenBankId', 135) - },{ - label: 'Sequence', - width: 150, - dataIndex: 'Sequence', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Sequence', 135) - }] - } - }]; - width += 1000; - - if (this.showDoseRoute) - { - this.columnConfigs.push({ - label: 'Doses and Routes', - width: 315, - dataIndex: 'DoseAndRoute', - subgridConfig: { - columns: [{ - label: 'Dose', - width: 140, - dataIndex: 'Dose', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Dose', 125) - },{ - label: 'Route', - width: 140, - dataIndex: 'Route', - queryName: 'StudyDesignRoutes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Route', 125, 'StudyDesignRoutes') - }] - } - }); - width += 315; - } - - this.setWidth(width); - } - - return this.columnConfigs; - } -}); - -Ext4.define('LABKEY.VaccineDesign.AdjuvantsGrid', { - extend : 'LABKEY.VaccineDesign.StudyProductsGrid', - - cls : 'study-vaccine-design vaccine-design-adjuvants', - - mainTitle : 'Adjuvants', - - filterRole : 'Adjuvant', - - studyDesignQueryNames : ['StudyDesignRoutes'], - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - var width = 0; // add to the running width as we go through which columns to show in the config - - this.columnConfigs = [{ - label: 'Label', - width: 200, - dataIndex: 'Label', - required: true, - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Label', 185) - }]; - width += 200; - - if (this.showDoseRoute) - { - this.columnConfigs.push({ - label: 'Doses and Routes', - width: 330, - dataIndex: 'DoseAndRoute', - subgridConfig: { - columns: [{ - label: 'Dose', - width: 140, - dataIndex: 'Dose', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Dose', 125) - }, { - label: 'Route', - width: 140, - dataIndex: 'Route', - queryName: 'StudyDesignRoutes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Route', 125, 'StudyDesignRoutes') - }] - } - }); - width += 330; - } - - this.setWidth(width); - } - - return this.columnConfigs; - } -}); - -Ext4.define('LABKEY.VaccineDesign.ChallengesGrid', { - extend : 'LABKEY.VaccineDesign.StudyProductsGrid', - - cls : 'study-vaccine-design vaccine-design-challenges', - - mainTitle : 'Challenges', - - filterRole : 'Challenge', - - studyDesignQueryNames : ['StudyDesignChallengeTypes', 'StudyDesignRoutes'], - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - var width = 0; // add to the running width as we go through which columns to show in the config - - this.columnConfigs = [{ - label: 'Label', - width: 200, - dataIndex: 'Label', - required: true, - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Label', 185) - }, { - label: 'Type', - width: 200, - dataIndex: 'Type', - queryName: 'StudyDesignChallengeTypes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Type', 185, 'StudyDesignChallengeTypes') - }]; - width += 400; - - if (this.showDoseRoute) - { - this.columnConfigs.push({ - label: 'Doses and Routes', - width: 330, - dataIndex: 'DoseAndRoute', - subgridConfig: { - columns: [{ - label: 'Dose', - width: 140, - dataIndex: 'Dose', - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Dose', 125) - }, { - label: 'Route', - width: 140, - dataIndex: 'Route', - queryName: 'StudyDesignRoutes', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('Route', 125, 'StudyDesignRoutes') - }] - } - }); - width += 330; - } - - this.setWidth(width); - } - - return this.columnConfigs; - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/TreatmentDialog.js b/studydesign/webapp/study/vaccineDesign/TreatmentDialog.js deleted file mode 100644 index 0b4f63df753..00000000000 --- a/studydesign/webapp/study/vaccineDesign/TreatmentDialog.js +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.TreatmentDialog', { - - extend: 'Ext.window.Window', - - bodyStyle: 'overflow-y: auto; padding: 10px 0;', - - listeners: { - resize: function (cmp) - { - cmp.doLayout(); - } - }, - - initComponent : function() - { - this.items = this.getForm(); - this.callParent(); - }, - - getForm : function() - { - if (!this.formPanel) { - this.formPanel = Ext4.create('Ext.form.Panel',{ - border : false, - layout : { - type : 'vbox', - align: 'stretch' - }, - fieldDefaults :{ - labelAlign : 'top', - labelWidth : 130 - }, - items : this.getFormItems(), - scope : this - }); - } - return this.formPanel; - }, - - getFormItems : function() { - var productRolesItems = {}, columns = []; - Ext4.each(this.productRoles, function(role){ - var checkedProducts = this.treatmentDetails ? this.treatmentDetails[role] : []; - productRolesItems[role] = []; - var values = this.getProductAndDoseRouteValues(role, checkedProducts); - Ext4.each(values, function(val){ - var checked = false; - Ext4.each(checkedProducts, function(product){ - if (product.ProductDoseRoute == val.ProductDoseRoute) { - checked = true; - return false; - } - }); - productRolesItems[role].push({ - boxLabel: Ext4.util.Format.htmlEncode(val.Label), - name: role, - inputValue: val.ProductDoseRoute, - productLabel: val.ProductLabel, - checked: checked, - cls: 'dialog-product-label', - listeners: { - render: function (cmp) - { - //tooltip - cmp.getEl().dom.title = val.Label; - } - } - }); - }, this); - }, this); - - Ext4.iterate(productRolesItems, function(key, val){ - var column = { - xtype: 'checkboxgroup', - fieldLabel: key, - labelStyle: 'font-weight: bold;', - colspan: 1, - columns: 1, - flex: 0.75, - height: 22 * val.length + 22, - style: 'margin-left: 20px;', - items: val - - }; - columns.push(column); - }); - return columns; - }, - - getProductAndDoseRouteValues : function(productRole, checkedProducts) - { - var data = []; - - Ext4.each(Ext4.getStore('Product').getRange(), function(product) - { - if (!product.get('RowId') || product.get('Role') != productRole) - return; - var hasDoseRoute = false; - Ext4.each(Ext4.getStore('DoseAndRoute').getRange(), function(dose) - { - if (dose.get('RowId') != null && dose.get('ProductId') == product.get('RowId') && product.get('Role') == productRole) { - var productDose = Ext4.clone(dose.data); - productDose.ProductLabel = product.get('Label'); - productDose.Label = product.get('Label') + ' - ' + dose.get('Label'); - productDose.ProductDoseRoute = dose.get('ProductId') + '-#-' + dose.get('Label'); - productDose.SortKey = product.get('RowId'); - data.push(productDose); - hasDoseRoute = true; - } - }, this); - if (!hasDoseRoute) - { - var productDose = Ext4.clone(product.data); - productDose.ProductLabel = product.get('Label'); - productDose.Label = product.get('Label'); - productDose.ProductDoseRoute = product.get('RowId') + '-#-'; - productDose.SortKey = product.get('RowId'); - data.push(productDose); - } - else { - //Issue 28273: No products selected in Treatment dialog for single table manage treatment page if product does not have dose/route selected - Ext4.each(checkedProducts, function(checked){ - if (checked.ProductId == product.get('RowId') && !checked.DoseAndRoute && !checked.Dose && !checked.Route) - { - var productDose = Ext4.clone(checked); - productDose.ProductLabel = checked['ProductId/Label']; - productDose.Label = checked['ProductId/Label']; - productDose.SortKey = product.get('RowId'); - data.push(productDose); - } - }); - } - }, this); - - data.sort(function(a, b){ - // if different product, sort by product RowId - // otherwise use a natural sort on the generated product + dose/route label - if (a.SortKey > b.SortKey) { - return 1; - } - else if (a.SortKey < b.SortKey) { - return -1; - } - else { - return LABKEY.internal.SortUtil.naturalSort(a.Label, b.Label); - } - }); - - return data; - }, - - getTreatmentFormValues: function() { - var fields = this.getForm().getForm().getFields().items, treatmentLabel = ''; - for (var f = 0; f < fields.length; f++) { - var field = fields[f]; - var data = field.getSubmitData(); - if (Ext4.isObject(data) && field.productLabel) { - if (treatmentLabel != '') { - treatmentLabel += '|'; - } - treatmentLabel += field.productLabel; - } - } - - var productValues = this.getForm().getValues(), treatment = {Label: treatmentLabel, Products: []}; - Ext4.iterate(productValues, function(key, val){ - treatment[key] = []; - if (val) { - if (Ext4.isArray(val)){ - Ext4.each(val, function(v){ - treatment[key].push({ProductDoseRoute: v}); - treatment.Products.push({ProductDoseRoute: v}); - }) - } - else { - treatment[key].push({ProductDoseRoute: val}); - treatment.Products.push({ProductDoseRoute: val}); - } - } - }); - return treatment; - } -}); - diff --git a/studydesign/webapp/study/vaccineDesign/TreatmentSchedule.js b/studydesign/webapp/study/vaccineDesign/TreatmentSchedule.js deleted file mode 100644 index de25f2f1e19..00000000000 --- a/studydesign/webapp/study/vaccineDesign/TreatmentSchedule.js +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.TreatmentSchedulePanel', { - extend : 'LABKEY.VaccineDesign.TreatmentSchedulePanelBase', - - width: 1400, - - initComponent : function() - { - this.items = [this.getTreatmentsGrid()]; - - this.callParent(); - - window.onbeforeunload = LABKEY.beforeunload(this.beforeUnload, this); - }, - - getTreatmentsGrid : function() - { - if (!this.treatmentsGrid) - { - this.treatmentsGrid = Ext4.create('LABKEY.VaccineDesign.TreatmentsGrid', { - disableEdit: this.disableEdit, - productRoles: this.productRoles - }); - - this.treatmentsGrid.on('dirtychange', this.enableSaveButton, this); - this.treatmentsGrid.on('celledited', this.enableSaveButton, this); - - // Note: since we need the data from the treatment grid, don't add this.getTreatmentScheduleGrid() until the treatment grid store has loaded - this.treatmentsGrid.on('loadcomplete', this.onTreatmentGridLoadComplete, this, {single: true}); - } - - return this.treatmentsGrid; - }, - - onTreatmentGridLoadComplete : function() - { - this.add(this.getTreatmentScheduleGrid()); - this.add(this.getButtonBar()); - - // since a treatment label change needs to be reflected in the treatment schedule grid, force a refresh there - this.getTreatmentsGrid().on('celledited', function(view, fieldName, value){ - if (fieldName == 'Label') - this.getTreatmentScheduleGrid().refresh(); - }, this); - - // removing a treatment row needs to also remove any visit mappings for that treatment - this.getTreatmentsGrid().on('beforerowdeleted', function(grid, record){ - this.getTreatmentScheduleGrid().removeTreatmentUsages(record.get('RowId')); - }, this); - }, - - getTreatmentScheduleGrid : function() - { - if (!this.treatmentScheduleGrid) - { - this.treatmentScheduleGrid = Ext4.create('LABKEY.VaccineDesign.TreatmentScheduleGrid', { - padding: '20px 0', - disableEdit: this.disableEdit, - subjectNoun: this.subjectNoun, - visitNoun: this.visitNoun - }); - - this.treatmentScheduleGrid.on('dirtychange', this.enableSaveButton, this); - this.treatmentScheduleGrid.on('celledited', this.enableSaveButton, this); - } - - return this.treatmentScheduleGrid; - }, - - getTreatments: function() - { - var treatments = [], index = 0, errorMsg = []; - - Ext4.each(this.getTreatmentsGrid().getStore().getRange(), function(record) - { - var recData = Ext4.clone(record.data); - index++; - - // drop any empty immunogen or adjuvant or challenge rows that were just added - recData['Products'] = []; - Ext4.each(this.productRoles, function(role) - { - Ext4.each(recData[role], function(product) - { - if (Ext4.isDefined(product['RowId']) || LABKEY.VaccineDesign.Utils.objectHasData(product)) - recData['Products'].push(product); - }, this); - }, this); - - // drop any empty treatment rows that were just added - var hasData = recData['Label'] != '' || recData['Description'] != '' || recData['Products'].length > 0; - if (Ext4.isDefined(recData['RowId']) || hasData) - { - var treatmentLabel = recData['Label'] != '' ? '\'' + recData['Label'] + '\'' : index; - - // validation: treatment must have at least one immunogen or adjuvant, no duplicate immunogens/adjuvants for a treatment - var treatmentProductIds = Ext4.Array.clean(Ext4.Array.pluck(recData['Products'], 'ProductId')); - if (recData['Products'].length == 0) - errorMsg.push('Treatment ' + treatmentLabel + ' must have at least one immunogen, adjuvant or challenge defined.'); - else if (treatmentProductIds.length != Ext4.Array.unique(treatmentProductIds).length) - errorMsg.push('Treatment ' + treatmentLabel + ' contains a duplicate immunogen, adjuvant or challenge.'); - else - treatments.push(recData); - } - }, this); - - if (errorMsg.length > 0) - { - this.onFailure(errorMsg.join('
    ')); - return false; - } - return treatments; - } -}); - -Ext4.define('LABKEY.VaccineDesign.TreatmentsGrid', { - extend : 'LABKEY.VaccineDesign.BaseDataView', - - cls : 'study-vaccine-design vaccine-design-treatments', - - mainTitle : 'Treatments', - - width: 1400, - - studyDesignQueryNames : ['StudyDesignRoutes', 'Product', 'DoseAndRoute'], - - //Override - getStore : function() - { - if (!this.store) - { - this.store = Ext4.create('Ext.data.Store', { - storeId : 'TreatmentsGridStore', - model : 'LABKEY.VaccineDesign.Treatment', - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL("study-design", "getStudyTreatments", null, {splitByRole: true}), - reader: { - type: 'json', - root: 'treatments' - } - }, - sorters: [{ property: 'RowId', direction: 'ASC' }], - autoLoad: true - }); - } - - return this.store; - }, - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - this.columnConfigs = [{ - label: 'Label', - width: 200, - dataIndex: 'Label', - required: true, - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Label', 185) - },{ - label: 'Description', - width: 200, - dataIndex: 'Description', - editorType: 'Ext.form.field.TextArea', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Description', 185, '95%') - }]; - - if (Ext4.isArray(this.productRoles)) { - Ext4.each(this.productRoles, function(role){ - var roleColumn = this.getProductRoleColumn(role); - this.columnConfigs.push(roleColumn); - }, this); - } - } - - return this.columnConfigs; - }, - - getProductRoleColumn: function(roleName) { - var column = { - label: roleName + 's', - width: 310, - dataIndex: roleName, - subgridConfig: { - columns: [{ - label: roleName, - width: 140, - dataIndex: 'ProductId', - required: true, - queryName: 'Product', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: this.getProductEditor(roleName) - },{ - label: 'Dose and Route', - width: 140, - dataIndex: 'DoseAndRoute', - queryName: 'DoseAndRoute', - editorType: 'LABKEY.ext4.ComboBox', - editorConfig: this.getDoseAndRouteEditorConfig() - }] - } - }; - return column; - }, - - getProductEditor : function(roleName){ - - var filter = LABKEY.Filter.create('Role', roleName), - cfg = LABKEY.VaccineDesign.Utils.getStudyDesignComboConfig('ProductId', 125, 'Product', filter, 'Label', 'RowId'); - - cfg.listeners = { - scope: this, - change : function(cmp, productId) { - // clear out (if any) value for the dose and route field - var record = this.getStore().getAt(cmp.storeIndex), - outerDataIndex = cmp.outerDataIndex, - subgridIndex = Number(cmp.subgridIndex), - selector = 'tr.data-row:nth(' + (this.getStore().indexOf(record)+1) + ') table.subgrid-' + outerDataIndex - + ' tr.subrow:nth(' + (subgridIndex+1) + ') td[data-index=DoseAndRoute] input'; - - var inputField = this.getInputFieldFromSelector(selector); - if (inputField != null) - { - inputField.setValue(''); - inputField.bindStore(this.getNewDoseAndRouteComboStore(productId)); - } - } - }; - return cfg; - }, - - getDoseAndRouteEditorConfig : function() - { - return { - hideFieldLabel: true, - name: 'DoseAndRoute', - width: 125, - forceSelection : false, // allow usage of inactive types - editable : false, - queryMode : 'local', - displayField : 'Label', - valueField : 'Label', - store : null, // the store will be created and bound to this combo after render - listeners : { - scope: this, - render : function(cmp) { - var record = this.getStore().getAt(cmp.storeIndex), - outerDataIndex = cmp.outerDataIndex, - subgridIndex = Number(cmp.subgridIndex), - productId = record.get(outerDataIndex)[subgridIndex]['ProductId']; - - cmp.bindStore(this.getNewDoseAndRouteComboStore(productId)); - }, - change : function(cmp, newValue, oldValue) { - var record = this.getStore().getAt(cmp.storeIndex), - outerDataIndex = cmp.outerDataIndex, - subgridIndex = Number(cmp.subgridIndex), - subRecord = record.get(outerDataIndex)[subgridIndex]; - - // if the ProductDoseRoute is set, we need to update it - if (Ext4.isDefined(subRecord['ProductDoseRoute']) && Ext4.isDefined(subRecord['ProductId'])) - subRecord['ProductDoseRoute'] = subRecord['ProductId'] + '-#-' + newValue; - } - } - }; - }, - - getNewDoseAndRouteComboStore : function(productId) - { - // need to create a new store each time since we need to add a [none] option and include any new treatment records - var data = []; - Ext4.each(Ext4.getStore('DoseAndRoute').getRange(), function(record) - { - if (record.get('ProductId') == null || record.get('ProductId') == productId) - data.push(Ext4.clone(record.data)); - }, this); - - return Ext4.create('Ext.data.Store', { - fields: ['RowId', 'Label'], - data: data - }); - }, - - //Override - getNewModelInstance : function() - { - return LABKEY.VaccineDesign.Treatment.create({ - RowId: Ext4.id() // need to generate an id so that the treatment schedule grid can use it - }); - }, - - //Override - getDeleteConfirmationMsg : function() - { - return 'Are you sure you want to delete the selected treatment? ' - + 'Note: this will also delete any usages of this treatment record in the Treatment Schedule grid below.'; - }, - - //Override - updateSubgridRecordValue : function(record, outerDataIndex, subgridIndex, fieldName, newValue) - { - var preProductIds = []; - Ext4.each(this.productRoles, function(role){ - var productRoleIds = Ext4.Array.pluck(record.get(role), 'ProductId'); - if (preProductIds.length == 0) - preProductIds = productRoleIds; - else - preProductIds = preProductIds.concat(productRoleIds); - }); - - this.callParent([record, outerDataIndex, subgridIndex, fieldName, newValue]); - - // auto populate the treatment label if the user has not already entered a value - if (fieldName == 'ProductId') - this.populateTreatmentLabel(record, preProductIds); - }, - - //Override - removeSubgridRecord : function(target, record) - { - var preProductIds = []; - Ext4.each(this.productRoles, function(role){ - var productRoleIds = Ext4.Array.pluck(record.get(role), 'ProductId'); - if (preProductIds.length == 0) - preProductIds = productRoleIds; - else - preProductIds = preProductIds.concat(productRoleIds); - }); - this.callParent([target, record]); - this.populateTreatmentLabel(record, preProductIds); - this.refresh(true); - }, - - populateTreatmentLabel : function(record, preProductIds) - { - var currentLabel = record.get('Label'); - if (currentLabel == '' || currentLabel == this.getLabelFromProductIds(preProductIds)) - { - var postProductIds = []; - Ext4.each(this.productRoles, function(role){ - var productRoleIds = Ext4.Array.pluck(record.get(role), 'ProductId'); - if (postProductIds.length == 0) - postProductIds = productRoleIds; - else - postProductIds = postProductIds.concat(productRoleIds); - }); - - var updatedTreatmentLabel = this.getLabelFromProductIds(postProductIds); - - // need to update the input field value, which will intern update the record and fire teh celledited event - var inputField = this.getInputFieldFromSelector('tr.data-row:nth(' + (this.getStore().indexOf(record)+1) + ') td.cell-value input'); - if (inputField != null) - { - inputField.setValue(updatedTreatmentLabel); - record.set('Label', updatedTreatmentLabel); - } - } - }, - - getInputFieldFromSelector : function(selector) - { - var inputFieldEl = Ext4.DomQuery.selectNode(selector, this.getEl().dom); - if (inputFieldEl != null) - return Ext4.ComponentManager.get(inputFieldEl.id.replace('-inputEl', '')); - - return null; - }, - - getLabelFromProductIds : function(productIdsArr) - { - var labelArr = []; - - if (Ext4.isArray(productIdsArr)) - { - Ext4.each(productIdsArr, function(productId){ - if (productId != undefined || productId != null) - labelArr.push(LABKEY.VaccineDesign.Utils.getLabelFromStore('Product', productId)); - }); - } - - return labelArr.join(' | '); - } -}); - -Ext4.define('LABKEY.VaccineDesign.TreatmentScheduleGrid', { - extend : 'LABKEY.VaccineDesign.TreatmentScheduleGridBase', - - //Override - onStudyTreatmentScheduleStoreLoad : function() - { - this.getStore().fireEvent('load', this.getStore()); - }, - - getTreatmentsStore : function() - { - if (!this.treatmentsStore) - { - this.treatmentsStore = Ext4.getStore('TreatmentsGridStore'); - } - - return this.treatmentsStore; - }, - - //Override - getTreatmentFieldEditorType: function() - { - return 'LABKEY.ext4.ComboBox'; - }, - - //Override - isFieldTreatmentLookup: function() - { - return false; - }, - - getTreatmentFieldConfig : function() - { - return { - hideFieldLabel: true, - name: 'VisitMap', - width: 135, - forceSelection : false, // allow usage of inactive types - editable : false, - queryMode : 'local', - displayField : 'Label', - valueField : 'RowId', - store : this.getNewTreatmentComboStore() - }; - }, - - getNewTreatmentComboStore : function() - { - // need to create a new store each time since we need to add a [none] option and include any new treatment records - var data = [{RowId: null, Label: '[none]'}]; - Ext4.each(this.getTreatmentsStore().getRange(), function(record) - { - data.push(Ext4.clone(record.data)); - }, this); - - return Ext4.create('Ext.data.Store', { - fields: ['RowId', 'Label'], - data: data - }); - }, - - removeTreatmentUsages : function(treatmentId) - { - this.getStore().suspendEvents(); - Ext4.each(this.getStore().getRange(), function(record) - { - var newVisitMapArr = Ext4.Array.filter(record.get('VisitMap'), function(item){ return item.TreatmentId != treatmentId; }); - record.set('VisitMap', newVisitMapArr); - }, this); - this.getStore().resumeEvents(); - - this.refresh(true); - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/TreatmentScheduleBase.js b/studydesign/webapp/study/vaccineDesign/TreatmentScheduleBase.js deleted file mode 100644 index 73aece245fa..00000000000 --- a/studydesign/webapp/study/vaccineDesign/TreatmentScheduleBase.js +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.TreatmentSchedulePanelBase', { - extend : 'Ext.panel.Panel', - - border : false, - - bodyStyle : 'background-color: transparent;', - - disableEdit : true, - - dirty : false, - - returnUrl : null, - - getButtonBar : function() - { - if (!this.buttonBar) - { - this.buttonBar = Ext4.create('Ext.toolbar.Toolbar', { - dock: 'bottom', - ui: 'footer', - padding: 0, - style : 'background-color: transparent;', - defaults: {width: 75}, - items: [this.getSaveButton(), this.getCancelButton()] - }); - } - - return this.buttonBar; - }, - - getSaveButton : function() - { - if (!this.saveButton) - { - this.saveButton = Ext4.create('Ext.button.Button', { - text: 'Save', - disabled: true, - hidden: this.disableEdit, - handler: this.saveTreatmentSchedule, - scope: this - }); - } - - return this.saveButton; - }, - - enableSaveButton : function() - { - this.setDirty(true); - this.getSaveButton().enable(); - }, - - getCancelButton : function() - { - if (!this.cancelButton) - { - this.cancelButton = Ext4.create('Ext.button.Button', { - text: this.disableEdit ? 'Done' : 'Cancel', - handler: this.goToReturnURL, - scope: this - }); - } - - return this.cancelButton; - }, - - getTreatments: function() - { - return []; - }, - - saveTreatmentSchedule : function() - { - this.getEl().mask('Saving...'); - - var treatments = this.getTreatments(), cohorts = [], errorMsg = []; - - if (!Ext4.isArray(treatments)) // treatments invalid - return; - - Ext4.each(this.getTreatmentScheduleGrid().getStore().getRange(), function(record) - { - var recData = Ext4.clone(record.data); - - // drop any empty cohort rows that were just added - var hasData = recData['Label'] != '' || recData['SubjectCount'] != '' || recData['VisitMap'].length > 0; - if (Ext4.isDefined(recData['RowId']) || hasData) - { - var countVal = Number(recData['SubjectCount']); - if (isNaN(countVal) || countVal < 0) - errorMsg.push('Cohort ' + this.subjectNoun.toLowerCase() + ' count values must be a positive integer: ' + recData['SubjectCount'] + '.'); - else - cohorts.push(recData); - } - }, this); - - if (errorMsg.length > 0) - { - this.onFailure(errorMsg.join('
    ')); - return; - } - - LABKEY.Ajax.request({ - url : LABKEY.ActionURL.buildURL('study-design', 'updateTreatmentSchedule.api'), - method : 'POST', - jsonData: { - treatments: treatments, - cohorts: cohorts - }, - scope: this, - success: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.success) - this.goToReturnURL(); - else - this.onFailure(); - }, - failure: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.errors) - this.onFailure(Ext4.Array.pluck(resp.errors, 'message').join('
    ')); - else - this.onFailure(resp.exception); - } - }); - }, - - goToReturnURL : function() - { - this.setDirty(false); - window.location = this.returnUrl; - }, - - onFailure : function(text) - { - Ext4.Msg.show({ - title: 'Error', - msg: text || 'Unknown error occurred.', - icon: Ext4.Msg.ERROR, - buttons: Ext4.Msg.OK - }); - - this.getEl().unmask(); - }, - - setDirty : function(dirty) - { - this.dirty = dirty; - LABKEY.Utils.signalWebDriverTest("treatmentScheduleDirty", dirty); - }, - - isDirty : function() - { - return this.dirty; - }, - - beforeUnload : function() - { - if (!this.disableEdit && this.isDirty()) - return 'Please save your changes.'; - } -}); - -Ext4.define('LABKEY.VaccineDesign.TreatmentScheduleGridBase', { - extend : 'LABKEY.VaccineDesign.BaseDataViewAddVisit', - - cls : 'study-vaccine-design vaccine-design-cohorts', - - mainTitle : 'Treatment Schedule', - - width: 350, - - subjectNoun : 'Subject', - - visitNoun : 'Visit', - - //studyDesignQueryNames : ['StudyDesignRoutes', 'Product', 'DoseAndRoute'], - - getStore : function() - { - if (!this.store) - { - this.store = Ext4.create('Ext.data.Store', { - model : 'LABKEY.VaccineDesign.Cohort', - sorters: [{ property: 'RowId', direction: 'ASC' }] - }); - - this.queryStudyTreatmentSchedule(); - } - - return this.store; - }, - - queryStudyTreatmentSchedule : function() - { - LABKEY.Ajax.request({ - url: LABKEY.ActionURL.buildURL('study-design', 'getStudyTreatmentSchedule', null, {splitByRole: true}), - method: 'GET', - scope: this, - success: function (response) - { - var o = Ext4.decode(response.responseText); - if (o.success) - { - this.getVisitStore(o['visits']); - this.getStore().loadData(o['cohorts']); - this.onStudyTreatmentScheduleStoreLoad(); - } - } - }); - }, - - getVisitStore : function(data) - { - if (!this.visitStore) - { - this.visitStore = Ext4.create('Ext.data.Store', { - model : 'LABKEY.VaccineDesign.Visit', - data : data, - sorters : [{property: 'DisplayOrder', direction: 'ASC'},{property: 'SequenceNumMin', direction: 'ASC'}] - }); - } - - return this.visitStore; - }, - - getTreatmentsStore : function() - { - if (!this.treatmentsStore) - { - var me = this; - this.treatmentsStore = Ext4.create('Ext.data.Store', { - storeId : 'TreatmentsGridStore', - model : 'LABKEY.VaccineDesign.Treatment', - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL("study-design", "getStudyTreatments", null, {splitByRole: true}), - reader: { - type: 'json', - root: 'treatments' - } - }, - sorters: [{ property: 'RowId', direction: 'ASC' }], - autoLoad: true, - listeners: { - scope: this, - load: function (store) - { - me.getStore().fireEvent('load', me.getStore()); - } - } - }); - } - - return this.treatmentsStore; - }, - - getVisitColumnConfigs : function() - { - var visitConfigs = []; - - Ext4.each(this.getVisitStore().getRange(), function(visit) - { - if (visit.get('Included')) - { - visitConfigs.push({ - label: visit.get('Label') || (this.visitNoun + visit.get('RowId')), - width: 150, - dataIndex: 'VisitMap', - dataIndexArrFilterProp: 'VisitId', - dataIndexArrFilterValue: visit.get('RowId'), - dataIndexArrValue: 'TreatmentId', - lookupStoreId: 'TreatmentsGridStore', - editorType: this.getTreatmentFieldEditorType(), - editorConfig: this.getTreatmentFieldConfig, - isTreatmentLookup: this.isFieldTreatmentLookup() - }); - } - }, this); - - if (visitConfigs.length == 0 && !this.disableEdit) - { - visitConfigs.push({ - label: 'No ' + this.visitNoun + 's Defined', - displayValue: '', - width: 160 - }); - } - - return visitConfigs; - }, - - //Override - getColumnConfigs : function() - { - if (!this.columnConfigs) - { - var columnConfigs = [{ - label: 'Group / Cohort', - width: 200, - dataIndex: 'Label', - required: true, - editorType: 'Ext.form.field.Text', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignTextConfig('Label', 185) - },{ - label: this.subjectNoun + ' Count', - width: 130, - dataIndex: 'SubjectCount', - editorType: 'Ext.form.field.Number', - editorConfig: LABKEY.VaccineDesign.Utils.getStudyDesignNumberConfig('SubjectCount', 115) - }]; - - var visitConfigs = this.getVisitColumnConfigs(); - - // update the width based on the number of visit columns - var width = 400 + (Math.max(2, visitConfigs.length) * 150); - this.setWidth(width); - - // update the outer panel width if necessary - var outerPanel = this.up('panel'); - if (outerPanel != null) - outerPanel.setWidth(Math.max(width, 1400)); - - this.columnConfigs = columnConfigs.concat(visitConfigs); - } - - return this.columnConfigs; - }, - - //Override - getNewModelInstance : function() - { - var newCohort = LABKEY.VaccineDesign.Cohort.create(); - newCohort.set('VisitMap', []); - return newCohort; - }, - - //Override - removeOuterRecord : function(title, record) { - if (!record.get('CanDelete')) { - Ext4.Msg.show({ - title: 'Unable to Remove Cohort', - msg: 'The selected cohort can not be removed because it is in-use in the study.
    ' - + Ext4.String.htmlEncode(record.get('Label')) + '', - buttons: Ext4.Msg.OK, - icon: Ext4.Msg.INFO - }); - } - else { - this.callParent([title, record]); - } - }, - - //Override - getDeleteConfirmationMsg : function() - { - return 'Are you sure you want to delete the selected group / cohort and its associated treatment / visit mapping records?'; - }, - - //Override - getCurrentCellValue : function(column, record, dataIndex, outerDataIndex, subgridIndex) - { - var value = this.callParent([column, record, dataIndex, outerDataIndex, subgridIndex]); - - if (Ext4.isArray(value)) - { - var matchingIndex = LABKEY.VaccineDesign.Utils.getMatchingRowIndexFromArray(value, column.dataIndexArrFilterProp, column.dataIndexArrFilterValue); - if (matchingIndex > -1) - return value[matchingIndex][column.dataIndexArrValue]; - else - return null; - } - - return value; - }, - - getTreatmentCellDisplayValue : function(val, lookupStore) - { - var displayVal = val; - if (Ext4.isDefined(lookupStore) && val != null && val != '') - { - var store = Ext4.getStore(lookupStore); - if (store != null) - { - var record = store.findRecord('RowId', val); - if (record != null) - displayVal = record.get('Label'); - } - } - return displayVal; - }, - - //Override - updateStoreRecordValue : function(record, column, newValue, field) - { - var value = this.getTreatmentValue(column, newValue, field); - // special case for editing the value of one of the pivot visit columns - if (column.dataIndex == 'VisitMap') - { - var visitMapArr = record.get(column.dataIndex), - matchingIndex = LABKEY.VaccineDesign.Utils.getMatchingRowIndexFromArray(visitMapArr, column.dataIndexArrFilterProp, column.dataIndexArrFilterValue); - - if (matchingIndex > -1) - { - if (value != null) - visitMapArr[matchingIndex][column.dataIndexArrValue] = value; - else - Ext4.Array.splice(visitMapArr, matchingIndex, 1); - } - else if (value != null) - { - visitMapArr.push({ - CohortId: record.get('RowId'), - VisitId: column.dataIndexArrFilterValue, - TreatmentId: value - }); - } - - this.fireEvent('celledited', this, 'VisitMap', visitMapArr); - } - else - { - this.callParent([record, column, value]); - } - }, - - getTreatmentValue : function(column, newValue, field) { - return newValue; - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/TreatmentScheduleSingleTablePanel.js b/studydesign/webapp/study/vaccineDesign/TreatmentScheduleSingleTablePanel.js deleted file mode 100644 index f71af73efa2..00000000000 --- a/studydesign/webapp/study/vaccineDesign/TreatmentScheduleSingleTablePanel.js +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2016-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -Ext4.define('LABKEY.VaccineDesign.TreatmentScheduleSingleTablePanel', { - extend : 'LABKEY.VaccineDesign.TreatmentSchedulePanelBase', - - width: 1400, - - initComponent : function() - { - this.items = [this.getTreatmentScheduleGrid(), this.getButtonBar()]; - - this.callParent(); - - window.onbeforeunload = LABKEY.beforeunload(this.beforeUnload, this); - }, - - getTreatmentScheduleGrid : function() - { - if (!this.treatmentScheduleGrid) - { - this.treatmentScheduleGrid = Ext4.create('LABKEY.VaccineDesign.TreatmentScheduleSingleTableGrid', { - padding: '20px 0', - disableEdit: this.disableEdit, - subjectNoun: this.subjectNoun, - visitNoun: this.visitNoun, - productRoles: this.productRoles - }); - - this.treatmentScheduleGrid.on('dirtychange', this.enableSaveButton, this); - this.treatmentScheduleGrid.on('celledited', this.enableSaveButton, this); - } - - return this.treatmentScheduleGrid; - } - -}); - -Ext4.define('LABKEY.VaccineDesign.TreatmentScheduleSingleTableGrid', { - extend : 'LABKEY.VaccineDesign.TreatmentScheduleGridBase', - - studyDesignQueryNames : ['StudyDesignRoutes', 'Product', 'DoseAndRoute'], - - //Override - onStudyTreatmentScheduleStoreLoad : function() - { - this.getTreatmentsStore(); - }, - - getTreatmentsStore : function() - { - if (!this.treatmentsStore) - { - var me = this; - this.treatmentsStore = Ext4.create('Ext.data.Store', { - storeId : 'TreatmentsGridStore', - model : 'LABKEY.VaccineDesign.Treatment', - proxy: { - type: 'ajax', - url : LABKEY.ActionURL.buildURL("study-design", "getStudyTreatments", null, {splitByRole: true}), - reader: { - type: 'json', - root: 'treatments' - } - }, - sorters: [{ property: 'RowId', direction: 'ASC' }], - autoLoad: true, - listeners: { - scope: this, - load: function (store) - { - me.getStore().fireEvent('load', me.getStore()); - } - } - }); - } - - return this.treatmentsStore; - }, - - getTreatmentFieldConfig : function() - { - var me = this; - return { - hideFieldLabel: true, - name: 'VisitMap', - width: 135, - readOnly: true, - enableKeyEvents: false, - cls: 'treatment-input-cell', - listeners: { - render: function(cmp) { - if (cmp.value) - cmp.getEl().dom.title = cmp.value; //tooltip - - cmp.getEl().on('click', function(){ - if (me.productRoles == null || me.productRoles.length == 0) { - Ext4.Msg.show({ - title: 'Error', - msg: 'No study products have been defined.', - icon: Ext4.Msg.ERROR, - buttons: Ext4.Msg.OK - }); - return; - } - - var win; - var popupConfig = { - productRoles: me.productRoles, - autoScroll : true, - buttonAlign : 'right', - modal: true, - width: 400, - height: 500, - border: false, - closable: false, - title: 'Treatment', - draggable: false, - buttons: [{ - text: 'Cancel', - onClick : function () { - win.close(); - } - },{ - text: 'OK', - cls: 'commentSubmit', - onClick : function () { - var isFormDirty = win.getForm().getForm().isDirty(); - if (!isFormDirty) { - win.close(); - return; - } - - var treatment = win.getTreatmentFormValues(); - if (treatment && treatment.Products.length == 0) { - win.close(); - cmp.treatmentId = null; - cmp.setValue(null); - cmp.getEl().dom.title = ''; - return; - } - var treatments = [treatment]; - LABKEY.Ajax.request({ - url : LABKEY.ActionURL.buildURL('study-design', 'updateTreatments.api'), - method : 'POST', - jsonData: { - treatments: treatments - }, - scope: this, - success: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.success) { - win.close(); - me.fireEvent('celledited'); - var changed = cmp.treatmentId != resp.treatmentIds[0]; - if (changed) - cmp.setValue(''); // force a change event, in case label is same, but id changed - cmp.treatmentId = resp.treatmentIds[0]; - cmp.setValue(treatments[0].Label); - cmp.getEl().dom.title = treatments[0].Label; - me.getTreatmentsStore().load(); - } - else - this.onFailure(); - }, - failure: function(response) - { - var resp = Ext4.decode(response.responseText); - if (resp.errors) - this.onFailure(Ext4.Array.pluck(resp.errors, 'message').join('
    ')); - else - this.onFailure(resp.exception); - } - }); - - } - }] - - }; - if (cmp.treatmentId) { - Ext4.Ajax.request({ - url : LABKEY.ActionURL.buildURL("study-design", "getStudyTreatments", null, {splitByRole: true, treatmentId: cmp.treatmentId}), - method : 'POST', - success: LABKEY.Utils.getCallbackWrapper(function(response){ - popupConfig.treatmentDetails = response.treatments.length > 0 ? response.treatments[0] : null; - win = new LABKEY.VaccineDesign.TreatmentDialog(popupConfig); - win.show(); - - }, me) - }); - } - else { - win = new LABKEY.VaccineDesign.TreatmentDialog(popupConfig); - win.show(); - } - }); - } - } - }; - }, - - //Override - getTreatmentFieldEditorType: function() - { - return 'Ext.form.field.Text'; - }, - - //Override - isFieldTreatmentLookup: function() - { - return true; - }, - - //Override - getTreatmentValue : function(column, newValue, field) { - var value = newValue; - if (column.lookupStoreId && field && field.treatmentId) - value = field.treatmentId; - return value; - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/Utils.js b/studydesign/webapp/study/vaccineDesign/Utils.js deleted file mode 100644 index ce684cd9ceb..00000000000 --- a/studydesign/webapp/study/vaccineDesign/Utils.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -Ext4.define('LABKEY.VaccineDesign.Utils', { - - singleton: true, - - /** - * Helper function to get field editor config object for a study design lookup combo. - * @param name Field name - * @param width Field width - * @param queryName If combo, the queryName for the store - * @param filter LABKEY.Filter.create() object - * @param displayField The field name of the combo store displayField - * @param valueField The field name of the combo store valueField - * @returns {Object} Field config - */ - getStudyDesignComboConfig : function(name, width, queryName, filter, displayField, valueField) - { - return { - hideFieldLabel: true, - name: name, - width: width || 150, - forceSelection : false, // allow usage of inactive types - editable : false, - queryMode : 'local', - // TODO: this does not htmlEncode the display value in expanded options list - displayField : displayField || 'Label', - valueField : valueField || 'Name', - store : LABKEY.VaccineDesign.Utils.getStudyDesignStore(queryName, filter) - }; - }, - - /** - * Helper function to get field editor config object for a study design text or text area field. - * @param name Field name - * @param width Field width - * @param height Field height - * @returns {Object} Field config - */ - getStudyDesignTextConfig : function(name, width, height) - { - return { - hideFieldLabel: true, - name: name, - width: width, - height: height, - selectOnFocus: true - } - }, - - /** - * Helper function to get field editor config object for a study design number field. - * @param name Field name - * @param width Field width - * @param decimalPrecision Field maximum precision to display after decimal - * @returns {Object} Field config - */ - getStudyDesignNumberConfig : function(name, width, decimalPrecision) - { - return { - hideFieldLabel: true, - name: name, - width: width, - minValue: 0, - allowDecimals: Ext4.isNumber(decimalPrecision), - decimalPrecision: decimalPrecision - } - }, - - /** - * Create a new LABKEY.ext4.Store for the given queryName from the study schema. - * @param queryName - * @param filter LABKEY.Filter.create() object - * @returns {LABKEY.ext4.Store} - */ - getStudyDesignStore : function(queryName, filter) - { - var key = Ext4.isDefined(filter) ? queryName + '|' + filter.getColumnName() + '|' + filter.getValue() : queryName, - store = Ext4.getStore(key), - hasStudyDesignPrefix = queryName.indexOf('StudyDesign') == 0, - columns = 'RowId,Name,Label'; - - if (Ext4.isDefined(store)) - return store; - - // special case to query DisplayOrder and SequenceNumMin for Visit table - if (queryName == 'Visit') - columns += ',DisplayOrder,SequenceNumMin'; - // special case to query ProductId column for DoseAndRoute table - else if (queryName == 'DoseAndRoute') - columns += ',ProductId'; - else if (queryName == 'Product') - columns += ',Role'; - else if (queryName == 'DataSets') - columns += ',DataSetId'; - - return Ext4.create('LABKEY.ext4.Store', { - storeId: key, - schemaName: 'study', - queryName: queryName, - columns: columns, - filterArray: Ext4.isDefined(filter) ? [filter] : (hasStudyDesignPrefix ? [LABKEY.Filter.create('Inactive', false)] : []), - containerFilter: LABKEY.container.type == 'project' || Ext4.isDefined(filter) || !hasStudyDesignPrefix ? undefined : 'CurrentPlusProject', - sort: '-Container/Path,Label', - autoLoad: true, - listeners: { - load: function(store) - { - store.insert(0, {Name: null}); - } - } - }); - }, - - /** - * Lookup a label for a given value using a store generated from the queryName. - * @param queryName - * @param value - * @returns {String} - */ - getLabelFromStore : function(queryName, value) - { - var store = LABKEY.VaccineDesign.Utils.getStudyDesignStore(queryName), - storeCols = Ext4.Array.pluck(store.getColumns(), 'dataIndex'), - keys = ['RowId', 'Name', 'DataSetId'], - record = null; - - Ext4.each(keys, function(key) { - if (record == null && storeCols.indexOf(key) > -1) - record = store.findRecord(key, value, 0, false, true, true); - }); - - return record != null ? record.get("Label") : value; - }, - - /** - * Check if the given object has any properties which have data (i.e. non null, not an empty string, or is an array) - * @param obj The object to test - * @returns {boolean} - */ - objectHasData : function(obj) - { - var hasNonNull = false; - - if (Ext4.isObject(obj)) - { - Ext4.Object.each(obj, function (key, value) - { - if ((Ext4.isArray(value) && value.length > 0) || (value != null && value != '')) - { - hasNonNull = true; - return false; // break - } - }); - } - - return hasNonNull; - }, - - /** - * Check if the given model object has any properties which have data (i.e. non null, not an empty string, or is an array) - * @param obj The object to test - * @returns {boolean} - */ - modelHasData : function(obj, fields) - { - var hasNonNull = false; - - if (Ext4.isObject(obj) && Ext4.isArray(fields)) - { - Ext4.each(fields, function(field) - { - if (Ext4.isArray(obj[field.name]) && obj[field.name].length > 0) - hasNonNull = true; - else if ((field.type.type == 'int' || field.type.type == 'float') && obj[field.name] != null && obj[field.name] != 0) - hasNonNull = true; - else if (field.type.type == 'string' && obj[field.name] != null && obj[field.name] != '') - hasNonNull = true; - - if (hasNonNull) - return false; // break; - }); - } - - return hasNonNull; - }, - - /** - * Get the matching row index from an array based on a given row's object property name and value. - * @param arr The array to traverse - * @param filterPropName The name of the row's object property to compare - * @param filterPropValue The value of the row's object property that indicates a match - * @returns {Object} - */ - getMatchingRowIndexFromArray : function(arr, filterPropName, filterPropValue) - { - if (Ext4.isString(filterPropName) && Ext4.isDefined(filterPropValue) && Ext4.isArray(arr)) - { - for (var i = 0; i < arr.length; i++) - { - if (arr[i].hasOwnProperty(filterPropName) && arr[i][filterPropName] == filterPropValue) - return i; - } - } - - return -1; - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/VaccineDesign.css b/studydesign/webapp/study/vaccineDesign/VaccineDesign.css deleted file mode 100644 index a44ba06e85a..00000000000 --- a/studydesign/webapp/study/vaccineDesign/VaccineDesign.css +++ /dev/null @@ -1,82 +0,0 @@ -.study-vaccine-design .x4-panel-body { - background-color: transparent; -} - -.study-vaccine-design .main-title { - font-weight: bold; - font-size: 16px; - padding-bottom: 5px; -} - -.study-vaccine-design table.outer, -.study-vaccine-design table.subgrid { - border-collapse: collapse; -} - -.study-vaccine-design td.cell-display, -.study-vaccine-design td.cell-value { - padding: 5px; - border: solid 1px #DDDDDD; - vertical-align: top; -} - -.study-vaccine-design td.cell-display { - height: 30px; -} -.study-vaccine-design td.cell-value { - height: 33px; -} - -.study-vaccine-design td.cell-value .x4-form-cb-wrap { - height: 18px; -} - -.study-vaccine-design table.subgrid td { - background-color: #FFFFFF !important; -} - -.study-vaccine-design tr.header-row td { - font-weight: bold; - padding: 5px; - background-color: #EEEEEE !important; - border-bottom-color: #C0C0C0; -} - -.study-vaccine-design table.outer tr.data-row td { - background-color: #FFFFFF; -} -.study-vaccine-design table.outer tr.alternate-row td { - background-color: #F4F4F4; -} - -.study-vaccine-design td.cell-value.missing-required { - background-color: #ffe5e5 !important; -} - -.study-vaccine-design td.empty { - font-style: italic; -} - -.study-vaccine-design td.action i { - color: #777777; -} -.study-vaccine-design td.action i:hover { - cursor: pointer; - color: #000000; -} - -.dialog-product-label .x4-form-cb-label-after { - /* Firefox */ - width: -moz-calc(100% - 20px); - /* WebKit */ - width: -webkit-calc(100% - 20px); - /* Standard */ - width: calc(100% - 20px); - white-space: nowrap; -} - -.treatment-input-cell .x4-form-field { - cursor: pointer; - opacity: 0.8; -} - diff --git a/studydesign/webapp/study/vaccineDesign/VisitWindow.js b/studydesign/webapp/study/vaccineDesign/VisitWindow.js deleted file mode 100644 index f8c1917b90c..00000000000 --- a/studydesign/webapp/study/vaccineDesign/VisitWindow.js +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -Ext4.define('LABKEY.VaccineDesign.VisitWindow', { - extend: 'Ext.window.Window', - - modal: true, - - visitStore: null, - - visitNoun: 'Visit', - - constructor: function(config) - { - this.callParent([config]); - this.addEvents('closewindow', 'selectexistingvisit', 'newvisitcreated'); - }, - - initComponent: function() - { - this.isTimepoint = this.visitNoun.toLowerCase() == 'timepoint'; - this.items = [this.getFormPanel()]; - this.callParent(); - }, - - getFormPanel : function() - { - if (!this.formPanel) - { - this.formPanel = Ext4.create('Ext.form.Panel',{ - border: false, - padding: 10, - items: [ - this.getExistingVisitRadio(), - this.getExistingVisitCombo(), - this.getNewVisitRadio(), - this.getNewVisitLabelField(), - this.getNewVisitMinMaxContainer() - ], - buttons: [ - this.getSelectBtn(), - this.getCancelBtn() - ] - }); - } - - return this.formPanel; - }, - - getExistingVisitRadio : function() - { - if (!this.existingVisitRadio) - { - this.existingVisitRadio = Ext4.create('Ext.form.field.Radio', { - name: 'visitType', - disabled: this.getFilteredVisitStore().getCount() == 0, - inputValue: 'existing', - boxLabel: 'Select an existing study ' + this.visitNoun.toLowerCase() + ':', - checked: this.getFilteredVisitStore().getCount() > 0, - hideFieldLabel: true, - width: 300 - }); - } - - return this.existingVisitRadio; - }, - - getNewVisitRadio : function() - { - if (!this.newVisitRadio) - { - this.newVisitRadio = Ext4.create('Ext.form.field.Radio', { - name: 'visitType', - inputValue: 'new', - boxLabel: 'Create a new study ' + this.visitNoun.toLowerCase() + ':', - checked: this.getFilteredVisitStore().getCount() == 0, - hideFieldLabel: true, - width: 300 - }); - - this.newVisitRadio.on('change', function(radio, newValue){ - this.getExistingVisitCombo().setDisabled(newValue); - this.getNewVisitLabelField().setDisabled(!newValue); - this.getNewVisitMinMaxContainer().setDisabled(!newValue); - this.getSelectBtn().setText(newValue ? 'Submit' : 'Select'); - this.updateSelectBtnState(); - - if (newValue) - this.getNewVisitLabelField().focus(); - else - this.getExistingVisitCombo().focus(); - }, this); - } - - return this.newVisitRadio; - }, - - getExistingVisitCombo : function() - { - if (!this.existingVisitCombo) - { - this.existingVisitCombo = Ext4.create('Ext.form.field.ComboBox', { - name: 'existingVisit', - disabled: this.getFilteredVisitStore().getCount() == 0, - hideFieldLabel: true, - style: 'margin-left: 15px;', - width: 300, - store: this.getFilteredVisitStore(), - editable: false, - queryMode: 'local', - displayField: 'Label', - valueField: 'RowId' - }); - - this.existingVisitCombo.on('change', this.updateSelectBtnState, this); - } - - return this.existingVisitCombo; - }, - - getFilteredVisitStore : function() - { - if (!this.filteredVisitStore) - { - var data = []; - if (this.visitStore != null) - { - Ext4.each(this.visitStore.query('Included', false).items, function(record) - { - var recData = Ext4.clone(record.data); - recData['Label'] = recData['Label'] || recData['SequenceNumMin']; - data.push(recData); - }, this); - } - - // add an option to select all existing visits for display - if (data.length > 1) - data.push({Label: '[Show All]', RowId: -1, DisplayOrder: -999999}); - - this.filteredVisitStore = Ext4.create('Ext.data.Store', { - model : 'LABKEY.VaccineDesign.Visit', - data : data, - sorters : [{property: 'DisplayOrder', direction: 'ASC'},{property: 'SequenceNumMin', direction: 'ASC'}] - }); - } - - return this.filteredVisitStore; - }, - - getNewVisitLabelField : function() - { - if (!this.newVisitLabelField) - { - this.newVisitLabelField = Ext4.create('Ext.form.field.Text', { - name: 'newVisitLabel', - disabled: this.getFilteredVisitStore().getCount() > 0, - fieldLabel: 'Label', - labelWidth: 50, - width: 300, - style: 'margin-left: 15px;' - }); - - this.newVisitLabelField.on('change', this.updateSelectBtnState, this); - } - - return this.newVisitLabelField; - }, - - getNewVisitMinField : function() - { - if (!this.newVisitMinField) - { - this.newVisitMinField = Ext4.create('Ext.form.field.Number', { - name: 'newVisitRangeMin', - hideLabel: true, - width: this.isTimepoint ? 100 : 80, - emptyText: 'min', - hideTrigger: true, - decimalPrecision: 4 - }); - - this.newVisitMinField.on('change', this.updateSelectBtnState, this); - } - - return this.newVisitMinField; - }, - - getNewVisitMaxField : function() - { - if (!this.newVisitMaxField) - { - this.newVisitMaxField = Ext4.create('Ext.form.field.Number', { - name: 'newVisitRangeMax', - hideLabel: true, - width: this.isTimepoint ? 100 : 80, - emptyText: 'max', - hideTrigger: true, - decimalPrecision: 4 - }); - - this.newVisitMinField.on('change', this.updateSelectBtnState, this); - } - - return this.newVisitMaxField; - }, - - getNewVisitMinMaxContainer : function() - { - if (!this.newVisitMinMaxContainer) - { - this.newVisitMinMaxContainer = Ext4.create('Ext.form.FieldContainer', { - layout: 'hbox', - style: 'margin-left: 15px; margin-bottom: 15px;', - fieldLabel: (this.isTimepoint ? 'Day' : 'Sequence') + ' Range', - labelWidth: this.isTimepoint ? 85 : 125, - disabled: this.getFilteredVisitStore().getCount() > 0, - items: [ - this.getNewVisitMinField(), - {xtype: 'label', width: 10}, // spacer - this.getNewVisitMaxField() - ] - }); - } - - return this.newVisitMinMaxContainer; - }, - - getSelectBtn : function() - { - if (!this.selectBtn) - { - this.selectBtn = Ext4.create('Ext.button.Button', { - text: this.getFilteredVisitStore().getCount() == 0 ? 'Submit' : 'Select', - disabled: true, - scope: this, - handler: function() { - var values = this.getFormPanel().getValues(); - - if (values['visitType'] == 'existing') - this.fireEvent('selectexistingvisit', this, values['existingVisit'] == -1 ? 'ALL' : values['existingVisit']); - else - this.createNewVisit(); - } - }); - } - - return this.selectBtn; - }, - - updateSelectBtnState : function() - { - var values = this.getFormPanel().getValues(); - - if (values['visitType'] == 'existing') - this.getSelectBtn().setDisabled(values['existingVisit'] == ''); - else - this.getSelectBtn().setDisabled(values['newVisitLabel'] == '' || values['newVisitRangeMin'] == ''); - }, - - getCancelBtn : function() - { - if (!this.cancelBtn) - { - this.cancelBtn = Ext4.create('Ext.button.Button', { - text: 'Cancel', - scope: this, - handler: function() { - this.fireEvent('closewindow', this); - } - }); - } - - return this.cancelBtn; - }, - - createNewVisit : function() - { - this.getEl().mask('Creating new visit...'); - var values = this.getFormPanel().getValues(); - - LABKEY.Ajax.request({ - url : LABKEY.ActionURL.buildURL('study', 'createVisitForVaccineDesign.api'), - method : 'POST', - jsonData: { - label: values['newVisitLabel'], - sequenceNumMin: values['newVisitRangeMin'], - sequenceNumMax: values['newVisitRangeMax'], - showByDefault: true - }, - success: function(response) { - var resp = Ext4.decode(response.responseText); - if (resp.success) - this.fireEvent('newvisitcreated', this, resp); - else - this.onFailure(); - }, - failure: function(response) { - var resp = Ext4.decode(response.responseText); - this.onFailure(resp.exception); - }, - scope : this - }); - }, - - onFailure : function(text) - { - Ext4.Msg.show({ - title: 'Error', - msg: text || 'Unknown error occurred.', - icon: Ext4.Msg.ERROR, - buttons: Ext4.Msg.OK - }); - - this.getEl().unmask(); - } -}); \ No newline at end of file diff --git a/studydesign/webapp/study/vaccineDesign/vaccineDesign.lib.xml b/studydesign/webapp/study/vaccineDesign/vaccineDesign.lib.xml deleted file mode 100644 index 0cdb9ab00a3..00000000000 --- a/studydesign/webapp/study/vaccineDesign/vaccineDesign.lib.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -