Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Login] Summary Statistics #9518

Merged
merged 21 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SQL/0000-00-00-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CREATE TABLE `Project` (
`Name` VARCHAR(255) NOT NULL,
`Alias` char(4) NOT NULL,
`recruitmentTarget` INT(6) Default NULL,
`showSummaryOnLogin` BOOLEAN DEFAULT TRUE;
skarya22 marked this conversation as resolved.
Show resolved Hide resolved
PRIMARY KEY (`ProjectID`),
UNIQUE KEY `u_ProjectName` (`Name`)
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
Expand Down
13 changes: 13 additions & 0 deletions SQL/New_patches/2024-12-18-Login_statistics.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE Login_Summary_Statistics (
Title VARCHAR(255),
Project VARCHAR(255),
Value INT
skarya22 marked this conversation as resolved.
Show resolved Hide resolved
);

ALTER TABLE Login_Summary_Statistics
MODIFY COLUMN PinType enum('topquery','dashboard', 'loginpage') DEFAULT NULL;

ALTER TABLE Project
ADD COLUMN showSummaryOnLogin BOOLEAN DEFAULT TRUE;

UPDATE Project SET showSummaryOnLogin = FALSE WHERE Name = 'DCP';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the show showSummaryOnLogin column is for projects to be able to opt-out from being displayed on the login page, and then DCP is added as an example of how to do that in raisinbread

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this patch is going to the release patch, not raisinbread. Can you remove this RB specific line?

2 changes: 2 additions & 0 deletions modules/configuration/php/configuration.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class Configuration extends \NDB_Form
'PatientID' => 'PatientID',
'PatientName' => 'PatientName',
];

$this->tpl_data['shared_queries'] = $user_starred_queries;
skarya22 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
28 changes: 21 additions & 7 deletions modules/dataquery/jsx/welcome.adminquerymodal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ function AdminQueryModal(props: {
QueryID: number,
defaultName: string,
closeModal: () => void,
onSubmit: (name: string, topQuery: boolean, dashboardQuery: boolean)
onSubmit: (
name: string,
topQuery: boolean,
dashboardQuery: boolean,
loginQuery: boolean,
)
=> void,
}) {
const [queryName, setQueryName] = useState(props.defaultName || '');
const [topQuery, setTopQuery] = useState(true);
const [dashboardQuery, setDashboardQuery] = useState(true);
const [loginQuery, setLoginQuery] = useState(true);
/**
* Convert the onSubmit callback to a promise function of the format
* expected by jsx/Modal.
Expand All @@ -39,20 +45,20 @@ function AdminQueryModal(props: {
reject();
return;
}
if (!topQuery && !dashboardQuery) {
if (!topQuery && !dashboardQuery && !loginQuery) {
swal.fire({
type: 'error',
text: 'Must pin as study query or pin to dashboard.',
text: 'Must pin as study query, to dashboard, or to the login page.',
});
reject();
return;
}
resolve([queryName.trim(), topQuery, dashboardQuery]);
resolve([queryName.trim(), topQuery, dashboardQuery, loginQuery]);
});
if (props.onSubmit) {
sbmt = sbmt.then((val: [string, boolean, boolean]) => {
const [name, topq, dashq] = val;
props.onSubmit(name, topq, dashq);
sbmt = sbmt.then((val: [string, boolean, boolean, boolean]) => {
const [name, topq, dashq, loginq] = val;
props.onSubmit(name, topq, dashq, loginq);
});
}
return sbmt;
Expand Down Expand Up @@ -87,6 +93,14 @@ function AdminQueryModal(props: {
setDashboardQuery(value)
}
/>
<CheckboxElement name='loginpage'
value={loginQuery}
label='Pin To Login Page'
onUserInput={
(name: string, value: boolean) =>
setLoginQuery(value)
}
/>
</FieldsetElement>
</form>
</Modal>;
Expand Down
37 changes: 19 additions & 18 deletions modules/dataquery/jsx/welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,7 @@ function QueryList(props: {
const [fullQuery, setFullQuery]
= useState<boolean>(!props.defaultCollapsed);
const [unpinAdminQuery, setUnpinAdminQuery] = useState<number|null>(null);
const [adminPinAction, setAdminPinAction]
= useState<'top'|'dashboard'|'top,dashboard'>('top');
const [adminPinAction, setAdminPinAction] = useState<string>('');

useEffect(() => {
const modules = new Set<string>();
Expand Down Expand Up @@ -300,14 +299,17 @@ function QueryList(props: {
setAdminModalID(null);
setQueryName(null);

let param;
if (adminPinAction == 'top') {
param = 'adminname=' + encodeURIComponent(name);
} else if (adminPinAction == 'dashboard') {
param = 'dashboardname=' + encodeURIComponent(name);
} else if (adminPinAction == 'top,dashboard') {
param = 'adminname=' + encodeURIComponent(name)
+ '&dashboardname=' + encodeURIComponent(name);
let param = '';
if (adminPinAction.includes('top')) {
param += 'adminname=' + encodeURIComponent(name);
}
if (adminPinAction.includes('dashboard')) {
if (param != '') param += '&';
param += 'dashboardname=' + encodeURIComponent(name);
}
if (adminPinAction.includes('login')) {
if (param != '') param += '&';
param += 'loginname=' + encodeURIComponent(name);
}
fetch(
'/dataquery/queries/' + id
Expand Down Expand Up @@ -363,16 +365,15 @@ function QueryList(props: {
/>);
const adminModal = adminModalID == null ? '' :
<AdminQueryModal
onSubmit={(name, topQ, dashboardQ) => {
if (topQ && dashboardQ) {
setAdminPinAction('top,dashboard');
} else if (topQ) {
setAdminPinAction('top');
} else if (dashboardQ) {
setAdminPinAction('dashboard');
} else {
onSubmit={(name, topQ, dashboardQ, loginQ) => {
let boolList = '';
if (topQ) boolList += 'top';
if (dashboardQ) boolList += 'dashboard';
if (loginQ) boolList += 'login';
if (!topQ && !dashboardQ && !loginQ) {
throw new Error('Modal promise should not have resolved');
}
setAdminPinAction(boolList);
setQueryName(name);
}}
closeModal={() => setAdminModalID(null)}
Expand Down
14 changes: 14 additions & 0 deletions modules/dataquery/php/endpoints/queries/query.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ class Query extends \LORIS\Http\Endpoint
}
}

if (isset($params['loginname'])) {
if ($params['loginname'] == '') {
$query->removeAdminPinnedQuery('loginpage');
$resp['loginpage'] = 'Unpinned query from login page';
} else {
$query->setAdminPinnedQuery(
$user,
$params['loginname'],
'loginpage'
);
$resp['loginpage'] = 'Pinned query to login page';
}
}

if (isset($params['name'])) {
$query->setQueryName($user, $params['name']);
$resp['Name'] = 'Named query';
Expand Down
4 changes: 2 additions & 2 deletions modules/dataquery/php/provisioners/studyqueries.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class StudyQueries extends \LORIS\Data\Provisioners\DBRowProvisioner
* the pinned study queries.
*
* @param protected \LORIS\LorisInstance $loris - The LORIS object
* @param string $pintype - The pin type. Either
* "dashboard" or "study"
* @param string $pintype - The pin type. "dashboard"
* or "study" or "loginpage"
*/
function __construct(protected \LORIS\LorisInstance $loris, $pintype)
{
Expand Down
13 changes: 11 additions & 2 deletions modules/dataquery/php/query.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,16 @@ class Query implements \LORIS\StudyEntities\AccessibleResource,
'Name' => $name,
]
);
}

/**
* Get the name of the query.
*
* @return void
*/
public function getQueryName()
{
return $this->name;
}

/**
Expand Down Expand Up @@ -492,7 +501,7 @@ class Query implements \LORIS\StudyEntities\AccessibleResource,
* @param string $name The name that the admin thinks should be
* used for the query
* @param string $type The type of querypin to remove. Either
* 'topquery' or 'dashboard'
* 'topquery' or 'dashboard' or 'loginpage'
*
* @return void
*/
Expand All @@ -517,7 +526,7 @@ class Query implements \LORIS\StudyEntities\AccessibleResource,
* Remove this query from the list of queries pinned by an admin.
*
* @param string $type The type of querypin to remove. Either
* 'topquery' or 'dashboard'
* 'topquery' or 'dashboard' or 'loginpage'
*
* @return void
*/
Expand Down
6 changes: 6 additions & 0 deletions modules/dataquery/static/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ paths:
description: The admin name to pin the query to the dashboard as. If the empty string, will be unpinned.
schema:
type: string
- name: loginpagename
in: query
style: pipeDelimited
description: The admin name to pin the query to the login page as. If the empty string, will be unpinned.
schema:
type: string
- name: name
in: query
style: pipeDelimited
Expand Down
8 changes: 4 additions & 4 deletions modules/dataquery/test/TestPlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
13. Click the `Pin` icon to pin some queries.
1. With and empty text in the `query name` text field, click the `Submit` button.
2. Assert that: the error message `Must provide a query name to pin query as.` is triggered.
3. Unchecking all checkboxes (i.e. `Pin Study Query` and `Pin Dashboard Summary`).
4. Assert that: clicking `Submit` triggers the error message `Must pin as study query or pin to dashboard.`.
3. Unchecking all checkboxes (i.e. `Pin Study Query` and `Pin Dashboard Summary` and `Pin to Login Page`).
4. Assert that: clicking `Submit` triggers the error message `Must pin as study query, to dashboard, or to the login page.`.
5. Check the `Pin Study Query` checkbox and click the submit button.
6. Assert that: the query is now pinned at the top of the page in the `Study Queries` panel.
7. Go to LORIS main page by clicking the `LORIS` name in the top-left corner.
Expand All @@ -34,8 +34,8 @@
13. Assert that: the query is displayed inside the right-side `Study Queries` panel.
14. Click the pinned query.
15. Assert that: the confirmation message `Query loaded` is displayed and query can immediately be executed.
16. Try pinning a query with both `Pin Study Query` and `Pin Dashboard Summary` options.
17. Assert that: both `Study Queries` in the dataquery module **AND** `Study Queries` in LORIS welcome page are displayed.
16. Try pinning a query with `Pin Study Query`, `Pin Dashboard Summary` and `Pin to Login Page` options.
17. Assert that: `Study Queries` in the dataquery module **AND** `Study Queries` in LORIS welcome page **AND** `Data in LORIS` on the LORIS Login Page are displayed.
14. Assert that: the query is now pinned at the top of the page, in `Study Queries` panel.
15. Go back to `LORIS main page`.
16. Assert that: `starred queries` are available in the right side `Starred Queries` panel.
Expand Down
7 changes: 7 additions & 0 deletions modules/login/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ to provide references on the LORIS landing page.
The configuration setting "StudyLogo" is the URL for an image to
show above the login box.

If a query is pinned to the login page from the dataquery module, then
after the tools/update_login_summary_statistics.php tool is run, a summary of
all the pinned queries will be displayed on the login page including the count.
If a query returns more than one row, the name will be appended with an 's'.
Pinned queries must include the column Project in order to be displayed.


## Interactions with LORIS

The login module redirects to the dashboard upon successful login.
128 changes: 128 additions & 0 deletions modules/login/assets/summaryStatisticsPhone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import * as React from "react"
const SvgComponent = (props) => (
<svg
width={300}
viewBox="0 0 1857 2749"
fill="none"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
{...props}
>
<g clipPath="url(#clip0_16_246)">
<path
d="M1104.91 2743.61H230.873C103.741 2743.61 0.325439 2640.19 0.325439 2513.06V230.554C0.325439 103.419 103.741 0 230.873 0H1104.91C1232.04 0 1335.46 103.419 1335.46 230.554V2513.06C1335.46 2640.19 1232.04 2743.61 1104.91 2743.61Z"
fill="#D7D7D8"
/>
<path
d="M1105.54 2681.2H230.24C136.147 2681.2 59.5688 2604.62 59.5688 2510.53V228.608C59.5688 134.513 136.147 57.933 230.24 57.933H1105.54C1199.64 57.933 1276.21 134.513 1276.21 228.608V2510.53C1276.21 2604.62 1199.64 2681.2 1105.54 2681.2Z"
fill="white"
/>
<path
d="M791.629 209.825H544.109C511.432 209.825 484.865 183.258 484.865 150.58C484.865 117.902 511.432 91.3349 544.109 91.3349H791.629C824.305 91.3349 850.872 117.902 850.872 150.58C850.872 183.258 824.305 209.825 791.629 209.825Z"
fill="#D7D7D8"
/>
<path
d="M1737.42 2440.41L1659.78 2490.04L1730.18 2600.17L1807.82 2550.54L1737.42 2440.41Z"
fill="#F3A3A6"
/>
<path
d="M1403.03 890.943C1457.19 890.943 1501.11 847.031 1501.11 792.864C1501.11 738.697 1457.19 694.786 1403.03 694.786C1348.86 694.786 1304.95 738.697 1304.95 792.864C1304.95 847.031 1348.86 890.943 1403.03 890.943Z"
fill="#F3A3A6"
/>
<path
d="M1429.87 782.862C1413.48 782.545 1402.49 766.116 1395.92 750.999C1389.36 735.972 1382.62 718.593 1367.37 712.483C1354.87 707.504 1333.33 742.264 1323.37 733.212C1313.01 723.752 1322.47 674.328 1333.29 665.412C1344.1 656.496 1358.95 654.595 1372.89 653.735C1407.06 651.789 1441.41 654.142 1474.99 660.796C1495.72 664.869 1517.17 671.16 1532.24 685.96C1551.39 704.743 1556.55 733.347 1558.18 760.096C1559.9 787.478 1558.58 816.173 1545.55 840.342C1532.47 864.466 1504.82 882.434 1477.98 876.64C1475.13 862.112 1477.66 847.221 1478.57 832.376C1479.47 817.621 1478.16 801.69 1469.02 790.013C1459.87 778.336 1440.59 773.9 1430.23 784.446"
fill="#9A9AA3"
/>
<path
d="M1550.89 815.494C1560.62 808.207 1572.25 802.052 1584.34 803.41C1597.42 804.813 1608.55 815.494 1612.03 828.167C1615.52 840.84 1611.9 854.87 1603.98 865.371C1596.06 875.871 1584.16 882.841 1571.48 886.417C1564.15 888.499 1556.14 889.359 1549.08 886.417C1538.72 882.072 1533.01 868.991 1536.95 858.446"
fill="#9A9AA3"
/>
<path
d="M1185.92 1742.06C1179.77 1774.33 1192.03 1803.65 1213.39 1807.5C1234.71 1811.35 1257.02 1788.27 1263.22 1756C1265.89 1743.14 1265.31 1729.84 1261.5 1717.21L1336.95 1211.38L1235.3 1193.46L1201.85 1706.53C1193.66 1717.03 1188.19 1729.2 1185.92 1742.19V1742.06Z"
fill="#F3A3A6"
/>
<path
d="M1391.31 928.463L1322.06 929.232C1273.18 937.153 1260.19 963.449 1249.65 1011.79C1233.49 1085.52 1212.85 1183.77 1217.2 1185.13C1224.12 1187.4 1342.56 1241.53 1402.53 1228.13L1391.35 928.463H1391.31Z"
fill="#074785"
/>
<path
d="M1476.35 2536.15L1384.21 2537.18L1385.67 2667.89L1477.81 2666.86L1476.35 2536.15Z"
fill="#F3A3A6"
/>
<path
d="M1296.58 2748.05C1286.85 2748.19 1278.3 2748.05 1271.78 2747.51C1247.25 2745.56 1223.76 2727.73 1211.86 2717.32C1206.52 2712.66 1204.75 2705.05 1207.42 2698.53C1209.32 2693.87 1213.21 2690.3 1218.1 2688.8L1282.6 2669.61L1386.55 2597.79L1387.73 2599.87C1388.18 2600.64 1398.68 2619.06 1402.26 2631.55C1403.62 2636.3 1403.35 2640.24 1401.35 2643.32C1400 2645.45 1398.1 2646.71 1396.56 2647.48C1398.46 2649.43 1404.43 2653.41 1422.81 2656.13C1449.51 2660.11 1454.9 2632.32 1455.08 2631.14L1455.26 2630.19L1456.03 2629.65C1468.65 2621.28 1476.39 2617.52 1479.11 2618.29C1480.83 2618.74 1483.59 2619.6 1492.01 2694.91C1492.78 2697.27 1498.3 2714.56 1494.86 2731.21C1491.15 2749.32 1412.17 2743.93 1396.42 2742.71C1395.97 2742.75 1336.95 2747.64 1296.49 2748.05H1296.63H1296.58Z"
fill="#2F2E43"
/>
<path
d="M1491.19 959.964L1393.12 993.456L1391.58 851.838L1480.83 850.842L1491.19 959.964Z"
fill="#F3A3A6"
/>
<path
d="M1636.79 2726.32C1625.97 2726.46 1616.02 2725.24 1608.91 2724.06C1601.94 2722.88 1596.42 2717.41 1595.24 2710.44C1594.34 2705.41 1595.83 2700.39 1599.14 2696.59L1643.67 2646.17L1693.82 2530.21L1695.94 2531.34C1696.71 2531.75 1715.36 2541.85 1725.05 2550.54C1728.71 2553.84 1730.57 2557.32 1730.57 2561.04C1730.57 2563.57 1729.62 2565.65 1728.67 2567.05C1731.34 2567.69 1738.49 2567.87 1755.5 2560.49C1780.26 2549.72 1770.12 2523.29 1769.67 2522.25L1769.31 2521.34L1769.72 2520.53C1776.01 2506.77 1780.62 2499.44 1783.29 2498.62C1785.01 2498.17 1787.77 2497.31 1834.8 2556.78C1836.7 2558.36 1850.55 2570.09 1856.43 2586.02C1862.81 2603.35 1793.07 2640.56 1778.95 2647.84C1778.54 2648.21 1705.63 2702.38 1675.67 2717.91C1663.77 2724.06 1649.6 2726.1 1636.7 2726.19L1636.84 2726.32H1636.79Z"
fill="#2F2E43"
/>
<path
d="M1531.88 1442.07L1273.91 1444.92L1253.18 1685.16L1365.46 2570.81L1497.17 2569.32L1438.83 2057.74L1657.61 2517.81L1773.74 2434.53L1602.12 2004.65C1602.12 2004.65 1657.56 1627.91 1609.68 1534.77C1561.84 1441.62 1531.93 1441.94 1531.93 1441.94V1442.07H1531.88Z"
fill="#2F2E43"
/>
<path
d="M1660.33 1455.29L1250.6 1459.86L1367.64 928.78L1546.18 926.743L1660.33 1455.29Z"
fill="#074785"
/>
<path
d="M1700.33 1736.35C1707.21 1768.53 1695.58 1798.09 1674.36 1802.39C1653.08 1806.73 1630.27 1784.15 1623.44 1751.97C1620.5 1739.16 1620.77 1725.85 1624.25 1713.13L1537.54 1209.07L1638.74 1188.89L1683.59 1701.14C1692.01 1711.46 1697.75 1723.54 1700.33 1736.44V1736.35Z"
fill="#F3A3A6"
/>
<path
d="M1476.98 927.513L1546.23 926.743C1595.24 933.623 1608.82 959.602 1620.5 1007.71C1638.28 1081.08 1661.05 1178.8 1656.8 1180.29C1649.87 1182.64 1532.74 1239.4 1472.5 1227.36L1477.07 927.513H1476.98Z"
fill="#074785"
/>
<path
d="M175.658 2344.47H747.963V2613.31H175.658V2344.47Z"
fill="url(#pattern0_16_246)"
/>
<path
d="M788.153 2377.72H1162.3V2581.43H788.153V2377.72Z"
fill="url(#pattern1_16_246)"
/>
</g>
<defs>
<pattern
id="pattern0_16_246"
patternContentUnits="objectBoundingBox"
width={1}
height={1}
>
<use
xlinkHref="#image0_16_246"
transform="scale(0.00242131 0.00515464)"
/>
</pattern>
<pattern
id="pattern1_16_246"
patternContentUnits="objectBoundingBox"
width={1}
height={1}
>
<use
xlinkHref="#image1_16_246"
transform="scale(0.000981354 0.00180249)"
/>
</pattern>
<clipPath id="clip0_16_246">
<rect width={1857} height={2749} fill="white" />
</clipPath>
<image
id="image0_16_246"
width={680}
height={194}
/>
<image
id="image1_16_246"
width={1019}
height={555}
/>
</defs>
</svg>
)
export default SvgComponent
Loading
Loading