@reqquest/ui 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +1 -1163
- package/dist/components/FieldCardCheckbox.svelte +1 -1
- package/dist/components/index.js +2 -11
- package/dist/index.js +2 -4
- package/dist/typed-client/schema.graphql +56 -11
- package/dist/typed-client/types.js +57 -11
- package/package.json +3 -3
- package/dist/components/AppRequestCard.svelte +0 -172
- package/dist/components/ApplicantProgramList.svelte +0 -184
- package/dist/components/ApplicantProgramListTooltip.svelte +0 -22
- package/dist/components/ApplicantPromptPage.svelte +0 -88
- package/dist/components/ApplicationDetailsView.svelte +0 -307
- package/dist/components/ButtonLoadingIcon.svelte +0 -28
- package/dist/components/IntroPanel.svelte +0 -41
- package/dist/components/PeriodPanel.svelte +0 -100
- package/dist/components/RenderDisplayComponent.svelte +0 -38
- package/dist/components/ReviewerList.svelte +0 -93
- package/dist/components/StatusMessageList.svelte +0 -35
- package/dist/components/WarningIconYellow.svelte +0 -20
- package/dist/csv.js +0 -21
- package/dist/status-utils.js +0 -343
- package/dist/stores/IStateStore.js +0 -0
- package/dist/util.js +0 -14
- /package/dist/{components/types.js → types.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { CardSelectItem } from '
|
|
2
|
+
import type { CardSelectItem } from '../components/FieldCardRadio.svelte'
|
|
3
3
|
import { Card, CardGrid, FormInlineNotification } from '@txstate-mws/carbon-svelte'
|
|
4
4
|
import { FORM_CONTEXT, FORM_INHERITED_PATH, Field, type FormStore } from '@txstate-mws/svelte-forms'
|
|
5
5
|
import { Store } from '@txstate-mws/svelte-store'
|
package/dist/components/index.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export { default as ApplicantProgramList } from './ApplicantProgramList.svelte';
|
|
2
|
-
export { default as ApplicantPromptPage } from './ApplicantPromptPage.svelte';
|
|
3
|
-
export { default as ApplicationDetailsView } from './ApplicationDetailsView.svelte';
|
|
4
|
-
export { default as AppRequestCard } from './AppRequestCard.svelte';
|
|
5
|
-
export { default as ButtonLoadingIcon } from './ButtonLoadingIcon.svelte';
|
|
6
|
-
export { default as IntroPanel } from './IntroPanel.svelte';
|
|
7
|
-
export { default as PeriodPanel } from './PeriodPanel.svelte';
|
|
8
|
-
export { default as QuestionnairePrompt } from './QuestionnairePrompt.svelte';
|
|
9
|
-
export { default as RenderDisplayComponent } from './RenderDisplayComponent.svelte';
|
|
10
|
-
export { default as FieldCardRadio } from './FieldCardRadio.svelte';
|
|
11
1
|
export { default as FieldCardCheckbox } from './FieldCardCheckbox.svelte';
|
|
12
|
-
export
|
|
2
|
+
export { default as FieldCardRadio } from './FieldCardRadio.svelte';
|
|
3
|
+
export { default as QuestionnairePrompt } from '../../lib/components/QuestionnairePrompt.svelte';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export * from './registry.js';
|
|
2
|
-
export * from './api.js';
|
|
3
1
|
export * from './components/index.js';
|
|
2
|
+
export * from './registry.js';
|
|
3
|
+
export * from './types.js';
|
|
4
4
|
export * from './typed-client/index.js';
|
|
5
|
-
export * from './util.js';
|
|
6
|
-
export * from './status-utils.js';
|
|
@@ -278,17 +278,6 @@ Represents a group of applications all being applied for at the same time. As pa
|
|
|
278
278
|
type AppRequest {
|
|
279
279
|
"""Actions the user can take on this app request."""
|
|
280
280
|
actions: AppRequestActions!
|
|
281
|
-
|
|
282
|
-
"""
|
|
283
|
-
The activity log for this app request. This is a list of actions taken on the app request, such as submission, updating prompts, make an offer, add a note, etc. It will be sorted by the date of the activity in descending order.
|
|
284
|
-
"""
|
|
285
|
-
activity(
|
|
286
|
-
"""
|
|
287
|
-
Filters to apply to the activity log. This can be used to filter by action type, date range, etc.
|
|
288
|
-
"""
|
|
289
|
-
filters: AppRequestActivityFilters
|
|
290
|
-
paged: Pagination
|
|
291
|
-
): [AppRequestActivity!]!
|
|
292
281
|
applicant: AccessUser!
|
|
293
282
|
applications: [Application!]!
|
|
294
283
|
|
|
@@ -403,6 +392,16 @@ type AppRequestActions {
|
|
|
403
392
|
|
|
404
393
|
"""User may submit this app request either as or on behalf of the owner."""
|
|
405
394
|
submit: Boolean!
|
|
395
|
+
|
|
396
|
+
"""
|
|
397
|
+
User is able to see the acceptance UI. i.e. they are the applicant and the request is in the appropriate phase.
|
|
398
|
+
"""
|
|
399
|
+
viewAcceptUI: Boolean!
|
|
400
|
+
|
|
401
|
+
"""
|
|
402
|
+
User is able to see the applicant UI. i.e. they are the applicant and the request is in the appropriate phase.
|
|
403
|
+
"""
|
|
404
|
+
viewApplyUI: Boolean!
|
|
406
405
|
}
|
|
407
406
|
|
|
408
407
|
type AppRequestActivity {
|
|
@@ -538,13 +537,23 @@ type AppRequestIndexCategory {
|
|
|
538
537
|
If this is > 0, the index values should be shown on the applicant dashboard, sorted by this priority in descending order.
|
|
539
538
|
"""
|
|
540
539
|
applicantDashboardPriority: Float
|
|
540
|
+
|
|
541
|
+
"""
|
|
542
|
+
The internal category name for this index. Use this with any GraphQL filters.
|
|
543
|
+
"""
|
|
541
544
|
category: String!
|
|
545
|
+
|
|
546
|
+
"""A human-friendly label for this category that can be shown in the UI."""
|
|
542
547
|
categoryLabel: String!
|
|
543
548
|
|
|
544
549
|
"""
|
|
545
550
|
If this is > 0, the index values should be shown on the list filters, sorted by this priority in descending order.
|
|
546
551
|
"""
|
|
547
552
|
listFiltersPriority: Float
|
|
553
|
+
|
|
554
|
+
"""
|
|
555
|
+
If true, this category has few enough values that it is reasonable to list them all in a dropdown or similar UI control. If false, the list of values is likely to get very long and it would be better to use an autofill combobox or something.
|
|
556
|
+
"""
|
|
548
557
|
listable: Boolean!
|
|
549
558
|
|
|
550
559
|
"""
|
|
@@ -960,13 +969,23 @@ type IndexCategory {
|
|
|
960
969
|
If this is > 0, the index values should be shown on the applicant dashboard, sorted by this priority in descending order.
|
|
961
970
|
"""
|
|
962
971
|
applicantDashboardPriority: Float
|
|
972
|
+
|
|
973
|
+
"""
|
|
974
|
+
The internal category name for this index. Use this with any GraphQL filters.
|
|
975
|
+
"""
|
|
963
976
|
category: String!
|
|
977
|
+
|
|
978
|
+
"""A human-friendly label for this category that can be shown in the UI."""
|
|
964
979
|
categoryLabel: String!
|
|
965
980
|
|
|
966
981
|
"""
|
|
967
982
|
If this is > 0, the index values should be shown on the list filters, sorted by this priority in descending order.
|
|
968
983
|
"""
|
|
969
984
|
listFiltersPriority: Float
|
|
985
|
+
|
|
986
|
+
"""
|
|
987
|
+
If true, this category has few enough values that it is reasonable to list them all in a dropdown or similar UI control. If false, the list of values is likely to get very long and it would be better to use an autofill combobox or something.
|
|
988
|
+
"""
|
|
970
989
|
listable: Boolean!
|
|
971
990
|
|
|
972
991
|
"""
|
|
@@ -1057,6 +1076,9 @@ type Mutation {
|
|
|
1057
1076
|
"""Create a new app request."""
|
|
1058
1077
|
createAppRequest(login: String!, periodId: ID!, validateOnly: Boolean): ValidatedAppRequestResponse!
|
|
1059
1078
|
createPeriod(copyPeriodId: String, period: PeriodUpdate!, validateOnly: Boolean): ValidatedPeriodResponse!
|
|
1079
|
+
|
|
1080
|
+
"""Delete an existing note."""
|
|
1081
|
+
deleteNote(noteId: String!): Boolean!
|
|
1060
1082
|
deletePeriod(periodId: ID!): ValidatedResponse!
|
|
1061
1083
|
markPeriodReviewed(periodId: ID!, validateOnly: Boolean): ValidatedPeriodResponse!
|
|
1062
1084
|
|
|
@@ -1097,6 +1119,9 @@ type Mutation {
|
|
|
1097
1119
|
"""Submit the app request."""
|
|
1098
1120
|
submitAppRequest(appRequestId: ID!): ValidatedAppRequestResponse!
|
|
1099
1121
|
updateConfiguration(data: JsonData!, key: String!, periodId: ID!, validateOnly: Boolean): ValidatedConfigurationResponse!
|
|
1122
|
+
|
|
1123
|
+
"""Update the content of an existing note."""
|
|
1124
|
+
updateNote(content: String!, noteId: String!): Note!
|
|
1100
1125
|
updatePeriod(periodId: ID!, update: PeriodUpdate!, validateOnly: Boolean): ValidatedPeriodResponse!
|
|
1101
1126
|
updatePeriodRequirement(disabled: Boolean!, periodId: String!, requirementKey: String!): ValidatedResponse!
|
|
1102
1127
|
|
|
@@ -1159,10 +1184,12 @@ type Note {
|
|
|
1159
1184
|
content: String!
|
|
1160
1185
|
createdAt: DateTime!
|
|
1161
1186
|
id: ID!
|
|
1187
|
+
updatedAt: DateTime!
|
|
1162
1188
|
}
|
|
1163
1189
|
|
|
1164
1190
|
"""Actions that can be performed on a note."""
|
|
1165
1191
|
type NoteActions {
|
|
1192
|
+
delete: Boolean!
|
|
1166
1193
|
update: Boolean!
|
|
1167
1194
|
}
|
|
1168
1195
|
|
|
@@ -1426,6 +1453,18 @@ type Query {
|
|
|
1426
1453
|
"\n This is the global access object. Each field represents a global permission\n like the ability to view the role management interface.\n "
|
|
1427
1454
|
access: Access!
|
|
1428
1455
|
accessUsers(filter: AccessUserFilter, paged: Pagination): [AccessUser!]!
|
|
1456
|
+
|
|
1457
|
+
"""
|
|
1458
|
+
The activity log for this app request. This is a list of actions taken on the app request, such as submission, updating prompts, make an offer, add a note, etc. It will be sorted by the date of the activity in descending order.
|
|
1459
|
+
"""
|
|
1460
|
+
appRequestActivity(
|
|
1461
|
+
"""
|
|
1462
|
+
Filters to apply to the activity log. This can be used to filter by action type, date range, etc.
|
|
1463
|
+
"""
|
|
1464
|
+
filters: AppRequestActivityFilters
|
|
1465
|
+
id: String!
|
|
1466
|
+
paged: Pagination
|
|
1467
|
+
): [AppRequestActivity!]!
|
|
1429
1468
|
appRequestIndexes(
|
|
1430
1469
|
categories: [String!]
|
|
1431
1470
|
|
|
@@ -1449,6 +1488,12 @@ type Query {
|
|
|
1449
1488
|
A list of all possible scopes. Scopes are used to limit users when they are accessing the system through an alternate UI or login method. For instance, if you generate an authentication token to give to a third party, it may have a scope identifying that third party and limiting their access even though they are acting as you. Roles must match the token scope in order to apply permissions.
|
|
1450
1489
|
"""
|
|
1451
1490
|
scopes: [String!]!
|
|
1491
|
+
userIndexes(
|
|
1492
|
+
"""
|
|
1493
|
+
Returns indexes that are flagged to appear in this destination. Also sorts for this destination.
|
|
1494
|
+
"""
|
|
1495
|
+
for: AppRequestIndexDestination
|
|
1496
|
+
): [IndexCategory!]!
|
|
1452
1497
|
}
|
|
1453
1498
|
|
|
1454
1499
|
"""
|
|
@@ -405,17 +405,6 @@ export default {
|
|
|
405
405
|
"actions": [
|
|
406
406
|
23
|
|
407
407
|
],
|
|
408
|
-
"activity": [
|
|
409
|
-
24,
|
|
410
|
-
{
|
|
411
|
-
"filters": [
|
|
412
|
-
25
|
|
413
|
-
],
|
|
414
|
-
"paged": [
|
|
415
|
-
56
|
|
416
|
-
]
|
|
417
|
-
}
|
|
418
|
-
],
|
|
419
408
|
"applicant": [
|
|
420
409
|
17
|
|
421
410
|
],
|
|
@@ -531,6 +520,12 @@ export default {
|
|
|
531
520
|
"submit": [
|
|
532
521
|
37
|
|
533
522
|
],
|
|
523
|
+
"viewAcceptUI": [
|
|
524
|
+
37
|
|
525
|
+
],
|
|
526
|
+
"viewApplyUI": [
|
|
527
|
+
37
|
|
528
|
+
],
|
|
534
529
|
"__typename": [
|
|
535
530
|
77
|
|
536
531
|
]
|
|
@@ -1038,6 +1033,15 @@ export default {
|
|
|
1038
1033
|
]
|
|
1039
1034
|
}
|
|
1040
1035
|
],
|
|
1036
|
+
"deleteNote": [
|
|
1037
|
+
37,
|
|
1038
|
+
{
|
|
1039
|
+
"noteId": [
|
|
1040
|
+
77,
|
|
1041
|
+
"String!"
|
|
1042
|
+
]
|
|
1043
|
+
}
|
|
1044
|
+
],
|
|
1041
1045
|
"deletePeriod": [
|
|
1042
1046
|
81,
|
|
1043
1047
|
{
|
|
@@ -1223,6 +1227,19 @@ export default {
|
|
|
1223
1227
|
]
|
|
1224
1228
|
}
|
|
1225
1229
|
],
|
|
1230
|
+
"updateNote": [
|
|
1231
|
+
54,
|
|
1232
|
+
{
|
|
1233
|
+
"content": [
|
|
1234
|
+
77,
|
|
1235
|
+
"String!"
|
|
1236
|
+
],
|
|
1237
|
+
"noteId": [
|
|
1238
|
+
77,
|
|
1239
|
+
"String!"
|
|
1240
|
+
]
|
|
1241
|
+
}
|
|
1242
|
+
],
|
|
1226
1243
|
"updatePeriod": [
|
|
1227
1244
|
80,
|
|
1228
1245
|
{
|
|
@@ -1313,11 +1330,17 @@ export default {
|
|
|
1313
1330
|
"id": [
|
|
1314
1331
|
45
|
|
1315
1332
|
],
|
|
1333
|
+
"updatedAt": [
|
|
1334
|
+
43
|
|
1335
|
+
],
|
|
1316
1336
|
"__typename": [
|
|
1317
1337
|
77
|
|
1318
1338
|
]
|
|
1319
1339
|
},
|
|
1320
1340
|
"NoteActions": {
|
|
1341
|
+
"delete": [
|
|
1342
|
+
37
|
|
1343
|
+
],
|
|
1321
1344
|
"update": [
|
|
1322
1345
|
37
|
|
1323
1346
|
],
|
|
@@ -1623,6 +1646,21 @@ export default {
|
|
|
1623
1646
|
]
|
|
1624
1647
|
}
|
|
1625
1648
|
],
|
|
1649
|
+
"appRequestActivity": [
|
|
1650
|
+
24,
|
|
1651
|
+
{
|
|
1652
|
+
"filters": [
|
|
1653
|
+
25
|
|
1654
|
+
],
|
|
1655
|
+
"id": [
|
|
1656
|
+
77,
|
|
1657
|
+
"String!"
|
|
1658
|
+
],
|
|
1659
|
+
"paged": [
|
|
1660
|
+
56
|
|
1661
|
+
]
|
|
1662
|
+
}
|
|
1663
|
+
],
|
|
1626
1664
|
"appRequestIndexes": [
|
|
1627
1665
|
46,
|
|
1628
1666
|
{
|
|
@@ -1679,6 +1717,14 @@ export default {
|
|
|
1679
1717
|
"scopes": [
|
|
1680
1718
|
77
|
|
1681
1719
|
],
|
|
1720
|
+
"userIndexes": [
|
|
1721
|
+
46,
|
|
1722
|
+
{
|
|
1723
|
+
"for": [
|
|
1724
|
+
28
|
|
1725
|
+
]
|
|
1726
|
+
}
|
|
1727
|
+
],
|
|
1682
1728
|
"__typename": [
|
|
1683
1729
|
77
|
|
1684
1730
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reqquest/ui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@sveltejs/kit": "^2.0.0",
|
|
26
|
-
"svelte": "^
|
|
26
|
+
"svelte": "^5.0.0"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@txstate-mws/carbon-svelte": "^1.5.5",
|
|
30
30
|
"@txstate-mws/fastify-shared": "^1.1.0",
|
|
31
31
|
"@txstate-mws/svelte-components": "^1.6.11",
|
|
32
32
|
"@txstate-mws/sveltekit-utils": "^1.0.2",
|
|
33
|
-
"carbon-components-svelte": ">=0.85.1 <
|
|
33
|
+
"carbon-components-svelte": ">=0.85.1 <0.96.0",
|
|
34
34
|
"carbon-icons-svelte": "^13.0.0",
|
|
35
35
|
"luxon": "^3.5.0",
|
|
36
36
|
"txstate-utils": "^1.8.15"
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { goto } from '$app/navigation'
|
|
3
|
-
import { resolve } from '$app/paths'
|
|
4
|
-
import { getApplicationStatusInfo, getAppRequestStatusInfo, getNavigationButton } from '../status-utils.js'
|
|
5
|
-
import { longNumericTime } from '../util.js'
|
|
6
|
-
import type { ActionItem } from '@txstate-mws/carbon-svelte'
|
|
7
|
-
import { Card, TagSet } from '@txstate-mws/carbon-svelte'
|
|
8
|
-
import Button from "carbon-components-svelte/src/Button/Button.svelte";
|
|
9
|
-
import type { PageData } from '../../routes/dashboards/applicant/$types'
|
|
10
|
-
import StatusMessageList from './StatusMessageList.svelte'
|
|
11
|
-
import WarningIconYellow from './WarningIconYellow.svelte'
|
|
12
|
-
import { enumPromptVisibility } from '../typed-client'
|
|
13
|
-
|
|
14
|
-
// Type for the partial AppRequest data passed from dashboard
|
|
15
|
-
type DashboardAppRequest = PageData['appRequests'][number]
|
|
16
|
-
|
|
17
|
-
export let request: DashboardAppRequest
|
|
18
|
-
export let actions: ActionItem[] = []
|
|
19
|
-
export let showAcceptanceButtons = true
|
|
20
|
-
export let onAcceptanceNavigate: ((requestId: string) => void) | undefined = undefined
|
|
21
|
-
|
|
22
|
-
$: statusInfo = getAppRequestStatusInfo(request.status)
|
|
23
|
-
$: firstInvalidatedPrompt = request.applications
|
|
24
|
-
.flatMap(app => app.requirements)
|
|
25
|
-
.flatMap(req => req.prompts)
|
|
26
|
-
.find(p => p.visibility === enumPromptVisibility.AVAILABLE && p.invalidated && p.invalidatedReason)
|
|
27
|
-
$: navButton = firstInvalidatedPrompt
|
|
28
|
-
? { label: 'Make corrections', href: `/requests/${request.id}/apply/${firstInvalidatedPrompt.id}` }
|
|
29
|
-
: getNavigationButton(request.status, request.id)
|
|
30
|
-
|
|
31
|
-
async function handleAcceptanceClick () {
|
|
32
|
-
if (onAcceptanceNavigate) {
|
|
33
|
-
onAcceptanceNavigate(request.id)
|
|
34
|
-
} else {
|
|
35
|
-
await goto(resolve(`/requests/${request.id}/apply`))
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<Card
|
|
41
|
-
title={request.period.name}
|
|
42
|
-
subhead={`Started: ${longNumericTime(request.createdAt)}`}
|
|
43
|
-
tags={[{ label: statusInfo.label, type: statusInfo.color }]}
|
|
44
|
-
tagsInBody
|
|
45
|
-
{actions}
|
|
46
|
-
forceOverflow={true}
|
|
47
|
-
navigations={navButton ? [navButton] : []}>
|
|
48
|
-
|
|
49
|
-
<!-- Status description -->
|
|
50
|
-
{#if statusInfo.description}
|
|
51
|
-
<p class="pl-1.5 mb-4 text-sm">{statusInfo.description}</p>
|
|
52
|
-
{/if}
|
|
53
|
-
|
|
54
|
-
<!-- Benefits section -->
|
|
55
|
-
<div class="rounded">
|
|
56
|
-
<h4 class="m-0 mb-2 text-lg benefits-title">Potential benefits</h4>
|
|
57
|
-
<p class="m-0 mb-3 benefits-subtitle text-sm">Benefit results will be finalized once the application submission and review is completed.</p>
|
|
58
|
-
|
|
59
|
-
{#if request.applications.length > 0}
|
|
60
|
-
{#each request.applications as application (application.id)}
|
|
61
|
-
{@const invalidatedPrompts = application.requirements
|
|
62
|
-
.flatMap(req => req.prompts)
|
|
63
|
-
.filter(p => p.visibility === enumPromptVisibility.AVAILABLE && p.invalidated && p.invalidatedReason)
|
|
64
|
-
}
|
|
65
|
-
{@const warningReqs = application.requirements.filter(r => r.status === 'WARNING' && r.statusReason)}
|
|
66
|
-
{@const appStatusTag = invalidatedPrompts.length > 0
|
|
67
|
-
? { label: 'Needs corrections', color: 'magenta' as const }
|
|
68
|
-
: getApplicationStatusInfo(application.status)}
|
|
69
|
-
<div class="program-status py-2 px-4 mb-4">
|
|
70
|
-
<div class="flex items-center">
|
|
71
|
-
<span class="font-medium">{application.title}</span>
|
|
72
|
-
<div class="tagwrap">
|
|
73
|
-
<TagSet tags={[{ label: appStatusTag.label, type: appStatusTag.color }]} />
|
|
74
|
-
</div>
|
|
75
|
-
{#if (application.status === 'PENDING' || application.status === 'ELIGIBLE') && warningReqs.length > 0}
|
|
76
|
-
<WarningIconYellow size={20} />
|
|
77
|
-
{/if}
|
|
78
|
-
|
|
79
|
-
<!-- Acceptance buttons -->
|
|
80
|
-
{#if showAcceptanceButtons && (request.status === 'ACCEPTANCE' || request.status === 'READY_TO_ACCEPT') && application.status === 'ELIGIBLE'}
|
|
81
|
-
<Button kind="primary" size="small" class="ml-auto"
|
|
82
|
-
on:click={handleAcceptanceClick}>
|
|
83
|
-
{request.status === 'READY_TO_ACCEPT' ? 'Accept Offer' : 'Review Offer'}
|
|
84
|
-
</Button>
|
|
85
|
-
{/if}
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
<!-- Status reason -->
|
|
89
|
-
{#if application.statusReason && application.status !== 'INELIGIBLE' && invalidatedPrompts.length === 0}
|
|
90
|
-
<p class="status-reason mt-2 mb-0 text-sm">{application.statusReason}</p>
|
|
91
|
-
{/if}
|
|
92
|
-
|
|
93
|
-
<!-- Warnings for PENDING/ELIGIBLE applications -->
|
|
94
|
-
{#if (application.status === 'PENDING' || application.status === 'ELIGIBLE') && warningReqs.length > 0}
|
|
95
|
-
<StatusMessageList
|
|
96
|
-
items={warningReqs.map(r => ({ id: r.id, message: r.statusReason! }))}
|
|
97
|
-
variant="warning"
|
|
98
|
-
accordionTitle="Multiple warnings" />
|
|
99
|
-
{/if}
|
|
100
|
-
|
|
101
|
-
<!-- Failed requirements for INELIGIBLE applications -->
|
|
102
|
-
{#if application.status === 'INELIGIBLE' && application.requirements}
|
|
103
|
-
{@const failedRequirements = application.requirements.filter(req => req.status === 'DISQUALIFYING' && req.statusReason)}
|
|
104
|
-
<StatusMessageList
|
|
105
|
-
items={failedRequirements.map(r => ({ id: r.id, message: r.statusReason! }))}
|
|
106
|
-
accordionTitle="Multiple eligibility issues" />
|
|
107
|
-
{/if}
|
|
108
|
-
|
|
109
|
-
<!-- Corrections needed for non-INELIGIBLE applications -->
|
|
110
|
-
{#if invalidatedPrompts.length > 0}
|
|
111
|
-
<StatusMessageList
|
|
112
|
-
items={invalidatedPrompts.map(p => ({ id: p.id, message: p.invalidatedReason! }))}
|
|
113
|
-
accordionTitle="Multiple corrections needed" />
|
|
114
|
-
{/if}
|
|
115
|
-
</div>
|
|
116
|
-
{/each}
|
|
117
|
-
{:else}
|
|
118
|
-
<p>No benefits associated with this application.</p>
|
|
119
|
-
{/if}
|
|
120
|
-
</div>
|
|
121
|
-
|
|
122
|
-
<!-- Footer info grid -->
|
|
123
|
-
<div class="mt-4 grid grid-cols-3 footer-grid">
|
|
124
|
-
<div class="text-center py-4 px-2 footer-section">
|
|
125
|
-
<span class="block text-sm font-semibold footer-label mb-1">Request number:</span>
|
|
126
|
-
<span class="block text-sm footer-value">{request.id.slice(0, 6).toUpperCase()}</span>
|
|
127
|
-
</div>
|
|
128
|
-
<div class="text-center py-4 px-2 footer-section">
|
|
129
|
-
<span class="block text-sm font-semibold footer-label mb-1">Last updated:</span>
|
|
130
|
-
<span class="block text-sm footer-value">{longNumericTime(request.updatedAt)}</span>
|
|
131
|
-
</div>
|
|
132
|
-
<div class="text-center py-4 px-2 footer-section">
|
|
133
|
-
<span class="block text-sm font-semibold footer-label mb-1">Waiting on:</span>
|
|
134
|
-
<span class="block text-sm footer-value">{statusInfo.waitingOn}</span>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
</Card>
|
|
138
|
-
|
|
139
|
-
<style>
|
|
140
|
-
/* Global styles for external component overrides */
|
|
141
|
-
:global(.tagwrap .tag-set > *) {
|
|
142
|
-
max-width: 100% !important;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.benefits-subtitle {
|
|
146
|
-
color: var(--cds-text-02);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.program-status {
|
|
150
|
-
background-color: var(--cds-ui-01);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.footer-grid {
|
|
154
|
-
background-color: var(--cds-ui-01);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.footer-section {
|
|
158
|
-
border-right: 1px solid var(--cds-ui-05);
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
.footer-section:last-child {
|
|
162
|
-
border-right: none;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.footer-label {
|
|
166
|
-
color: var(--cds-text-01);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.footer-value {
|
|
170
|
-
color: var(--cds-text-01);
|
|
171
|
-
}
|
|
172
|
-
</style>
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { TagSet } from '@txstate-mws/carbon-svelte'
|
|
3
|
-
import Button from "carbon-components-svelte/src/Button/Button.svelte";
|
|
4
|
-
import Close from "carbon-icons-svelte/lib/Close.svelte";
|
|
5
|
-
import InProgress from "carbon-icons-svelte/lib/InProgress.svelte";
|
|
6
|
-
import CheckmarkFilled from "carbon-icons-svelte/lib/CheckmarkFilled.svelte";
|
|
7
|
-
import Information from "carbon-icons-svelte/lib/Information.svelte";
|
|
8
|
-
import { ucfirst } from 'txstate-utils'
|
|
9
|
-
import type { ApplicationForDetails } from './types'
|
|
10
|
-
import { enumApplicationStatus, enumIneligiblePhases, enumRequirementType, getApplicationStatusInfo } from '..'
|
|
11
|
-
import ApplicantProgramListTooltip from './ApplicantProgramListTooltip.svelte'
|
|
12
|
-
import WarningIconYellow from './WarningIconYellow.svelte'
|
|
13
|
-
|
|
14
|
-
export let applications: ApplicationForDetails[]
|
|
15
|
-
export let viewMode = false
|
|
16
|
-
export let showTooltipsAsText = false
|
|
17
|
-
|
|
18
|
-
$: promptsByApplicationId = applications.reduce<Record<string, typeof applications[0]['requirements'][0]['prompts'] | undefined>>((acc, curr) => ({
|
|
19
|
-
...acc,
|
|
20
|
-
[curr.id]: curr.requirements
|
|
21
|
-
.filter(r => r.type === enumRequirementType.QUALIFICATION)
|
|
22
|
-
.flatMap(r => r.prompts)
|
|
23
|
-
}), {})
|
|
24
|
-
|
|
25
|
-
$: programButtonStatus = applications.reduce((acc, curr) => ({
|
|
26
|
-
...acc,
|
|
27
|
-
[curr.id]: curr.completionStatus === enumApplicationStatus.PENDING
|
|
28
|
-
? curr.requirements.some(r => r.prompts.some(p => p.answered && !p.invalidated))
|
|
29
|
-
? curr.requirements.filter(r => r.type === enumRequirementType.QUALIFICATION).every(r => r.prompts.every(p => p.answered && !p.invalidated))
|
|
30
|
-
? 'complete'
|
|
31
|
-
: 'continue'
|
|
32
|
-
: 'start'
|
|
33
|
-
: curr.completionStatus === enumApplicationStatus.INELIGIBLE
|
|
34
|
-
? curr.ineligiblePhase === enumIneligiblePhases.PREQUAL
|
|
35
|
-
? 'ineligible'
|
|
36
|
-
: 'revisit'
|
|
37
|
-
: 'complete'
|
|
38
|
-
}), {})
|
|
39
|
-
$: programFirstPromptId = applications.reduce((acc, curr) => ({
|
|
40
|
-
...acc,
|
|
41
|
-
[curr.id]: (promptsByApplicationId[curr.id]?.find(p => !p.answered || p.invalidated) ?? promptsByApplicationId[curr.id]?.[0])?.id
|
|
42
|
-
}), {})
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<section class="programs-container">
|
|
46
|
-
<header>
|
|
47
|
-
<div class="program column">Program</div>
|
|
48
|
-
<div class="status column">Eligibility</div>
|
|
49
|
-
</header>
|
|
50
|
-
{#each applications as application (application.id)}
|
|
51
|
-
{@const programStatus = programButtonStatus[application.id]}
|
|
52
|
-
{@const programFirstPrompt = programFirstPromptId[application.id]}
|
|
53
|
-
<div class="program column">{application.title}</div>
|
|
54
|
-
<div class="status column" class:no-tooltip={!application.statusReason?.length}>
|
|
55
|
-
{#if !viewMode}
|
|
56
|
-
<div class="icon-and-tooltip" class:wide-icon={application.completionStatus === enumApplicationStatus.INELIGIBLE}>
|
|
57
|
-
{#if application.completionStatus === enumApplicationStatus.INELIGIBLE}
|
|
58
|
-
<Close size={32} class="status-icon-ineligible" />
|
|
59
|
-
{:else if ['start', 'continue'].includes(programStatus)}
|
|
60
|
-
<InProgress size={24} class="status-icon-pending" />
|
|
61
|
-
{:else if application.hasWarning}
|
|
62
|
-
<WarningIconYellow size={24} class="status-icon-warning" />
|
|
63
|
-
{:else}
|
|
64
|
-
<CheckmarkFilled size={24} class="status-icon-complete" />
|
|
65
|
-
{/if}
|
|
66
|
-
<ApplicantProgramListTooltip {application} />
|
|
67
|
-
</div>
|
|
68
|
-
{#if programFirstPrompt && programStatus !== 'ineligible'}
|
|
69
|
-
<Button size="small" kind={programStatus === 'complete' ? 'ghost' : programStatus === 'revisit' ? 'secondary' : 'primary'} href={programFirstPrompt}>{ucfirst(programStatus)}</Button>
|
|
70
|
-
{/if}
|
|
71
|
-
{:else}
|
|
72
|
-
{@const statusInfo = getApplicationStatusInfo(application.status)}
|
|
73
|
-
<TagSet tags={[{ type: statusInfo.color, label: statusInfo.label }]} />
|
|
74
|
-
<ApplicantProgramListTooltip {application} />
|
|
75
|
-
{/if}
|
|
76
|
-
</div>
|
|
77
|
-
{#if application.warningReasons.length || application.ineligibleReasons.length}
|
|
78
|
-
<div class="tooltip-text-row" class:visible={showTooltipsAsText}>
|
|
79
|
-
{#each application.ineligibleReasons as reason (reason)}
|
|
80
|
-
<div class="tooltip-text-item">
|
|
81
|
-
<Information size={16} /> {reason}
|
|
82
|
-
</div>
|
|
83
|
-
{/each}
|
|
84
|
-
{#each application.warningReasons as reason (reason)}
|
|
85
|
-
<div class="tooltip-text-item">
|
|
86
|
-
<Information size={16} /> {reason}
|
|
87
|
-
</div>
|
|
88
|
-
{/each}
|
|
89
|
-
</div>
|
|
90
|
-
{/if}
|
|
91
|
-
{/each}
|
|
92
|
-
</section>
|
|
93
|
-
|
|
94
|
-
<style>
|
|
95
|
-
.programs-container {
|
|
96
|
-
display: grid;
|
|
97
|
-
grid-template-columns: 2fr 1fr;
|
|
98
|
-
margin-bottom: 1.5rem;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.programs-container header {
|
|
102
|
-
display: contents;
|
|
103
|
-
font-weight: bold;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.programs-container header .column {
|
|
107
|
-
padding: 0.5rem 8px;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.programs-container .column {
|
|
111
|
-
border-bottom: 1px solid var(--cds-ui-03, #e0e0e0);
|
|
112
|
-
padding: 1rem 8px;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.programs-container :global(.status-column) {
|
|
116
|
-
flex-grow: 0;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
:not(.header) .program.column {
|
|
120
|
-
display: flex;
|
|
121
|
-
align-items: center;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
:not(.header) .status.column {
|
|
125
|
-
display: flex;
|
|
126
|
-
flex-wrap: wrap;
|
|
127
|
-
align-items: center;
|
|
128
|
-
justify-content: flex-start;
|
|
129
|
-
gap: 12px;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.status.column :global(.reason-tooltip) {
|
|
133
|
-
height: 16px;
|
|
134
|
-
}
|
|
135
|
-
:not(.header) .status.column.no-tooltip {
|
|
136
|
-
flex-wrap: nowrap
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.programs-container :global(.status-icon-pending) {
|
|
140
|
-
fill: var(--cds-support-04);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.programs-container :global(.status-icon-complete) {
|
|
144
|
-
fill: var(--cds-support-04);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.programs-container :global(.status-icon-ineligible) {
|
|
148
|
-
margin-left: -4px;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.icon-and-tooltip {
|
|
152
|
-
display: flex;
|
|
153
|
-
align-items: center;
|
|
154
|
-
gap: 8px;
|
|
155
|
-
}
|
|
156
|
-
.icon-and-tooltip.wide-icon {
|
|
157
|
-
gap: 4px;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.tooltip-text-row {
|
|
161
|
-
grid-column: span 2;
|
|
162
|
-
background-color: #FBF1DA;
|
|
163
|
-
padding: 0.5rem 1rem;
|
|
164
|
-
display: none;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.tooltip-text-row.visible {
|
|
168
|
-
display: block;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.tooltip-text-item {
|
|
172
|
-
display: flex;
|
|
173
|
-
align-items: center;
|
|
174
|
-
gap: 0.5rem;
|
|
175
|
-
padding: 0.125rem 16px;
|
|
176
|
-
color: var(--cds-text-01);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
@media print {
|
|
180
|
-
.tooltip-text-row {
|
|
181
|
-
display: block !important;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
</style>
|