@reqquest/ui 1.1.1 → 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 -1159
- package/dist/components/FieldCardCheckbox.svelte +1 -1
- package/dist/components/index.js +2 -11
- package/dist/index.js +2 -4
- package/package.json +2 -2
- 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';
|
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,7 +23,7 @@
|
|
|
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",
|
|
@@ -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>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import Tooltip from "carbon-components-svelte/src/Tooltip/Tooltip.svelte";
|
|
3
|
-
import type { ApplicationForDetails } from './types'
|
|
4
|
-
|
|
5
|
-
export let application: ApplicationForDetails
|
|
6
|
-
</script>
|
|
7
|
-
|
|
8
|
-
{#if application.warningReasons.length || application.ineligibleReasons.length}
|
|
9
|
-
<Tooltip align="end" direction="bottom" triggerText="" class="reason-tooltip">
|
|
10
|
-
{#if application.ineligibleReasons.length}
|
|
11
|
-
<p><strong>Ineligible Because:</strong></p>
|
|
12
|
-
{#each application.ineligibleReasons as reason (reason)}
|
|
13
|
-
<p>{reason}</p>
|
|
14
|
-
{/each}
|
|
15
|
-
{:else if application.warningReasons.length}
|
|
16
|
-
<p><strong>Warnings:</strong></p>
|
|
17
|
-
{#each application.warningReasons as reason (reason)}
|
|
18
|
-
<p>{reason}</p>
|
|
19
|
-
{/each}
|
|
20
|
-
{/if}
|
|
21
|
-
</Tooltip>
|
|
22
|
-
{/if}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* This page collects prompt data from the applicant. Only one route exists per
|
|
4
|
-
* prompt, even if the prompt is shared between multiple applications. We should
|
|
5
|
-
* be able to figure out which application we are in based on the full state of
|
|
6
|
-
* the app request since the prompt should only be visible in a single spot.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { Form } from '@txstate-mws/carbon-svelte'
|
|
10
|
-
import type { FormStore } from '@txstate-mws/svelte-forms'
|
|
11
|
-
import Button from "carbon-components-svelte/src/Button/Button.svelte";
|
|
12
|
-
import { getContext } from 'svelte'
|
|
13
|
-
import type { Writable } from 'svelte/store'
|
|
14
|
-
import { afterNavigate, beforeNavigate, goto, invalidate } from '$app/navigation'
|
|
15
|
-
import type { ResolvedPathname } from '$app/types'
|
|
16
|
-
import { api, ButtonLoadingIcon } from '..'
|
|
17
|
-
import { uiRegistry } from '../../local/index.js'
|
|
18
|
-
import type { PageData } from '../../routes/requests/[id]/apply/[promptId]/$types.js'
|
|
19
|
-
|
|
20
|
-
export let data: PageData
|
|
21
|
-
$: ({ prompt, appRequestForExport } = data)
|
|
22
|
-
$: def = uiRegistry.getPrompt(prompt.key)
|
|
23
|
-
const nextHref = getContext<Writable<{ nextHref: ResolvedPathname, prevHref: ResolvedPathname | undefined }>>('nextHref')
|
|
24
|
-
|
|
25
|
-
let store: FormStore | undefined
|
|
26
|
-
let continueAfterSave = false
|
|
27
|
-
$: hasPreviousPrompt = $nextHref.prevHref != null
|
|
28
|
-
|
|
29
|
-
async function handleBack () {
|
|
30
|
-
const previousHref = $nextHref.prevHref
|
|
31
|
-
if (previousHref) {
|
|
32
|
-
// eslint-disable-next-line svelte/no-navigation-without-resolve -- already resolved
|
|
33
|
-
await goto(previousHref)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function onSubmit (data: any) {
|
|
38
|
-
const { success, messages } = await api.updatePrompt(prompt.id, data, false, appRequestForExport.dataVersion)
|
|
39
|
-
return {
|
|
40
|
-
success,
|
|
41
|
-
messages,
|
|
42
|
-
data
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function onValidate (data: any) {
|
|
47
|
-
const { messages } = await api.updatePrompt(prompt.id, data, true, appRequestForExport.dataVersion)
|
|
48
|
-
return messages
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function onSaved () {
|
|
52
|
-
await invalidate('request:apply')
|
|
53
|
-
if (continueAfterSave && prompt.answered) {
|
|
54
|
-
// eslint-disable-next-line svelte/no-navigation-without-resolve -- already resolved
|
|
55
|
-
await goto($nextHref.nextHref)
|
|
56
|
-
} else await store?.setData(appRequestForExport.data[prompt.key] as object)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Remove the form from the DOM when navigating between prompts
|
|
60
|
-
// to make sure state is reset
|
|
61
|
-
let hideForm = false
|
|
62
|
-
beforeNavigate(() => {
|
|
63
|
-
hideForm = true
|
|
64
|
-
})
|
|
65
|
-
afterNavigate(() => {
|
|
66
|
-
hideForm = false
|
|
67
|
-
})
|
|
68
|
-
</script>
|
|
69
|
-
|
|
70
|
-
{#if !hideForm}
|
|
71
|
-
<div class="prompt-intro flow max-w-screen-md mx-auto pt-10 px-6">
|
|
72
|
-
<!-- svelte-ignore a11y_autofocus -->
|
|
73
|
-
<h2 id="prompt-title" tabindex="-1" autofocus class="font-medium text-xl text-center">{prompt.title}</h2>
|
|
74
|
-
<p class="text-center"> {prompt.description}</p>
|
|
75
|
-
</div>
|
|
76
|
-
<Form bind:store hideFallbackMessage submit={onSubmit} validate={onValidate} preload={prompt.preloadData} on:saved={onSaved} let:data>
|
|
77
|
-
<svelte:component this={def!.formComponent} {data} appRequestId={appRequestForExport.id} appRequestData={appRequestForExport.data} fetched={prompt.fetchedData} configData={prompt.configurationData} gatheredConfigData={prompt.gatheredConfigData} />
|
|
78
|
-
<svelte:fragment slot="submit" let:submitting>
|
|
79
|
-
<div class='form-submit flex gap-12 justify-center mt-16'>
|
|
80
|
-
{#if hasPreviousPrompt}
|
|
81
|
-
<Button kind="ghost" on:click={handleBack}>Back</Button>
|
|
82
|
-
{/if}
|
|
83
|
-
<Button icon={submitting && !continueAfterSave ? ButtonLoadingIcon : null} type="submit" kind="secondary" disabled={submitting} on:click={() => { continueAfterSave = false }}>Save</Button>
|
|
84
|
-
<Button icon={submitting && !continueAfterSave ? ButtonLoadingIcon : null} type="submit" disabled={submitting} on:click={() => { continueAfterSave = true }}>Continue</Button>
|
|
85
|
-
</div>
|
|
86
|
-
</svelte:fragment>
|
|
87
|
-
</Form>
|
|
88
|
-
{/if}
|