From b859905c13cd5515804b46fb8958ee1888696ff2 Mon Sep 17 00:00:00 2001 From: Binal Patel Date: Wed, 6 Oct 2021 16:00:39 -0700 Subject: [PATCH 1/4] Fix receiver's data entry page not to show 'Reorder' button (#110) --- .../src/client/RequestEntry/RequestEntry.tsx | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/WNPRC_Purchasing/src/client/RequestEntry/RequestEntry.tsx b/WNPRC_Purchasing/src/client/RequestEntry/RequestEntry.tsx index 3a3503c34..1f2e05e0a 100644 --- a/WNPRC_Purchasing/src/client/RequestEntry/RequestEntry.tsx +++ b/WNPRC_Purchasing/src/client/RequestEntry/RequestEntry.tsx @@ -52,6 +52,9 @@ export const App: FC = memo(() => { const [rejectQCStateId, setRejectQCStateId] = useState(); const [isReorder, setIsReorder] = useState(ActionURL.getParameter('isReorder') || false); const { isAdmin: hasPurchasingAdminPermission, canUpdate: hasPurchasingUpdatePermission, canInsert: hasPurchasingInsertPermission } = getServerContext().user; + const [isRequester, setIsRequester] = useState(); + const [isReceiver, setIsReceiver] = useState(); + const [isPurchaseAdmin, setIsPurchaseAdmin] = useState(); // equivalent to componentDidMount and componentDidUpdate (if with dependencies, then equivalent to componentDidUpdate) useEffect(() => { @@ -59,6 +62,10 @@ export const App: FC = memo(() => { const reqRowId = ActionURL.getParameter('requestRowId'); setRequestId(reqRowId); + setIsRequester(hasPurchasingInsertPermission && !hasPurchasingAdminPermission && !hasPurchasingUpdatePermission); + setIsReceiver(hasPurchasingUpdatePermission && !hasPurchasingAdminPermission); + setIsPurchaseAdmin(hasPurchasingAdminPermission); + (async () => { //get QCStates const qcStateVals = await getData('core', 'qcState', 'RowId, Label'); @@ -454,9 +461,9 @@ export const App: FC = memo(() => { onInputChange={requestOrderModelChange} model={requestOrderModel} hasRequestId={!!requestId} - isRequester={hasPurchasingInsertPermission && !hasPurchasingAdminPermission && !hasPurchasingUpdatePermission} - isAdmin={hasPurchasingAdminPermission} - isReceiver={hasPurchasingUpdatePermission && !hasPurchasingAdminPermission} + isRequester={isRequester} + isAdmin={isPurchaseAdmin} + isReceiver={isReceiver} isReorder={isReorder} /> { @@ -478,9 +485,9 @@ export const App: FC = memo(() => { lineItems={lineItems} errorMsg={lineItemErrorMsg} hasRequestId={!!requestId} - isRequester={hasPurchasingInsertPermission && !hasPurchasingAdminPermission && !hasPurchasingUpdatePermission} - isAdmin={hasPurchasingAdminPermission} - isReceiver={hasPurchasingUpdatePermission && !hasPurchasingAdminPermission} + isRequester={isRequester} + isAdmin={isPurchaseAdmin} + isReceiver={isReceiver} isReorder={isReorder} /> { - (requestId && !isReorder) && ( + (requestId && !isReorder && !isReceiver) && ( + + + + + + + + + + + + +
+
+ +
+ +
Edit Single Day Water
+ + +
Enter Single Day Water
+ +
+ +
+ +
+ +
+

{{animalIdForm}}

+
+
+ +
+ +
+

{{dateForm}}

+ +
+
+
+ +
+

{{projectForm}}

+ +
+
+ +
+ +
+ <%----%> + + <%--

{{volumeCoalesced}}

--%> +
+ +
+ + +
+ +
+

+ +

+ +
+
+ + + + + +
+ +
+

+ +

+ + +
+
+ +
+ +
+

+ +

+
+
+ +
+ +
+ +
+
+
+ + <%----%> + + + + + + + + + +
+
+ +
+ +
+
+
+ + +
+
+
Calendar
+
+
+ +
+ + {{$parent.husbandryAssignmentLookup[$data].title}} + +
+ + +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/pages/husbandry/WaterCalendarWebPartFactory.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/pages/husbandry/WaterCalendarWebPartFactory.java new file mode 100644 index 000000000..08fd71672 --- /dev/null +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/pages/husbandry/WaterCalendarWebPartFactory.java @@ -0,0 +1,50 @@ +package org.labkey.wnprc_ehr.pages.husbandry; + +import org.json.JSONArray; +import org.labkey.api.view.BaseWebPartFactory; +import org.labkey.api.view.JspView; +import org.labkey.api.view.Portal; +import org.labkey.api.view.ViewContext; +import org.labkey.api.view.WebPartView; +import org.labkey.webutils.api.JspPage; + +import javax.validation.constraints.NotNull; +import java.util.Map; + +public class WaterCalendarWebPartFactory extends BaseWebPartFactory{ + + + + private Portal.WebPart _webPart; + + public WaterCalendarWebPartFactory(){super ("Water Calendar");} + + public WebPartView getWebPartView (@NotNull ViewContext portalCtx, @NotNull Portal.WebPart webpart){ + + Map props = webpart.getPropertyMap(); + + String animalIds = webpart.getPropertyMap().get("animalIds"); + Integer numberOfRenders = Integer.parseInt(webpart.getPropertyMap().get("numberOfRenders")); + + String[] unBindComponents = webpart.getPropertyMap().get("unbindComponents").split(","); + //String[] unBindComponents = {"waterInfoPanel","calendarLegend","waterExceptionPanel"}; + //JSONArray unBindJSON = new JSONArray(Arrays.asList(unBindComponents)); + JSONArray unBindJSON = new JSONArray(); + for (int i = 0; i < unBindComponents.length; i++){ + unBindJSON.put(unBindComponents[i]); + } + + + + + JspView view = new JspView("/org/labkey/wnprc_ehr/pages/husbandry/WaterCalendar.jsp"); + view.setTitle("Water Calendar"); + view.setFrame(WebPartView.FrameType.PORTAL); + + + + JspPage page = new JspPage(view, numberOfRenders,unBindJSON); + page.setFrame(WebPartView.FrameType.PORTAL); + return page; + } +} diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/schemas/WNPRC_Schema.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/schemas/WNPRC_Schema.java index 3cb5e3f86..8d9bf091e 100644 --- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/schemas/WNPRC_Schema.java +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/schemas/WNPRC_Schema.java @@ -5,38 +5,25 @@ import org.jetbrains.annotations.Nullable; import org.json.JSONArray; import org.json.JSONObject; -import org.labkey.api.cache.CacheManager; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; -import org.labkey.api.data.ContainerManager; import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbSchemaType; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.TableInfo; import org.labkey.api.ehr.security.EHRRequestPermission; import org.labkey.api.ehr.security.EHRVeterinarianPermission; -import org.labkey.api.exp.ChangePropertyDescriptorException; -import org.labkey.api.exp.OntologyManager; -import org.labkey.api.exp.PropertyDescriptor; -import org.labkey.api.exp.property.Domain; -import org.labkey.api.exp.property.DomainProperty; -import org.labkey.api.exp.property.SystemProperty; import org.labkey.api.ldk.table.CustomPermissionsTable; import org.labkey.api.query.SimpleUserSchema; import org.labkey.api.security.User; import org.labkey.api.security.permissions.InsertPermission; import org.labkey.api.security.permissions.UpdatePermission; -import org.labkey.api.study.Dataset; -import org.labkey.api.study.Study; -import org.labkey.api.study.StudyService; import org.labkey.dbutils.api.SimpleQueryFactory; import org.labkey.webutils.api.json.JsonUtils; import org.labkey.wnprc_ehr.schemas.enum_lookups.NecropsyDeliveryOptionTable; import org.labkey.wnprc_ehr.schemas.enum_lookups.NecropsySampleDeliveryDestination; -import java.beans.Introspector; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -77,6 +64,10 @@ public WNPRC_Schema(User user, Container container) { _container = container; } + public static DbSchema getWnprcDbSchema() { + return DbSchema.get(NAME, DbSchemaType.Module); + } + @Override public TableInfo createTable(String name, ContainerFilter cf) { Map enumTables = getEnumTables(); diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsEditPermission.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsEditPermission.java new file mode 100644 index 000000000..cb19040a1 --- /dev/null +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsEditPermission.java @@ -0,0 +1,12 @@ +package org.labkey.wnprc_ehr.security.permissions; + +import org.labkey.api.security.permissions.AbstractPermission; + +public class WNPRCAnimalRequestsEditPermission extends AbstractPermission +{ + public WNPRCAnimalRequestsEditPermission() + { + super("WNPRC EHR Animal Requests Edit Perm", + "This permission allows the user to edit certain animal requests fields."); + } +} diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsViewPermission.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsViewPermission.java new file mode 100644 index 000000000..d42c3638d --- /dev/null +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/permissions/WNPRCAnimalRequestsViewPermission.java @@ -0,0 +1,12 @@ +package org.labkey.wnprc_ehr.security.permissions; + +import org.labkey.api.security.permissions.AbstractPermission; + +public class WNPRCAnimalRequestsViewPermission extends AbstractPermission +{ + public WNPRCAnimalRequestsViewPermission() + { + super("WNPRC EHR Animal Requests View Perm", + "This permission allows the user to view certain animal requests fields."); + } +} diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/roles/WNPRCAnimalRequestsRole.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/roles/WNPRCAnimalRequestsRole.java new file mode 100644 index 000000000..fd3fc5c46 --- /dev/null +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/security/roles/WNPRCAnimalRequestsRole.java @@ -0,0 +1,20 @@ +package org.labkey.wnprc_ehr.security.roles; + +import org.labkey.api.security.permissions.Permission; +import org.labkey.api.security.roles.AbstractRole; +import org.labkey.wnprc_ehr.WNPRC_EHRModule; +import org.labkey.wnprc_ehr.security.permissions.WNPRCAnimalRequestsEditPermission; +import org.labkey.wnprc_ehr.security.permissions.WNPRCAnimalRequestsViewPermission; + +public class WNPRCAnimalRequestsRole extends AbstractRole +{ + + public WNPRCAnimalRequestsRole(){ + this("WNPRC Animal Requests", "Role for viewing/editing animal request items", WNPRCAnimalRequestsViewPermission.class, WNPRCAnimalRequestsEditPermission.class); + } + + protected WNPRCAnimalRequestsRole(String name, String description, Class... perms) { + super(name, description, WNPRC_EHRModule.class, perms); + } + +} diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java index f33fd86b4..b82a5cba8 100644 --- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java +++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java @@ -18,40 +18,47 @@ import org.apache.log4j.Logger; import org.labkey.api.data.AbstractTableInfo; import org.labkey.api.data.BaseColumnInfo; +import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; import org.labkey.api.data.DataColumn; import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbSchemaType; +import org.labkey.api.data.DisplayColumn; +import org.labkey.api.data.DisplayColumnFactory; import org.labkey.api.data.JdbcType; import org.labkey.api.data.RenderContext; import org.labkey.api.data.SQLFragment; -import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; import org.labkey.api.data.WrappedColumn; import org.labkey.api.ehr.EHRService; import org.labkey.api.exp.api.StorageProvisioner; import org.labkey.api.ldk.table.AbstractTableCustomizer; -import org.labkey.api.query.DetailsURL; import org.labkey.api.query.ExprColumn; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryForeignKey; import org.labkey.api.query.QueryService; import org.labkey.api.query.UserSchema; +import org.labkey.api.security.User; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.study.Dataset; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; import org.labkey.api.util.GUID; +import org.labkey.api.util.HtmlString; +import org.labkey.api.util.HtmlStringBuilder; import org.labkey.api.util.PageFlowUtil; import org.labkey.api.util.StringExpressionFactory; import org.labkey.api.view.ActionURL; import org.labkey.dbutils.api.SimplerFilter; -//import org.labkey.ehr.EHRSchema; +import org.labkey.wnprc_ehr.security.permissions.WNPRCAnimalRequestsEditPermission; +import org.labkey.wnprc_ehr.security.permissions.WNPRCAnimalRequestsViewPermission; import java.io.IOException; import java.io.Writer; -import java.util.Collections; +import java.util.ArrayList; +import java.util.List; /** * User: bimber @@ -93,7 +100,12 @@ else if (table.getName().equalsIgnoreCase("breeding_encounters") && table.getSch customizeDemographicsTable((AbstractTableInfo) table); } else if (matches(table, "ehr", "tasks")) { customizeTasksTable((AbstractTableInfo) table); + } else if (matches(table, "wnprc", "animal_requests")) { + customizeAnimalRequestsTable((AbstractTableInfo) table); } + else if (table.getName().equalsIgnoreCase("waterOrders")) + appendEnddateFuture((AbstractTableInfo) table, "enddate"); + } } @@ -252,11 +264,11 @@ private void customizeFeedingTable(AbstractTableInfo ti) GUID ehrEntityId = ehrContainer.getEntityId(); ehrEntityId.toString(); SQLFragment sql = new SQLFragment("(SELECT " + - " (CASE WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log' and container ='"+ ehrEntityId.toString() + "')" + + " (CASE WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log' and container ='"+ ehrEntityId.toString() + "')" + "THEN (ROUND(amount*"+ conv.toString() + ") || ' flower')" + - "WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log (gluten-free)' and container ='"+ ehrEntityId.toString() + "')" + + "WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log (gluten-free)' and container ='"+ ehrEntityId.toString() + "')" + "THEN (ROUND(amount*"+ conv.toString() + ") || ' flower')" + - "WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'flower' and container ='" + ehrEntityId.toString() + "')" + + "WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'flower' and container ='" + ehrEntityId.toString() + "')" + "THEN (ROUND(amount*" + invconv.toString() + ") || ' log')" + "ELSE " + " 'bad data'" + @@ -268,14 +280,14 @@ private void customizeFeedingTable(AbstractTableInfo ti) String chowLookup = "chowLookup"; SQLFragment sql2 = new SQLFragment("(SELECT " + - " (CASE WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log' and container ='"+ ehrEntityId.toString() + "')" + - "THEN (CAST (amount as text) || ' log')" + - "WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log (gluten-free)' and container ='"+ ehrEntityId.toString() + "')" + - "THEN (CAST (amount as text) || ' log (gluten-free)')" + - "WHEN type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'flower' and container ='"+ ehrEntityId.toString() + "')" + - "THEN (CAST (amount as text) || ' flower')" + + " (CASE WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log' and container ='"+ ehrEntityId.toString() + "')" + + "THEN (CAST (amount as text) || ' log')" + + "WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'log (gluten-free)' and container ='"+ ehrEntityId.toString() + "')" + + "THEN (CAST (amount as text) || ' log (gluten-free)')" + + "WHEN " + ExprColumn.STR_TABLE_ALIAS + ".type = (SELECT Rowid from ehr_lookups.lookups where set_name = 'feeding_types' and value = 'flower' and container ='"+ ehrEntityId.toString() + "')" + + "THEN (CAST (amount as text) || ' flower')" + "ELSE " + - " 'bad data'" + + " 'bad data'" + "END) as ChowLookup)"); ExprColumn newCol2 = new ExprColumn(ti, chowLookup, sql2, JdbcType.VARCHAR); newCol2.setLabel("Chow Lookup"); @@ -651,6 +663,140 @@ private void customizeDemographicsTable(AbstractTableInfo table) newCol.setDescription("Returns the animal's original vendor id."); table.addColumn(newCol); } + + if (table.getColumn("sire") == null) + { + String sire_new = "sire"; + TableInfo arrival = getRealTableForDataset(table, "arrival"); + TableInfo birth = getRealTableForDataset(table, "birth"); + TableInfo demographics = getRealTableForDataset(table, "demographics"); + + // Here we want a union of the birth and arrival tables to get the sire of the animal + // For the given demographic animal id, it checks the arrival records to see if there is a matching sire + // which is the actual vendor ID of an animal that arrived at the center, and it uses that animal's id as the sire as long as the species between the two are the same + // if that is not the case, it will fall back on the arrival and birth records, and if still no sire found in arrival or births, + // we fall back on the "old" data in the demographic table, called sire_old + String arrivalAndBirthQuery = "( " + + "SELECT " + + "COALESCE ( " + + "(SELECT " + + "a.participantid as sire " + + "FROM " + + "studydataset." + arrival.getName() + " a, studydataset." + arrival.getName() + " b " + + " WHERE " + + " b.participantid = " + ExprColumn.STR_TABLE_ALIAS + ".participantid AND lower(a.vendor_id) = lower(b.sire) AND lower(a.vendor_id) != lower(a.participantid) " + + " AND (SELECT x.species from studydataset." + demographics.getName() +" x WHERE x.participantid = a.participantid) = " + + " (SELECT y.species from studydataset." + demographics.getName() +" y WHERE y.participantid = " + ExprColumn.STR_TABLE_ALIAS + ".participantid) " + + "ORDER BY " + + "b.modified DESC " + + "LIMIT 1), " + + + "(SELECT " + + "sire " + + "FROM " + + "studydataset." + arrival.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + "ORDER BY " + + "modified DESC " + + "LIMIT 1), " + + + "(SELECT " + + "sire " + + "FROM " + + "studydataset." + birth.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + "ORDER BY " + + "modified DESC" + + " LIMIT 1), " + + + "(SELECT " + + "sire_old " + + "FROM " + + "studydataset." + demographics.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + " LIMIT 1) " + + ") AS sire " + + ")"; + SQLFragment sql = new SQLFragment(arrivalAndBirthQuery); + ExprColumn newCol = new ExprColumn(table, sire_new, sql, JdbcType.VARCHAR); + newCol.setLabel("Sire"); + newCol.setDescription("This is a calculated column that first checks arrival records and swaps out for the " + + "'real' animal id if a matching vendor id was found and the species of the animals are matching, " + + "if not found it will use whatever is in the " + + "arrival record, if not found, it then checks birth records, and if no sire is found there, it " + + "then finally uses the historic demographic text field called 'sire_old' as the sire."); + table.addColumn(newCol); + } + if (table.getColumn("dam") == null) + { + String dam_new = "dam"; + TableInfo arrival = getRealTableForDataset(table, "arrival"); + TableInfo birth = getRealTableForDataset(table, "birth"); + TableInfo demographics = getRealTableForDataset(table, "demographics"); + + // Here we want a union of the birth and arrival tables to get the dam of the animal + // For the given demographic animal id, it checks the arrival records to see if there is a matching dam + // which is the actual vendor ID of an animal that arrived at the center, and it uses that animal's id as the dam, as long as the species between the two are the same + // if that is not the case, it will fall back on the arrival and birth records, and if still no dam found in arrival or births, + // we fall back on the "old" data in the demographic table, called dam_old + String arrivalAndBirthQuery = "( " + + "SELECT " + + "COALESCE ( " + + "(SELECT " + + "a.participantid as dam " + + "FROM " + + "studydataset." + arrival.getName() + " a, studydataset." + arrival.getName() + " b " + + " WHERE " + + " b.participantid = " + ExprColumn.STR_TABLE_ALIAS + ".participantid AND lower(a.vendor_id) = lower(b.dam) AND lower(a.vendor_id) != lower(a.participantid) " + + " AND (SELECT x.species from studydataset." + demographics.getName() +" x WHERE x.participantid = a.participantid) = " + + " (SELECT y.species from studydataset." + demographics.getName() +" y WHERE y.participantid = " + ExprColumn.STR_TABLE_ALIAS + ".participantid) " + + "ORDER BY " + + "b.modified DESC " + + "LIMIT 1), " + + + "(SELECT " + + "dam " + + "FROM " + + "studydataset." + arrival.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + "ORDER BY " + + "modified DESC " + + "LIMIT 1), " + + + "(SELECT " + + "dam " + + "FROM " + + "studydataset." + birth.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + "ORDER BY " + + "modified DESC" + + " LIMIT 1), " + + + "(SELECT " + + "dam_old " + + "FROM " + + "studydataset." + demographics.getName() + + " WHERE " + + "participantid =" + ExprColumn.STR_TABLE_ALIAS + ".participantid " + + " LIMIT 1) " + + ") AS dam " + + ")"; + + SQLFragment sql = new SQLFragment(arrivalAndBirthQuery); + ExprColumn newCol = new ExprColumn(table, dam_new, sql, JdbcType.VARCHAR); + newCol.setLabel("Dam"); + newCol.setDescription("This is a calculated column that first checks arrival records and swaps out for the " + + "'real' animal id if a matching vendor id was found and the species of the animals are matching, " + + "if not found it will use whatever is in the " + + "arrival record, if not found, it then checks birth records, and if no dam is found there, it " + + "then finally uses the historic demographic text field called 'dam_old' as the dam."); + table.addColumn(newCol); + } } private TableInfo getRealTableForDataset(AbstractTableInfo ti, String name) @@ -866,6 +1012,281 @@ public Object getDisplayValue(RenderContext ctx) } } + public static class AnimalIdsToOfferColumn extends DataColumn { + public AnimalIdsToOfferColumn(ColumnInfo colInfo) { + super(colInfo); + } + + @Override + public Object getValue(RenderContext ctx) { + return super.getValue(ctx); + } + + } + + public static class AnimalIdsToOfferColumnQCStateConditional extends DataColumn { + private User _currentUser; + public AnimalIdsToOfferColumnQCStateConditional(ColumnInfo colInfo, User currentUser) { + super(colInfo); + _currentUser = currentUser; + } + + @Override + public void renderGridCellContents(RenderContext ctx, Writer out) throws IOException + { + if ("Request: Pending".equals(ctx.get("QCState$Label"))) + { + out.write(""); + } + else if (_currentUser.getUserId() == (Integer) ctx.get("createdBy")) + { + super.renderGridCellContents(ctx, out); + } + else + { + out.write(""); + } + } + } + + public static class AnimalRequestsEditLinkConditional extends DataColumn + { + private User _currentUser; + + public AnimalRequestsEditLinkConditional(ColumnInfo colInfo, User currentUser) + { + super(colInfo); + _currentUser = currentUser; + } + + @Override + public HtmlString getFormattedHtml(RenderContext ctx) + { + String edit; + if (_currentUser.getUserId() == (Integer) ctx.get("createdBy")) + { + edit = ""; + } + else { + edit = ""; + } + return HtmlString.unsafe(edit); + } + + + } + + public static class AnimalRequestsEditLinkShow extends DataColumn { + public AnimalRequestsEditLinkShow(ColumnInfo colInfo) { + super(colInfo); + } + + @Override + public HtmlString getFormattedHtml(RenderContext ctx) + { + String edit; + edit = ""; + return HtmlString.unsafe(edit); + } + } + + public static class AnimalReportLink extends DataColumn { + public AnimalReportLink(ColumnInfo colInfo) { + super(colInfo); + } + + @Override + public Object getValue(RenderContext ctx) { + return super.getValue(ctx); + } + } + + public static class AnimalReportLinkQCStateConditional extends DataColumn { + private User _currentUser; + public AnimalReportLinkQCStateConditional(ColumnInfo colInfo, User currentUser) { + super(colInfo); + _currentUser = currentUser; + } + + @Override + public Object getValue(RenderContext ctx) + { + if ("Request: Pending".equals(ctx.get("QCState$Label"))) + { + return ""; + } + else if (_currentUser.getUserId() == (Integer) ctx.get("createdBy")) + { + return super.getValue(ctx); + } + else + { + return ""; + } + } + @Override + public Object getDisplayValue(RenderContext ctx) + { + if ("Request: Pending".equals(ctx.get("QCState$Label"))) + { + return ""; + } + else if (_currentUser.getUserId() == (Integer) ctx.get("createdBy")) + { + return super.getDisplayValue(ctx); + } + else + { + return ""; + } + } + @Override + public HtmlString getFormattedHtml(RenderContext ctx) + { + HtmlStringBuilder emptyString = HtmlStringBuilder.of(); + if ("Request: Pending".equals(ctx.get("QCState$Label"))) + { + return emptyString.getHtmlString(); + } + else if (_currentUser.getUserId() == (Integer) ctx.get("createdBy")) + { + return super.getFormattedHtml(ctx); + } + else + { + return emptyString.getHtmlString(); + } + } + + } + + private void customizeAnimalRequestsTable(AbstractTableInfo table) + { + + UserSchema us = getStudyUserSchema(table); + if (us == null) + { + return; + } + User currentUser = us.getUser(); + + //Nail down individual fields for editing, unless user has permission + List readOnlyFields = new ArrayList<>(); + readOnlyFields.add("QCState"); + readOnlyFields.add("dateapprovedordenied"); + readOnlyFields.add("animalsorigin"); + readOnlyFields.add("dateordered"); + readOnlyFields.add("datearrival"); + for (String item : readOnlyFields) + { + if (table.getColumn(item) != null) + { + BaseColumnInfo col = (BaseColumnInfo) table.getColumn(item); + if (!us.getContainer().hasPermission(currentUser, WNPRCAnimalRequestsEditPermission.class) && !us.getContainer().hasPermission(currentUser, AdminPermission.class)) + { + col.setReadOnly(true); + } + } + } + + + if (table.getColumn("edit") == null){ + + String edit = "edit"; + + String theQuery = "( " + + "(SELECT 'edit')" + + ")"; + + SQLFragment sql = new SQLFragment(theQuery); + + ExprColumn newCol = new ExprColumn(table, edit, sql, JdbcType.VARCHAR); + table.addColumn(newCol); + newCol.setDisplayColumnFactory(new DisplayColumnFactory() + { + + @Override + public DisplayColumn createRenderer(ColumnInfo colInfo) + { + if (us.getContainer().hasPermission(currentUser, WNPRCAnimalRequestsEditPermission.class) || us.getContainer().hasPermission(currentUser, AdminPermission.class)) + { + return new AnimalRequestsEditLinkShow(colInfo); + } + else + { + return new AnimalRequestsEditLinkConditional(colInfo, currentUser); + } + } + }); + } + + //re-render animalidsoffer column + if (table.getColumn("animalidstooffer") != null) + { + BaseColumnInfo col = (BaseColumnInfo) table.getColumn("animalidstooffer"); + col.setLabel("Animal Ids"); + if (us.getContainer().hasPermission(currentUser, WNPRCAnimalRequestsViewPermission.class) || us.getContainer().hasPermission(currentUser, AdminPermission.class)){ + col.setDisplayColumnFactory(colInfo -> new AnimalIdsToOfferColumn(colInfo)); + } + else{ + col.setHidden(true); + col.setDisplayColumnFactory(colInfo -> new AnimalIdsToOfferColumnQCStateConditional(colInfo, currentUser)); + } + } + + //create animal history report link from a set of animal ids + if (table.getColumn("animal_history_link") == null) + { + String animal_history_link = "animal_history_link"; + + String theQuery = "( " + + "(SELECT " + + " CASE WHEN a.animalidstooffer is not null " + + "THEN 'Report Link' " + + "ELSE '' " + + " END AS animal_history_link " + + " FROM wnprc.animal_requests a " + + "WHERE a.rowid=" + ExprColumn.STR_TABLE_ALIAS + ".rowid LIMIT 1) " + + ")"; + + SQLFragment sql = new SQLFragment(theQuery); + + ExprColumn newCol = new ExprColumn(table, animal_history_link, sql, JdbcType.VARCHAR); + newCol.setLabel("Animal History Link"); + newCol.setDescription("Provides a link to the animal history records given the animal ids that were selected."); + newCol.setURL(StringExpressionFactory.create("ehr-animalHistory.view?#subjects:${animalidstooffer}&inputType:multiSubject&showReport:0&activeReport:abstractReport")); + table.addColumn(newCol); + newCol.setDisplayColumnFactory(new DisplayColumnFactory() + { + @Override + public DisplayColumn createRenderer(ColumnInfo colInfo) + { + if (us.getContainer().hasPermission(currentUser, WNPRCAnimalRequestsViewPermission.class) || us.getContainer().hasPermission(currentUser, AdminPermission.class)) + { + return new AnimalReportLink(colInfo); + } + else + { + return new AnimalReportLinkQCStateConditional(colInfo, currentUser); + } + } + }); + + } + } + private BaseColumnInfo getWrappedIdCol(UserSchema us, AbstractTableInfo ds, String name, String queryName) { String ID_COL = "Id"; @@ -901,6 +1322,34 @@ public UserSchema getUserSchema(AbstractTableInfo ds, String name) return null; } + private void appendEnddateFuture(AbstractTableInfo ti, String sourceColName) + { + ColumnInfo sourceCol = ti.getColumn(sourceColName); + if (sourceCol == null) + { + _log.error("Unable to find column: " + sourceColName + " on table " + ti.getSelectName()); + return; + } + + String name = sourceCol.getName(); + if (ti.getColumn(name + "CoalescedFuture") == null) + { + SQLFragment sql = new SQLFragment("CAST(COALESCE(").append(sourceCol.getValueSql(ExprColumn.STR_TABLE_ALIAS)).append(", {fn timestampadd(SQL_TSI_DAY, 365, {fn curdate()})}) as date)"); + //SQLFragment sql = new SQLFragment("CAST(COALESCE(" + ExprColumn.STR_TABLE_ALIAS + "." + sourceCol.getSelectName() + ", {fn curdate()} + integer '365') as date)"); + ExprColumn col = new ExprColumn(ti, name + "CoalescedFuture", sql, JdbcType.DATE); + col.setCalculated(true); + col.setUserEditable(false); + col.setHidden(true); + col.setLabel(col.getLabel() + ", CoalescedFuture"); + + if (sourceCol.getFormat() != null) + col.setFormat(sourceCol.getFormat()); + + ti.addColumn(col); + } + + } + //TODO: Look how to use another UI to allow for better support for virtual columns /* public static class ContactsColumn extends DataColumn { diff --git a/WNPRC_EHR/src/weight/containers/Forms/EnterWeightFormContainer.tsx b/WNPRC_EHR/src/weight/containers/Forms/EnterWeightFormContainer.tsx index 57eb4c934..a55d69c18 100644 --- a/WNPRC_EHR/src/weight/containers/Forms/EnterWeightFormContainer.tsx +++ b/WNPRC_EHR/src/weight/containers/Forms/EnterWeightFormContainer.tsx @@ -87,16 +87,16 @@ const EnterWeightFormContainer: React.FunctionComponent = props => { copyformdata.forEach(item => { if (vals["weight"]["value"]){ - item["weight"] = Object.assign({}, vals["weight"]); + item["weight"]["value"] = vals["weight"]["value"]; } if (vals["date"]["value"]){ - item["date"] = Object.assign({}, vals["date"]); + item["date"]["value"] = vals["date"]["value"]; } if (vals["restraint"]["value"]){ - item["restraint"] = Object.assign({}, vals["restraint"]); + item["restraint"]["value"] = vals["restraint"]["value"]; } if (vals["remark"]["value"]){ - item["remark"] = Object.assign({}, vals["remark"]); + item["remark"]["value"] = vals["remark"]["value"]; } }); diff --git a/WNPRC_EHR/test/sampledata/wnprc_ehr/wnprcEhrTestStudyPolicy.xml b/WNPRC_EHR/test/sampledata/wnprc_ehr/wnprcEhrTestStudyPolicy.xml new file mode 100644 index 000000000..85b1840fd --- /dev/null +++ b/WNPRC_EHR/test/sampledata/wnprc_ehr/wnprcEhrTestStudyPolicy.xml @@ -0,0 +1,429 @@ + + + ADVANCED_WRITE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java index eccb60961..f7680b41b 100644 --- a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java +++ b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java @@ -171,6 +171,12 @@ public BrowserType bestBrowser() return BrowserType.CHROME; } + @Override + protected File getStudyPolicyXML() + { + return TestFileUtils.getSampleData("wnprc_ehr/wnprcEhrTestStudyPolicy.xml"); + } + @BeforeClass @LogMethod public static void doSetup() throws Exception { @@ -649,7 +655,7 @@ public void testJETWithNonGenCreditAccount() DataRegionTable jetRegionTable = new DataRegionTable("query", this); assertEquals("Wrong jet item count: ", 1, jetRegionTable.getDataRowCount()); - List expectedRowData = Arrays.asList(NON_GEN_CREDIT_ACCOUNT_ID, "$8.00"); + List expectedRowData = Arrays.asList(NON_GEN_CREDIT_ACCOUNT_ID, "8.00"); List actualRowData = jetRegionTable.getRowDataAsText(0, "Project", "Amount"); assertEquals("Wrong row data for CSV to JET Preview report ", expectedRowData, actualRowData); } @@ -2205,6 +2211,7 @@ public void testEnterWeights() throws IOException, CommandException JSONObject wt = (JSONObject) r.getRows().get(0).get("weight"); TestLogger.log(wt.get("value").toString()); Assert.assertEquals(null, WEIGHT_VAL, wt.get("value")); + testWeightToRestraintObjectIdRelationship(); } @Test @@ -2282,6 +2289,7 @@ public void testWeightSubmitForReview() throws IOException, CommandException JSONObject id = (JSONObject) t.getRows().get(0).get("assignedto"); Assert.assertEquals(null, defaultItem, id.get("value").toString()); + testWeightToRestraintObjectIdRelationship(); } @Test @@ -2421,6 +2429,7 @@ public void testEditBatch() throws IOException, CommandException clickNewButton("edit-batch"); WebElement el = Locator.id("weight-bulk").findElement(getDriver()); el.sendKeys(WEIGHT_VAL.toString()); + WebElement el2 = fillAnInput("restraint-bulk", "T"); clickNewButton("submit-bulk"); waitUntilElementIsClickable("submit-all-btn"); clickNewButton("submit-all-btn"); @@ -2433,6 +2442,18 @@ public void testEditBatch() throws IOException, CommandException JSONObject wt = (JSONObject) r.getRows().get(i).get("weight"); Assert.assertEquals(null, WEIGHT_VAL, wt.get("value")); } + testWeightToRestraintObjectIdRelationship(); + } + + //for the most recently entered weight / restraint pair, do we have matching "FK" lookups + //from the weight record to the restraint record. e.g., weight|restraint_objectid == restraint|objectid ? + public void testWeightToRestraintObjectIdRelationship() throws IOException, CommandException + { + //get the weight data + SelectRowsResponse w = fetchWeightData(); + JSONObject wt = (JSONObject) w.getRows().get(0).get("restraint_objectid"); + SelectRowsResponse r = fetchRestraintDataGivenObjectId((String) wt.get("value")); + Assert.assertEquals(1, r.getRows().size()); } @Test @@ -2476,6 +2497,7 @@ public void testAddRestraint() throws IOException, CommandException SelectRowsResponse c = fetchRestraintDataGivenObjectId(objectid.get("value").toString()); JSONObject rt = (JSONObject) c.getRows().get(0).get("restraintType"); Assert.assertEquals(null, "Table-Top", rt.get("value")); + testWeightToRestraintObjectIdRelationship(); } diff --git a/WNPRC_EHR/tools/pg_testserver_change.sql b/WNPRC_EHR/tools/pg_testserver_change.sql index 1fcfc17bf..2accefa31 100644 --- a/WNPRC_EHR/tools/pg_testserver_change.sql +++ b/WNPRC_EHR/tools/pg_testserver_change.sql @@ -86,6 +86,15 @@ WHERE (SELECT s.Category FROM prop.PropertySets s WHERE s.Set = p.Set) = 'ld AND p.Name = 'enabled' ; +UPDATE prop.Properties p +SET Value = 'false' +WHERE (SELECT s.Category FROM prop.PropertySets s WHERE s.Set = p.Set) = 'org.labkey.ldk.notifications.config' + AND p.Name = 'serviceEnabled' +; + +DELETE FROM prop.properties p +WHERE (SELECT s.Category FROM prop.PropertySets s WHERE s.Set = p.Set) = 'org.labkey.ldk.notifications.status'; + UPDATE ehr.module_properties p SET stringvalue = 'test-ehr-do-not-reply@primate.wisc.edu' WHERE p.prop_name = 'site_email' @@ -175,12 +184,5 @@ VALUES (32, 'Incomplete Treatments', '29e3860b-02b5-102d-b524-493dbd27b599', 1005, '2011-09-27 13:11:20.188', 1005, '2011-09-27 13:11:20.188', 1975) ; --- Switch to using non-ssl LDAP -UPDATE prop.Properties p -SET Value = 'ldap://ldap.primate.wisc.edu' -WHERE (SELECT s.Category FROM prop.PropertySets s WHERE s.Set = p.Set) = 'LDAPAuthentication' - AND p.Name = 'Servers' -; - -- We've left a bit of a mess, so it's best to vacuum before guests arrive. (Deleting doesn't reclaim the space on it's own, and we just deleted 40-50GB) --VACUUM FULL; diff --git a/WNPRC_r24/resources/etls/WNPRC_demographics.xml b/WNPRC_r24/resources/etls/WNPRC_demographics.xml index 239921bed..5864c9f83 100644 --- a/WNPRC_r24/resources/etls/WNPRC_demographics.xml +++ b/WNPRC_r24/resources/etls/WNPRC_demographics.xml @@ -5,23 +5,41 @@ Copy to target - - + + + animalId + neprcId + primateId + birth + death + status + objectid + species + sourceColony + currentColony + gender + dam + sire + modified + date + u24_animals + + + - + - + - diff --git a/WNPRC_r24/resources/etls/WNPRC_weights.xml b/WNPRC_r24/resources/etls/WNPRC_weights.xml index 0b1febe5b..041eda29b 100644 --- a/WNPRC_r24/resources/etls/WNPRC_weights.xml +++ b/WNPRC_r24/resources/etls/WNPRC_weights.xml @@ -6,7 +6,11 @@ Copy to target - + + + + + diff --git a/WNPRC_r24/resources/etls/WNPRC_weights_queued_update.xml b/WNPRC_r24/resources/etls/WNPRC_weights_queued_update.xml index 9f7500a5a..d9560dd02 100644 --- a/WNPRC_r24/resources/etls/WNPRC_weights_queued_update.xml +++ b/WNPRC_r24/resources/etls/WNPRC_weights_queued_update.xml @@ -4,9 +4,9 @@ Queue up package related ETLs - + Copy weight rows to be deleted to local table - + objectid modified @@ -17,7 +17,7 @@ Copy weights to local table - + AnimalId primateId diff --git a/WNPRC_u24/build.gradle b/WNPRC_u24/build.gradle new file mode 100644 index 000000000..f33c8bc1d --- /dev/null +++ b/WNPRC_u24/build.gradle @@ -0,0 +1,10 @@ +apply plugin: 'java' +apply plugin: 'org.labkey.module' +compileJava { + options.compilerArgs << "-Xlint:unchecked" + +} + +dependencies { + implementation project(":server:modules:wnprc-modules:WNPRC_EHR") +} diff --git a/WNPRC_u24/module.properties b/WNPRC_u24/module.properties new file mode 100644 index 000000000..168077389 --- /dev/null +++ b/WNPRC_u24/module.properties @@ -0,0 +1,6 @@ +ModuleClass: org.labkey.wnprc_u24.wnprc_u24Module +Label: Marmoset WNPRC U24 module +License: Apache 2.0 +LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 +ManageVersion: false +SupportedDatabases: pgsql \ No newline at end of file diff --git a/WNPRC_u24/resources/etls/WNPRC_arrival.xml b/WNPRC_u24/resources/etls/WNPRC_arrival.xml new file mode 100644 index 000000000..7029f1cb1 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_arrival.xml @@ -0,0 +1,25 @@ + + + arrival + WNPRC Marmoset Arrivals + + + Copy to target + + + id + date + source + vendor_id + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_assignments.xml b/WNPRC_u24/resources/etls/WNPRC_assignments.xml new file mode 100644 index 000000000..821f003a9 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_assignments.xml @@ -0,0 +1,37 @@ + + + assignments + WNPRC Marmosets + + + Copy to target + + + id + date + enddate + project + project/title + project/projectType + + + + + + + + + + + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_demographics.xml b/WNPRC_u24/resources/etls/WNPRC_demographics.xml new file mode 100644 index 000000000..9593ec0c8 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_demographics.xml @@ -0,0 +1,46 @@ + + + demographics + WNPRC Marmosets + + + Copy to target + + + animalId + neprcId + primateId + birth + death + status + objectid + species + sourceColony + currentColony + gender + dam + sire + modified + date + u24_animals + + + + + + + + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_departure.xml b/WNPRC_u24/resources/etls/WNPRC_departure.xml new file mode 100644 index 000000000..9d8c3c025 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_departure.xml @@ -0,0 +1,24 @@ + + + departure + WNPRC Marmoset Departures + + + Copy to target + + + id + date + destination + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_pedigree.xml b/WNPRC_u24/resources/etls/WNPRC_pedigree.xml new file mode 100644 index 000000000..f61be483c --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_pedigree.xml @@ -0,0 +1,33 @@ + + + Pedigree + WNPRC Marmoset Pedigree + + + Copy to target + + + id + id/demographics/vendor_id + BirthDate + dam + sire + gender_code + source + Species + + + + + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_weights.xml b/WNPRC_u24/resources/etls/WNPRC_weights.xml new file mode 100644 index 000000000..e98b27f07 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_weights.xml @@ -0,0 +1,24 @@ + + + WNPRC weights third component (update) + WNPRC weights third component (update) + + + Copy to target + + + + + + + + + + + + + + + + diff --git a/WNPRC_u24/resources/etls/WNPRC_weights_queued_update.xml b/WNPRC_u24/resources/etls/WNPRC_weights_queued_update.xml new file mode 100644 index 000000000..a873f0ff7 --- /dev/null +++ b/WNPRC_u24/resources/etls/WNPRC_weights_queued_update.xml @@ -0,0 +1,47 @@ + + + WNPRC queued weights update + Queue up package related ETLs + + + + Copy weight rows to be deleted to local table + + + objectid + modified + + + + + + + Copy weights to local table + + + AnimalId + primateId + date + weight + objectid + modified + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/queries/study/Demographics.query.xml b/WNPRC_u24/resources/queries/study/Demographics.query.xml new file mode 100644 index 000000000..7b274cd2b --- /dev/null +++ b/WNPRC_u24/resources/queries/study/Demographics.query.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + true + + + Gender + + + Species + + + MM-dd-yy + Date of Birth + + + MM-dd-yy + Date of Death + + + Status + + + Dam + + study + animal + id + + /query/executeQuery.view?schemaName=${schemaName}&query.queryName=Demographics&query.participantId~eq=${dam} + + + Sire + + study + animal + id + + /query/executeQuery.view?schemaName=${schemaName}&query.queryName=Demographics&query.participantId~eq=${sire} + + + true + + + true + + + true + + + true + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_u24/resources/queries/study/Demographics/.qview.xml b/WNPRC_u24/resources/queries/study/Demographics/.qview.xml new file mode 100644 index 000000000..63d68f0f2 --- /dev/null +++ b/WNPRC_u24/resources/queries/study/Demographics/.qview.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/queries/study/Weight/.qview.xml b/WNPRC_u24/resources/queries/study/Weight/.qview.xml new file mode 100644 index 000000000..c805594b5 --- /dev/null +++ b/WNPRC_u24/resources/queries/study/Weight/.qview.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/referenceStudy/datasets/datasets_manifest.xml b/WNPRC_u24/resources/referenceStudy/datasets/datasets_manifest.xml new file mode 100644 index 000000000..97a2fe95c --- /dev/null +++ b/WNPRC_u24/resources/referenceStudy/datasets/datasets_manifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/referenceStudy/datasets/datasets_metadata.xml b/WNPRC_u24/resources/referenceStudy/datasets/datasets_metadata.xml new file mode 100644 index 000000000..2ee6bfcbe --- /dev/null +++ b/WNPRC_u24/resources/referenceStudy/datasets/datasets_metadata.xml @@ -0,0 +1,133 @@ + + + + Contains up to one row of demographics data for each Animal Id. + + + varchar + Animal Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + ptid + + 32 + + + varchar + NEPRC Id + http://www.w3.org/2001/XMLSchema#string + 32 + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + http://cpas.labkey.com/Study#VisitDate + false + Date + + + timestamp + DOB + http://www.w3.org/2001/XMLSchema#dateTime + + + timestamp + DOD + http://www.w3.org/2001/XMLSchema#dateTime + + + varchar + Status + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Object Id + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Species + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Source Colony + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Current Colony + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Sex + http://www.w3.org/2001/XMLSchema#string + 4000 + + + varchar + Dam + http://cpas.labkey.com/Study#ParticipantId + http://www.w3.org/2001/XMLSchema#string + false + 4000 + + + varchar + Sire + http://cpas.labkey.com/Study#ParticipantId + http://www.w3.org/2001/XMLSchema#string + false + 4000 + + + Demographics +
+ + Contains up to one row of weight data for each Animal Id/Date/objectid combination. + + + varchar + Animal Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + ptid + + 32 + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + http://cpas.labkey.com/Study#VisitDate + false + Date + + + double + Weight (kg) + http://www.w3.org/2001/XMLSchema#double + + + varchar + Object Id + http://www.w3.org/2001/XMLSchema#string + 4000 + true + + + Weight +
+
\ No newline at end of file diff --git a/WNPRC_u24/resources/referenceStudy/datasets/wnprc_u24.dataset b/WNPRC_u24/resources/referenceStudy/datasets/wnprc_u24.dataset new file mode 100644 index 000000000..667aa4358 --- /dev/null +++ b/WNPRC_u24/resources/referenceStudy/datasets/wnprc_u24.dataset @@ -0,0 +1,19 @@ + # default group can be used to avoid repeating definitions for each dataset +# +# action=[REPLACE,APPEND,DELETE] (default:REPLACE) +# deleteAfterImport=[TRUE|FALSE] (default:FALSE) + +default.action=REPLACE +default.deleteAfterImport=FALSE + +# map a source tsv column (right side) to a property name or full propertyURI (left) +# predefined properties: ParticipantId, SiteId, VisitId, Created +default.property.ParticipantId=ptid +default.property.Created=dfcreate + +# use to map from filename->datasetid +# NOTE: if there are NO explicit import definitions, we will try to import all files matching pattern +# NOTE: if there are ANY explicit mapping, we will only import listed datasets + +default.filePattern=dataset(\\d*).tsv +default.importAllMatches=TRUE diff --git a/WNPRC_u24/resources/referenceStudy/study.xml b/WNPRC_u24/resources/referenceStudy/study.xml new file mode 100644 index 000000000..455efa7dc --- /dev/null +++ b/WNPRC_u24/resources/referenceStudy/study.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/schemas/dbscripts/postgresql/wnprc_u24-0.00-21.30.sql b/WNPRC_u24/resources/schemas/dbscripts/postgresql/wnprc_u24-0.00-21.30.sql new file mode 100644 index 000000000..b6b8fb1d9 --- /dev/null +++ b/WNPRC_u24/resources/schemas/dbscripts/postgresql/wnprc_u24-0.00-21.30.sql @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018-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. + */ + +-- Create schema, tables, indexes, and constraints used for wnprc_u24 module here +-- All SQL VIEW definitions should be created in wnprc_u24-create.sql and dropped in wnprc_u24-drop.sql +-- Modify by Daniel Nicolalde to Postgres 07/26/2019 +CREATE SCHEMA wnprc_u24; + +CREATE TABLE wnprc_u24.lookupSets( + RowId SERIAL NOT NULL, + SetName VARCHAR(32) NOT NULL, + Label VARCHAR(32) NOT NULL, + ObjectId VARCHAR(128) NULL, + Created TIMESTAMP NULL, + CreatedBy USERID NULL, + Modified TIMESTAMP NULL, + ModifiedBy USERID NULL, + DiCreated TIMESTAMP NULL, + DiModified TIMESTAMP NULL, + DiCreatedBy USERID NULL, + DiModifiedBy USERID NULL, + Container entityId NOT NULL, + + CONSTRAINT pk_wnprc_u24_lookupsets PRIMARY KEY ( RowId ), + CONSTRAINT fk_wnprc_u24_lookupsets_container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) +); + + +CREATE UNIQUE INDEX idx_wnprc_u24_lookupSets_setname ON wnprc_u24.lookupSets ( SetName ); + + +ALTER TABLE wnprc_u24.LookupSets ALTER ObjectId SET DEFAULT (ehr.uuid()); + + +CREATE TABLE wnprc_u24.lookups( + RowId SERIAL NOT NULL, + SetName VARCHAR(32) NOT NULL, + Value VARCHAR(128) NOT NULL, + SortOrder INTEGER NULL, + DateDisabled TIMESTAMP NULL, + ObjectId VARCHAR(128) NULL, + Created TIMESTAMP NULL, + CreatedBy USERID NULL, + Modified TIMESTAMP NULL, + ModifiedBy USERID NULL, + DiCreated TIMESTAMP NULL, + DiModified TIMESTAMP NULL, + DiCreatedBy USERID NULL, + DiModifiedBy USERID NULL, + Container entityId NOT NULL, + + CONSTRAINT pk_wnprc_u24_lookups PRIMARY KEY ( RowId ), + CONSTRAINT fk_wnprc_u24_lookups_SetName FOREIGN KEY (SetName) REFERENCES wnprc_u24.LookupSets (SetName), + CONSTRAINT fk_wnprc_u24_lookups_container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) +); + + +CREATE UNIQUE INDEX idx_wnprc_u24_lookups_setname ON wnprc_u24.lookups ( SetName , VALUE ); + +ALTER TABLE wnprc_u24.Lookups ALTER ObjectId SET DEFAULT (ehr.uuid()); + +CREATE TABLE wnprc_u24.RowsToDelete( + ObjectId EntityId NOT NULL, + Modified TIMESTAMP NOT NULL, + CONSTRAINT pk_wnprc_u24_RowsToDelete PRIMARY KEY ( ObjectId ) +); + +CREATE TABLE wnprc_u24.WeightStaging ( + AnimalId VARCHAR(32) NOT NULL, + PrimateId VARCHAR(10) NOT NULL, + Date TIMESTAMP NOT NULL, + Weight NUMERIC(7,4) NOT NULL, + ObjectId EntityId NOT NULL, + Created TIMESTAMP NULL, + CreatedBy USERID NULL, + Modified TIMESTAMP NULL, + ModifiedBy USERID NULL, + WeightMVIndicator VARCHAR(32) NULL, + + CONSTRAINT pk_wnprc_u24_weight_staging PRIMARY KEY (ObjectId ) +); + + diff --git a/WNPRC_u24/resources/schemas/wnprc_u24.xml b/WNPRC_u24/resources/schemas/wnprc_u24.xml new file mode 100644 index 000000000..d3e3e77c1 --- /dev/null +++ b/WNPRC_u24/resources/schemas/wnprc_u24.xml @@ -0,0 +1,182 @@ + + + + + DETAILED + Provides lookup values. + RowId + + + false + true + + + varchar + Set Name + false + 32 + + + varchar + 32 + true + + + true + + + + + + + false + true + true + + core + Users + UserId + + + + false + true + true + + + false + true + true + + core + Users + UserId + + + + false + true + true + + + false + true + + + LookupSets +
+ + DETAILED + Provides lookup values. + RowId + + + false + true + + + varchar + Set Name + false + 32 + + + varchar + false + 128 + + + integer + Sort Order + true + + + timestamp + Date + true + Date + + + true + + + + + + + false + true + true + + core + Users + UserId + + + + false + true + true + + + false + true + true + + core + Users + UserId + + + + false + true + true + + + false + true + + + Lookups +
+ + + + + + RowsToDelete +
+ + Table to stage remote ETLs into. + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/WNPRC_u24/resources/views/welcome.html b/WNPRC_u24/resources/views/welcome.html new file mode 100644 index 000000000..229fc33b6 --- /dev/null +++ b/WNPRC_u24/resources/views/welcome.html @@ -0,0 +1 @@ +

Welcome to the u24 module

\ No newline at end of file diff --git a/WNPRC_u24/resources/views/welcome.view.xml b/WNPRC_u24/resources/views/welcome.view.xml new file mode 100644 index 000000000..024ced75a --- /dev/null +++ b/WNPRC_u24/resources/views/welcome.view.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/WNPRC_u24/resources/views/welcome.webpart.xml b/WNPRC_u24/resources/views/welcome.webpart.xml new file mode 100644 index 000000000..ff4fe068f --- /dev/null +++ b/WNPRC_u24/resources/views/welcome.webpart.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/view/hello.jsp b/WNPRC_u24/src/org/labkey/wnprc_u24/view/hello.jsp new file mode 100644 index 000000000..aa99d05c6 --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/view/hello.jsp @@ -0,0 +1,25 @@ +<% +/* + * Copyright (c) 2016-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. + */ +%> +<%@ page import="org.labkey.api.data.Container" %> +<%@ page import="org.labkey.api.security.User" %> +<%@ page extends="org.labkey.api.jsp.JspBase" %> +<% + Container c = getContainer(); + User user = getUser(); +%> +Hello, and welcome to the wnprc_u24 module. \ No newline at end of file diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24ContainerListener.java b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24ContainerListener.java new file mode 100644 index 000000000..2cbbc0855 --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24ContainerListener.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016-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.wnprc_u24; + +import org.jetbrains.annotations.NotNull; +import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerManager.ContainerListener; +import org.labkey.api.security.User; +import java.util.Collections; +import java.util.Collection; + +import java.beans.PropertyChangeEvent; + +public class wnprc_u24ContainerListener implements ContainerListener +{ + @Override + public void containerCreated(Container c, User user) + { + } + + @Override + public void containerDeleted(Container c, User user) + { + } + + @Override + public void propertyChange(PropertyChangeEvent evt) + { + } + + @Override + public void containerMoved(Container c, Container oldParent, User user) + { + } + + @NotNull @Override + public Collection canMove(Container c, Container newParent, User user) + { + return Collections.emptyList(); + } +} \ No newline at end of file diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Controller.java b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Controller.java new file mode 100644 index 000000000..d55dee8c6 --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Controller.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-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.wnprc_u24; + +import org.labkey.api.action.SimpleViewAction; +import org.labkey.api.action.SpringActionController; +import org.labkey.api.security.RequiresPermission; +import org.labkey.api.security.permissions.ReadPermission; +import org.labkey.api.view.JspView; +import org.labkey.api.view.NavTree; +import org.springframework.validation.BindException; +import org.springframework.web.servlet.ModelAndView; + +public class wnprc_u24Controller extends SpringActionController +{ + private static final DefaultActionResolver _actionResolver = new DefaultActionResolver(wnprc_u24Controller.class); + public static final String NAME = "wnprc_u24"; + + public wnprc_u24Controller() + { + setActionResolver(_actionResolver); + } + + @RequiresPermission(ReadPermission.class) + public class BeginAction extends SimpleViewAction + { + public ModelAndView getView(Object o, BindException errors) throws Exception + { + return new JspView("/org/labkey/wnprc_u24/view/hello.jsp"); + } + + @Override + public void addNavTrail(NavTree root) + { + } + } +} diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Manager.java b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Manager.java new file mode 100644 index 000000000..e0e61c694 --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Manager.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-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.wnprc_u24; + +public class wnprc_u24Manager +{ + private static final wnprc_u24Manager _instance = new wnprc_u24Manager(); + + private wnprc_u24Manager() + { + // prevent external construction with a private default constructor + } + + public static wnprc_u24Manager get() + { + return _instance; + } +} \ No newline at end of file diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Module.java b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Module.java new file mode 100644 index 000000000..b2bc9769e --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Module.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016-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.wnprc_u24; + +import org.jetbrains.annotations.NotNull; +import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerManager; +import org.labkey.api.data.DbSchema; +import org.labkey.api.data.DbSchemaType; +import org.labkey.api.module.DefaultModule; +import org.labkey.api.module.Module; +import org.labkey.api.module.ModuleContext; +import org.labkey.api.query.DefaultSchema; +import org.labkey.api.query.QuerySchema; +import org.labkey.api.query.QueryService; +import org.labkey.api.view.WebPartFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +public class wnprc_u24Module extends DefaultModule +{ + public static final String NAME = "wnprc_u24"; + + @Override + public String getName() + { + return NAME; + } + + @Override + public Double getSchemaVersion() + { + return 21.300; + } + + @Override + public boolean hasScripts() + { + return true; + } + + @Override + @NotNull + protected Collection createWebPartFactories() + { + return Collections.emptyList(); + } + + @Override + protected void init() + { + addController(wnprc_u24Controller.NAME, wnprc_u24Controller.class); + } + + @Override + public void doStartup(ModuleContext moduleContext) + { + // add a container listener so we'll know when our container is deleted: + ContainerManager.addContainerListener(new wnprc_u24ContainerListener()); + + for (final String schemaName : getSchemaNames()) + { + final DbSchema dbSchema = DbSchema.get(schemaName, DbSchemaType.Module); + DefaultSchema.registerProvider(dbSchema.getQuerySchemaName(), new DefaultSchema.SchemaProvider(this) + { + public QuerySchema createSchema(final DefaultSchema schema, Module module) + { + DbSchema dbSchema = DbSchema.get(schemaName, DbSchemaType.Module); + return QueryService.get().createSimpleUserSchema(dbSchema.getQuerySchemaName(), null, schema.getUser(), schema.getContainer(), dbSchema); + } + }); + } + } + + + @Override + @NotNull + public Collection getSummary(Container c) + { + return Collections.emptyList(); + } + + @Override + @NotNull + public Set getSchemaNames() + { + return Collections.singleton(wnprc_u24Schema.NAME); + } +} \ No newline at end of file diff --git a/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Schema.java b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Schema.java new file mode 100644 index 000000000..ed651b323 --- /dev/null +++ b/WNPRC_u24/src/org/labkey/wnprc_u24/wnprc_u24Schema.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-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.wnprc_u24; + +import org.labkey.api.data.DbSchema; +import org.labkey.api.data.DbSchemaType; +import org.labkey.api.data.dialect.SqlDialect; + +public class wnprc_u24Schema +{ + private static final wnprc_u24Schema _instance = new wnprc_u24Schema(); + public static final String NAME = "wnprc_u24"; + + public static wnprc_u24Schema getInstance() + { + return _instance; + } + + private wnprc_u24Schema() + { + // private constructor to prevent instantiation from + // outside this class: this singleton should only be + // accessed via org.labkey.wnprc_u24.wnprc_u24Schema.getInstance() + } + + public DbSchema getSchema() + { + return DbSchema.get(NAME, DbSchemaType.Module); + } + + public SqlDialect getSqlDialect() + { + return getSchema().getSqlDialect(); + } +} diff --git a/WebUtils/.gitignore b/WebUtils/.gitignore new file mode 100644 index 000000000..9e9cd1500 --- /dev/null +++ b/WebUtils/.gitignore @@ -0,0 +1 @@ +resources/web/gen \ No newline at end of file diff --git a/WebUtils/api-src/org/labkey/webutils/api/JspPage.java b/WebUtils/api-src/org/labkey/webutils/api/JspPage.java new file mode 100644 index 000000000..7b0fd3391 --- /dev/null +++ b/WebUtils/api-src/org/labkey/webutils/api/JspPage.java @@ -0,0 +1,100 @@ +package org.labkey.webutils.api; + +import org.json.JSONArray; +import org.labkey.api.view.JspView; +import org.labkey.api.view.template.ClientDependency; +import org.labkey.webutils.api.model.JspPageModel; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jon on 1/13/16. + */ +public class JspPage extends JspView { + //static private String _packagePathDir = WebUtilsService.getPackageDirFromClass(JspPage.class); + private Integer publicNumberOfRenders =0 ; + private JSONArray publicUnBindComponents = new JSONArray(); + + public JspPage(JspView view) { + this(view, new JspPageModel()); + } + + //Adding second constructor to allow rendering JSP under a LabKey webPart + //numberofRenders check if it is not the first time the page renders + //unBindComponents components in the page to rebind to ko.observables. + public JspPage(JspView view, Integer numberOfRenders, JSONArray unBindComponents){ + super("/org/labkey/webutils/view/JspPage.jsp", new JspPageModel()); + + publicNumberOfRenders = numberOfRenders; + publicUnBindComponents = unBindComponents; + + this.setBody(view); + + // Add universal client dependencies. + List dependencyPaths = Arrays.asList( + "/webutils/lib/webutils", + "/webutils/models/models" + ); + for(String path : dependencyPaths) { + this.addClientDependency(ClientDependency.fromPath(path)); + } + + + if (numberOfRenders == 0){ + + // Add some Knockout templates. + List templates = Arrays.asList( + "lk-table", + "lk-querytable", + "lk-input-textarea" + ); + for( String name: templates ) { + this.getModelBean().addTemplate(WebUtilsService.get().getKnockoutTemplate(name)); + } + + // Set the frame to none, since we don't want WebPartView to add any wrapping HTML, such as a web part. + this.setFrame(FrameType.NONE); + + } + + + } + + public JspPage(JspView view, JspPageModel model) { + super("/org/labkey/webutils/view/JspPage.jsp", model); + + // Set the body to the passed in view + this.setBody(view); + + // Add universal client dependencies. + List dependencyPaths = Arrays.asList( + "/webutils/lib/webutils", + "/webutils/models/models" + ); + for(String path : dependencyPaths) { + this.addClientDependency(ClientDependency.fromPath(path)); + } + + // Add some Knockout templates. + List templates = Arrays.asList( + "lk-table", + "lk-querytable", + "lk-input-textarea" + ); + for( String name: templates ) { + this.getModelBean().addTemplate(new JspView<>("/org/labkey/webutils/view/knockout_components/" + name + ".jsp")); + } + + // Set the frame to none, since we don't want WebPartView to add any wrapping HTML, such as a web part. + this.setFrame(FrameType.NONE); + } + + public Integer getNumberOfRenders(){ + return publicNumberOfRenders; + + } + public JSONArray getUnbindComponents(){ + return publicUnBindComponents; + } +} diff --git a/WebUtils/api-src/org/labkey/webutils/api/WebUtilsService.java b/WebUtils/api-src/org/labkey/webutils/api/WebUtilsService.java index 64811a006..8d8110858 100644 --- a/WebUtils/api-src/org/labkey/webutils/api/WebUtilsService.java +++ b/WebUtils/api-src/org/labkey/webutils/api/WebUtilsService.java @@ -2,7 +2,6 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.data.Container; -import org.labkey.api.module.Module; import org.labkey.api.security.User; import org.labkey.api.view.JspView; import org.springframework.web.servlet.ModelAndView; @@ -73,4 +72,5 @@ public static String getPackageDirFromClass(Class clazz) { */ abstract public ModelAndView getJspPageFromView(JspView view); abstract public ModelAndView getJspReportPageFromView(JspView view); + abstract public JspView getKnockoutTemplate(String templateName); } diff --git a/WebUtils/copy-distributions.js b/WebUtils/copy-distributions.js new file mode 100644 index 000000000..263fcb0a6 --- /dev/null +++ b/WebUtils/copy-distributions.js @@ -0,0 +1,23 @@ +const fs = require('fs-extra'); + +function log(msg) { + process.stdout.write(msg); +} + +/** + * Copy fullCalendar distribution to module resources. + */ +function copyFullCalendarFiles() { + log('Copying fullCalendar distribution from npm package ... '); + + // You could choose to be more explicit here and copy just individual assets. + // For ease of understanding I've just copied the entire package's contents. + const apiDistDir = __dirname + '/node_modules/fullcalendar/'; + const targetDir = __dirname + '/resources/web/gen/lib/fullcalendar/'; + + fs.copy(apiDistDir, targetDir); + + log('Done.\n'); +} + +copyFullCalendarFiles(); \ No newline at end of file diff --git a/WebUtils/package-lock.json b/WebUtils/package-lock.json new file mode 100644 index 000000000..18325ccdf --- /dev/null +++ b/WebUtils/package-lock.json @@ -0,0 +1,150 @@ +{ + "name": "webutils", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fullcalendar": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-5.8.0.tgz", + "integrity": "sha512-yXHh9NA/cB3YIYQmD3Gj+rWmzL9lVAc4P6sTqJW/eMIkUZVhB8Qkyz96xArVsn90Jk/nAbZ0Opddl9RcoFN1Tg==" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/WebUtils/package.json b/WebUtils/package.json new file mode 100644 index 000000000..2c1bccfc4 --- /dev/null +++ b/WebUtils/package.json @@ -0,0 +1,39 @@ +{ + "name": "webutils", + "version": "1.0.0", + "description": "Web utilities and libraries", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "npm run build-prod", + "build-prod": "npm run copy-distributions", + "clean": "rimraf resources/web/gen/lib/fullcalendar", + "copy-distributions": "npm run clean && node copy-distributions.js", + "setup": "npm ci" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/WNPRC-EHR-Services/wnprc-modules.git" + }, + "keywords": [ + "web", + "utility", + "utils", + "javascript", + "library", + "libraries" + ], + "author": "gottfredsen@wisc.edu", + "license": "ISC", + "bugs": { + "url": "https://github.com/WNPRC-EHR-Services/wnprc-modules/issues" + }, + "homepage": "https://github.com/WNPRC-EHR-Services/wnprc-modules#readme", + "dependencies": { + "fullcalendar": "^5.8.0" + }, + "devDependencies": { + "fs-extra": "^9.1.0", + "rimraf": "^3.0.2" + } +} diff --git a/WebUtils/resources/credits/scripts.txt b/WebUtils/resources/credits/scripts.txt index 00b4305d3..3ca3eab42 100644 --- a/WebUtils/resources/credits/scripts.txt +++ b/WebUtils/resources/credits/scripts.txt @@ -1,5 +1,5 @@ {table} -Library|Version|Source|License|LabKey Dev|Purpose +Library|Version|Source|License|WNPRC Dev|Purpose Bootstrap|3.3.6|{link:Bootstrap|http://getbootstrap.com}|{link:MIT|http://opensource.org/licenses/mit-license.php}|jrichardson|UI C3|0.4.10|{link:C3|http://c3js.org}|{link:MIT|http://opensource.org/licenses/mit-license.php}|jrichardson|Charts/Visualizations Classify|0.0.42|{link:ClassifyJS|https://github.com/JonathonRichardson/ClassifyJS}|{link:Apache 2.0|https://github.com/JonathonRichardson/ClassifyJS/blob/master/LICENSE}|jrichardson|Class Structures diff --git a/WebUtils/resources/web/fullcalendar.lib.xml b/WebUtils/resources/web/fullcalendar.lib.xml new file mode 100644 index 000000000..c3bfca47f --- /dev/null +++ b/WebUtils/resources/web/fullcalendar.lib.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/WebUtils/resources/web/webutils/lib/webutils_core/api.js b/WebUtils/resources/web/webutils/lib/webutils_core/api.js index b5f8a2710..741808130 100644 --- a/WebUtils/resources/web/webutils/lib/webutils_core/api.js +++ b/WebUtils/resources/web/webutils/lib/webutils_core/api.js @@ -127,15 +127,13 @@ WebUtils.API = (function(){ params['query.columns'] = columns; } - /* - if (config.parameters) { - for (var propName in config.parameters) { - if (config.parameters.hasOwnProperty(propName)) { - dataObject[config.dataRegionName + '.param.' + propName] = config.parameters[propName]; - } - } - } - */ + if (config.parameters) { + for (var propName in config.parameters) { + if (config.parameters.hasOwnProperty(propName)) { + params['query.param.' + propName] = config.parameters[propName]; + } + } + } params = $.param(params); diff --git a/WebUtils/resources/web/webutils/lib/webutils_core/utilities/utilities.lib.xml b/WebUtils/resources/web/webutils/lib/webutils_core/utilities/utilities.lib.xml index cd4100c32..f8b0434e6 100644 --- a/WebUtils/resources/web/webutils/lib/webutils_core/utilities/utilities.lib.xml +++ b/WebUtils/resources/web/webutils/lib/webutils_core/utilities/utilities.lib.xml @@ -27,6 +27,5 @@ - \ No newline at end of file diff --git a/WebUtils/src/org/labkey/webutils/WebUtilsServiceImpl.java b/WebUtils/src/org/labkey/webutils/WebUtilsServiceImpl.java index 9e9ded40d..37bca233f 100644 --- a/WebUtils/src/org/labkey/webutils/WebUtilsServiceImpl.java +++ b/WebUtils/src/org/labkey/webutils/WebUtilsServiceImpl.java @@ -5,7 +5,7 @@ import org.labkey.api.view.JspView; import org.labkey.api.view.ViewContext; import org.labkey.api.view.WebPartView; -import org.labkey.webutils.view.JspPage; +import org.labkey.webutils.api.JspPage; import org.labkey.webutils.api.WebUtilsService; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -62,6 +62,13 @@ public ModelAndView getJspReportPageFromView(JspView view) { return getJspPage(reportView); } + @Override + public JspView getKnockoutTemplate(String templateName) + { + //String _packagePathDir = WebUtilsServiceImpl.getPackageDirFromClass(JspPage.class); + return new JspView<>("/org/labkey/webutils/view/knockout_components/" + templateName + ".jsp"); + } + private ModelAndView getJspPage(JspView view) { JspView jspPage = new JspPage(view); diff --git a/WebUtils/src/org/labkey/webutils/view/JspPage.java b/WebUtils/src/org/labkey/webutils/view/JspPage.java deleted file mode 100644 index 0e8db5bda..000000000 --- a/WebUtils/src/org/labkey/webutils/view/JspPage.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.labkey.webutils.view; - -import org.labkey.api.view.JspView; -import org.labkey.api.view.template.ClientDependency; -import org.labkey.webutils.WebUtilsServiceImpl; -import org.labkey.webutils.api.model.JspPageModel; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by jon on 1/13/16. - */ -public class JspPage extends JspView { - static private String _packagePathDir = WebUtilsServiceImpl.getPackageDirFromClass(JspPage.class); - - public JspPage(JspView view) { - this(view, new JspPageModel()); - } - - public JspPage(JspView view, JspPageModel model) { - super(_packagePathDir + "JspPage.jsp", model); - - // Set the body to the passed in view - this.setBody(view); - - // Add universal client dependencies. - List dependencyPaths = Arrays.asList( - "/webutils/lib/webutils", - "/webutils/models/models" - ); - for(String path : dependencyPaths) { - this.addClientDependency(ClientDependency.fromPath(path)); - } - - // Add some Knockout templates. - List templates = Arrays.asList( - "lk-table", - "lk-querytable", - "lk-input-textarea" - ); - for( String name: templates ) { - this.getModelBean().addTemplate(new JspView<>(_packagePathDir + "knockout_components/" + name + ".jsp")); - } - - // Set the frame to none, since we don't want WebPartView to add any wrapping HTML, such as a web part. - this.setFrame(FrameType.NONE); - } -} diff --git a/WebUtils/src/org/labkey/webutils/view/JspPage.jsp b/WebUtils/src/org/labkey/webutils/view/JspPage.jsp index da6cfd10a..af1fd391f 100644 --- a/WebUtils/src/org/labkey/webutils/view/JspPage.jsp +++ b/WebUtils/src/org/labkey/webutils/view/JspPage.jsp @@ -1,5 +1,5 @@ <%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.webutils.view.JspPage" %> +<%@ page import="org.labkey.webutils.api.JspPage" %> <%@ page import="org.springframework.web.servlet.ModelAndView" %> <%@ page import="java.util.List" %> <%@ page import="org.labkey.api.module.Module" %> @@ -8,14 +8,21 @@ <%@ page import="org.labkey.webutils.WebUtilsModule" %> <%@ page import="org.labkey.api.module.ModuleProperty" %> <%@ page import="org.labkey.webutils.api.model.JspPageModel" %> +<%@ page import="org.labkey.api.util.GUID" %> +<%@ page import="org.json.JSONArray" %> <%@ page extends="org.labkey.api.jsp.JspBase" %> <% JspPage view = (JspPage) HttpView.currentView(); JspPageModel model = (JspPageModel) getModelBean(); + Integer numberOfRenders = view.getNumberOfRenders(); + JSONArray unBindComponents = view.getUnbindComponents(); + + + String sufix = GUID.makeGUID(); %>