First commit. Taken from open source branch of internal sample-tracking application.
This commit is contained in:
2
resources/config.edn
Normal file
2
resources/config.edn
Normal file
@@ -0,0 +1,2 @@
|
||||
{:datomic #include "config/datomic.edn"
|
||||
:application #include "config/application.edn"}
|
||||
65
resources/config/application.edn
Normal file
65
resources/config/application.edn
Normal file
@@ -0,0 +1,65 @@
|
||||
{:roles {:admin "administrator"
|
||||
:editor "editor"
|
||||
:viewer "viewer"
|
||||
:site-admin "site-admin"
|
||||
:site-coordinator "site-coordinator"}
|
||||
:email {:sendgrid-api-key #env SENDGRID_API_KEY
|
||||
:sender #env MANIFEST_EMAIL_SENDER
|
||||
:manifest-recipient #env MANIFEST_EMAIL_RECIPIENT
|
||||
:send-manifest-emails #or [#env SEND_MANIFEST_EMAILS "false"]
|
||||
:send-vendor-emails #or [#env SEND_VENDOR_EMAILS "false"]}
|
||||
:temp-path "/tmp"
|
||||
:api-key #env API_KEY
|
||||
:firebase-js-credentials-path #env FIREBASE_JS_APPLICATION_CREDENTIALS
|
||||
:csv-files {:form-type {:headers [:form-type-fields
|
||||
:form-type-name
|
||||
:kit-item-no]}
|
||||
:kit-type {:headers [:study-name
|
||||
:cohort-name
|
||||
:kit-item-no
|
||||
:kit-name
|
||||
:sample-id-suffix
|
||||
:sample-name
|
||||
:kit-timepoints
|
||||
:ships-with-kit
|
||||
:sample-reminders
|
||||
:vendor-email
|
||||
:collection-date-optional
|
||||
:air-waybill-optional]}
|
||||
:site {:headers [:site
|
||||
:study-names]}
|
||||
:study {:headers [:study
|
||||
:participant-id-prefix
|
||||
:participant-id-regex
|
||||
:participant-id-validation-message
|
||||
:kit-id-prefix
|
||||
:kit-id-regex
|
||||
:kit-id-validation-message]}}
|
||||
:sample-export {:columns-to-drop [:kit-uuid :timezone :complete :deleted :sample-type-uuid
|
||||
:kit-type-uuid]
|
||||
:column-order [:study-name
|
||||
:site-name
|
||||
"Bioinventory Group Name"
|
||||
:sample-id
|
||||
:participant-id
|
||||
:timepoints
|
||||
"PK Timepoint"
|
||||
:collection-date
|
||||
:collection-time
|
||||
"processing-time"
|
||||
:sample-type-name
|
||||
:air-waybill
|
||||
:kit-type-name
|
||||
:kit-id]
|
||||
:columns-to-rename {:study-name "BioInventory Project Name"
|
||||
:site-name "Site"
|
||||
:sample-id "Originating ID"
|
||||
:participant-id "Participant ID"
|
||||
:timepoints "Visit"
|
||||
:collection-date "Collection Date"
|
||||
:collection-time "Collection Time"
|
||||
"processing-time" "Processing Time"
|
||||
:sample-type-name "Sample"
|
||||
:air-waybill "Air Waybill"
|
||||
:kit-type-name "Kit"
|
||||
:kit-id "Kit ID"}}}
|
||||
7
resources/config/datomic.edn
Normal file
7
resources/config/datomic.edn
Normal file
@@ -0,0 +1,7 @@
|
||||
{:endpoint #or [#env DATOMIC_ENDPOINT "localhost:8998"]
|
||||
:access-key #or [#env DATOMIC_ACCESS_KEY "myaccesskey"]
|
||||
:secret #or [#env DATOMIC_SECRET "mysecret"]
|
||||
:db-name #or [#env DATOMIC_DB_NAME "ereq-dev"]
|
||||
:validate-hostnames #profile {:default false
|
||||
:staging false
|
||||
:production false}}
|
||||
6
resources/log4j.properties
Executable file
6
resources/log4j.properties
Executable file
@@ -0,0 +1,6 @@
|
||||
log4j.rootLogger=WARN, console
|
||||
log4j.appender.console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.console.layout.ConversionPattern=%-5p %c: %m%n
|
||||
|
||||
log4j.logger.org.eclipse.jetty=WARN
|
||||
23
resources/logback.xml
Executable file
23
resources/logback.xml
Executable file
@@ -0,0 +1,23 @@
|
||||
<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
|
||||
<configuration>
|
||||
<!-- Console output -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
|
||||
<encoder>
|
||||
<pattern>%-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<!-- Only log level INFO and above -->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- Enable FILE and STDOUT appenders for all log messages.
|
||||
By default, only log at level INFO and above. -->
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<!-- For loggers in the ".*" namespace, log at all levels. -->
|
||||
<logger name="starter" level="INFO" />
|
||||
</configuration>
|
||||
345
resources/public/css/app.css
Executable file
345
resources/public/css/app.css
Executable file
@@ -0,0 +1,345 @@
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-Bold.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-Bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-BoldIta.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-BoldIta.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-Light.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-Light.woff') format('woff');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-Regular.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-LightIta.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-LightIta.woff') format('woff');
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk';
|
||||
src: url('fonts/PxGrotesk-RegularIta.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-RegularIta.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Px Grotesk Screen';
|
||||
src: url('fonts/PxGrotesk-Screen.woff2') format('woff2'),
|
||||
url('fonts/PxGrotesk-Screen.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
*{font-family:'Px Grotesk';}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
|
||||
.main {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin: 0px auto;
|
||||
padding: 5px;
|
||||
background: #343a40!important;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.header.manifest {
|
||||
background: white!important;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
.header .content {
|
||||
text-align: left;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
.header .content .title {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header .content .log-in-out-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.header .content .console-link {
|
||||
float: right;
|
||||
clear: right;
|
||||
}
|
||||
|
||||
.header .bars {
|
||||
text-align: left;
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.page-body.manifest {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.page-body table {
|
||||
text-align: left;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.list-body {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
max-width: 1500px;
|
||||
margin: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.list-body table {
|
||||
text-align: left;
|
||||
margin-bottom: .5em;
|
||||
border-collapse: separate;
|
||||
border-spacing: 10px 5px;
|
||||
}
|
||||
|
||||
div.spacer {
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
/* Apply style colors to a links */
|
||||
a {
|
||||
color: #685bc7!important;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #4a4c9b!important;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #313377!important;
|
||||
}
|
||||
|
||||
a.disabled {
|
||||
color: #a197e6!important;
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Apply theme colors to reactstrap elements */
|
||||
.btn-secondary {
|
||||
background-color: #685bc7;
|
||||
border-color: #685bc7;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #4a4c9b;
|
||||
border-color: #4a4c9b;
|
||||
}
|
||||
|
||||
.btn-secondary:active {
|
||||
background-color: #313377;
|
||||
border-color: #313377;
|
||||
}
|
||||
|
||||
.btn-secondary:focus {
|
||||
background-color: #313377;
|
||||
border-color: #313377;
|
||||
}
|
||||
|
||||
.btn-secondary:not(:disabled):not(.disabled):active {
|
||||
background-color: #313377;
|
||||
border-color: #313377;
|
||||
}
|
||||
|
||||
.btn-secondary.disabled,
|
||||
.btn-secondary:disabled {
|
||||
background-color: #a197e6;
|
||||
border-color: #a197e6;
|
||||
}
|
||||
|
||||
/* Make React Select Menu List items have black font */
|
||||
|
||||
.react-select__menu-list {
|
||||
color: black!important;
|
||||
}
|
||||
|
||||
/* Disable red box outline in Firefox */
|
||||
input:required {
|
||||
box-shadow:none!important;
|
||||
}
|
||||
input:invalid {
|
||||
box-shadow:none!important;
|
||||
}
|
||||
|
||||
select[name=amPm] {
|
||||
box-shadow:none!important;
|
||||
}
|
||||
|
||||
/* Blueprint Styling */
|
||||
|
||||
.bp3-input {
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
|
||||
/* Editext Styling */
|
||||
|
||||
button[editext] {
|
||||
border-radius: .25rem;
|
||||
padding: 2px;
|
||||
background-color: #685bc7;
|
||||
border-color: #685bc7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button[editext]:hover {
|
||||
background-color: #4a4c9b;
|
||||
border-color: #4a4c9b;
|
||||
}
|
||||
|
||||
button[editext="input"] {
|
||||
width: auto!important;
|
||||
}
|
||||
|
||||
/* Tooltip styling */
|
||||
.tooltip-inner {
|
||||
background: #343a40!important;
|
||||
}
|
||||
|
||||
.bs-tooltip-auto[x-placement^=top] .arrow::before, .bs-tooltip-top .arrow::before {
|
||||
border-top-color: #343a40!important;
|
||||
}
|
||||
|
||||
/* Datetime picker */
|
||||
.react-datetime-picker__wrapper {
|
||||
background: white;
|
||||
border: 0;
|
||||
border-radius: .25rem;
|
||||
font-size: 1.25em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.react-datetime-picker__inputGroup__input {
|
||||
color: black!important;
|
||||
}
|
||||
|
||||
.react-datetime-picker__inputGroup__input:invalid {
|
||||
background: none!important;
|
||||
}
|
||||
|
||||
/* Checkbox stuff */
|
||||
|
||||
.Checkbox_themed {
|
||||
padding-left: 1.2em;
|
||||
}
|
||||
|
||||
.Checkbox__input_themed {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.Checkbox__image_themed {
|
||||
position: absolute;
|
||||
margin-left: -1.2em;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.bootstrap-checkbox {
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.bootstrap-checkbox__image {
|
||||
margin-left: -1.5rem;
|
||||
|
||||
border: #adb5bd solid 1px;
|
||||
border-radius: .25rem;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
}
|
||||
.bootstrap-checkbox__input:checked + .bootstrap-checkbox__image {
|
||||
border-color: #564bac;
|
||||
background: #685bc7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA4IDgnPjxwYXRoIGZpbGw9JyNmZmYnIGQ9J002LjU2NC43NWwtMy41OSAzLjYxMi0xLjUzOC0xLjU1TDAgNC4yNiAyLjk3NCA3LjI1IDggMi4xOTN6Jy8+PC9zdmc+) no-repeat 50%/50% 50%;
|
||||
}
|
||||
.bootstrap-checkbox__input_indeterminate + .bootstrap-checkbox__image {
|
||||
border-color: #5247a8;
|
||||
background: #685bc7 url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e") no-repeat 50%/50% 50%;
|
||||
}
|
||||
.bootstrap-checkbox__input:disabled + .bootstrap-checkbox__image {
|
||||
border-color: #888c91;
|
||||
background-color: #b3b7bb;
|
||||
}
|
||||
.bootstrap-checkbox__input:checked:disabled + .bootstrap-checkbox__image,
|
||||
.bootstrap-checkbox__input_indeterminate:disabled + .bootstrap-checkbox__image {
|
||||
border-color: #8077c0;
|
||||
background-color: #a197e6;
|
||||
}
|
||||
.bootstrap-checkbox__input:focus + .bootstrap-checkbox__image {
|
||||
box-shadow: 0 0 0 0.2rem #776cbe;
|
||||
}
|
||||
|
||||
.bootstrap-checkbox__label {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Date picker stuff */
|
||||
|
||||
.bp3-datepicker .DayPicker-Day.DayPicker-Day--selected {
|
||||
background-color: #685bc7!important;
|
||||
}
|
||||
7
resources/public/css/bootstrap.min.css
vendored
Executable file
7
resources/public/css/bootstrap.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
1
resources/public/css/bootstrap.min.css.map
Executable file
1
resources/public/css/bootstrap.min.css.map
Executable file
File diff suppressed because one or more lines are too long
BIN
resources/public/css/fonts/PxGrotesk-Bold.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Bold.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Bold.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Bold.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-BoldIta.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-BoldIta.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-BoldIta.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-BoldIta.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Light.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Light.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Light.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Light.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-LightIta.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-LightIta.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-LightIta.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-LightIta.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Regular.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Regular.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Regular.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Regular.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-RegularIta.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-RegularIta.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-RegularIta.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-RegularIta.woff2
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Screen.woff
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Screen.woff
Normal file
Binary file not shown.
BIN
resources/public/css/fonts/PxGrotesk-Screen.woff2
Normal file
BIN
resources/public/css/fonts/PxGrotesk-Screen.woff2
Normal file
Binary file not shown.
BIN
resources/public/favicon-16x16.png
Normal file
BIN
resources/public/favicon-16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 644 B |
BIN
resources/public/favicon-32x32.png
Normal file
BIN
resources/public/favicon-32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 975 B |
BIN
resources/public/images/bars.png
Normal file
BIN
resources/public/images/bars.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/public/images/logo_dark.png
Normal file
BIN
resources/public/images/logo_dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
resources/public/images/logo_light.png
Normal file
BIN
resources/public/images/logo_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
30
resources/public/index.html
Executable file
30
resources/public/index.html
Executable file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>PICI Sample Tracking</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/css/app.css" rel="stylesheet">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main role="main" class="main">
|
||||
<div id="app"></div>
|
||||
</main>
|
||||
|
||||
<script src="/cljs-out/main.js" type="text/javascript"></script>
|
||||
<script>
|
||||
org.parkerici.sample_tracking.core.init();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
resources/schema.edn
Normal file
1
resources/schema.edn
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user