@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.
@@ -1,307 +0,0 @@
1
- <script lang="ts">
2
- import type { UIRegistry } from '../registry.js'
3
- import { getAppRequestStatusInfo, getApplicationStatusInfo, applicantRequirementTypes, reviewRequirementTypes } from '../status-utils.js'
4
- import type { Scalars } from '../typed-client/schema'
5
- import { enumRequirementType, type RequirementType } from '../typed-client/index.js'
6
- import { Panel, TagSet } from '@txstate-mws/carbon-svelte'
7
- import Button from "carbon-components-svelte/src/Button/Button.svelte";
8
- import InlineNotification from "carbon-components-svelte/src/Notification/InlineNotification.svelte";
9
- import Tooltip from "carbon-components-svelte/src/Tooltip/Tooltip.svelte";
10
- import Edit from 'carbon-icons-svelte/lib/Edit.svelte'
11
- import type { AnsweredPrompt, PromptSection, AppRequestForDetails, ApplicationForDetails } from './types'
12
- import RenderDisplayComponent from './RenderDisplayComponent.svelte'
13
- import ApplicantProgramList from './ApplicantProgramList.svelte'
14
- import WarningIconYellow from './WarningIconYellow.svelte'
15
-
16
- // TODO: design alignement could reduce props here
17
- export let appRequest: AppRequestForDetails
18
- export let applications: ApplicationForDetails[]
19
- export let appData: Scalars['JsonData'] = {}
20
- export let prequalPrompts: AnsweredPrompt[] | undefined = undefined
21
- export let postqualPrompts: AnsweredPrompt[] | undefined = undefined
22
- export let loading = false
23
- export let uiRegistry: UIRegistry
24
- export let title = 'View your application'
25
- export let subtitle = 'Select document names to preview them.'
26
- export let expandable = true
27
- export let showWarningsInline = false
28
- export let showCorrectionsInline = false
29
- export let showAppRequestStatus = true
30
- export let statusDisplay: 'tags' | 'icons' = 'tags'
31
- export let showTooltipsAsText = false
32
-
33
- const CORRECTABLE_STATUSES = ['STARTED', 'READY_TO_SUBMIT', 'DISQUALIFIED']
34
-
35
- $: canMakeCorrections = CORRECTABLE_STATUSES.includes(appRequest.status)
36
-
37
- // Group prompts by sections, with reviewer prompts nested within application sections
38
- $: sections = (() => {
39
- const sections: PromptSection[] = []
40
-
41
- // General Questions === PREQUAL prompts
42
- if (prequalPrompts?.length) {
43
- sections.push({ title: 'General Questions', prompts: prequalPrompts })
44
- }
45
-
46
- // Application-Specific Questions with nested Reviewer Questions
47
- for (const application of applications) {
48
- const applicantPrompts = application.requirements
49
- .filter(r => applicantRequirementTypes.has(r.type))
50
- .flatMap(r => r.prompts)
51
- const reviewerPrompts = application.requirements
52
- .filter(r => reviewRequirementTypes.has(r.type))
53
- .flatMap(r => r.prompts)
54
- const workflowPrompts = application.requirements
55
- .filter(r => r.type === enumRequirementType.WORKFLOW)
56
- .flatMap(r => r.prompts)
57
-
58
- if (applicantPrompts.length || reviewerPrompts.length || workflowPrompts.length) {
59
- const subsections: PromptSection[] = []
60
- if (reviewerPrompts.length) subsections.push({ title: 'Reviewer Questions', prompts: reviewerPrompts })
61
- if (workflowPrompts.length) subsections.push({ title: 'Workflow Questions', prompts: workflowPrompts })
62
- sections.push({
63
- title: application.title,
64
- prompts: applicantPrompts,
65
- subsections,
66
- applicationStatus: application.status
67
- })
68
- }
69
- }
70
-
71
- // Additional Questions === POSTQUAL prompts
72
- if (postqualPrompts?.length) {
73
- sections.push({ title: 'Additional Questions', prompts: postqualPrompts })
74
- }
75
-
76
- return sections
77
- })()
78
-
79
- function hasWarning (prompt: AnsweredPrompt) {
80
- return prompt.statusReasons.some(r => r.status === 'WARNING' || r.status === 'DISQUALIFYING')
81
- }
82
-
83
- function getWarnings (prompt: AnsweredPrompt) {
84
- return prompt.statusReasons.filter(r => r.status === 'WARNING' || r.status === 'DISQUALIFYING')
85
- }
86
-
87
- function needsCorrection (prompt: AnsweredPrompt) {
88
- return prompt.invalidated && prompt.invalidatedReason
89
- }
90
- </script>
91
-
92
- {#if appRequest}
93
- <div class="[ my-6 ] application-details flow">
94
- <!-- Application Status Panel -->
95
- <header class="[ mb-12 ] app-view-intro text-center">
96
- <h2 class="[ text-xl mb-3 ]">{title}</h2>
97
- <p class="app-view-subtitle mb-3">{subtitle}</p>
98
- </header>
99
- <section class="prompt-section">
100
- <div class="status-content">
101
- {#if showAppRequestStatus}
102
- <dl class="status-list-item [ flex items-center justify-between px-2 py-3 border-b ]">
103
- <dt class="status-list-label font-medium">Application Status</dt>
104
- <dd class="px-2">
105
- <TagSet tags={[{ label: getAppRequestStatusInfo(appRequest.status).label, type: getAppRequestStatusInfo(appRequest.status).color }]} />
106
- </dd>
107
- </dl>
108
- {/if}
109
-
110
- <!-- Application Status List -->
111
- <ApplicantProgramList {applications} viewMode={statusDisplay === 'tags'} {showTooltipsAsText} />
112
- </div>
113
- </section>
114
-
115
- <!-- Prompt Sections -->
116
- {#if loading}
117
- <Panel title="Loading...">
118
- <p>Loading prompt data...</p>
119
- </Panel>
120
- {:else if sections.length > 0}
121
- {#each sections as section (section.title)}
122
- <Panel title={section.title} {expandable} expanded>
123
- <svelte:fragment slot="headerLeft">
124
- {#if section.applicationStatus}
125
- <TagSet tags={[{ label: getApplicationStatusInfo(section.applicationStatus).label, type: getApplicationStatusInfo(section.applicationStatus).color }]} />
126
- {/if}
127
- </svelte:fragment>
128
- {#if section.prompts.length}
129
- <dl class="prompt-list">
130
- {#each section.prompts as prompt (prompt.id)}
131
- {@const def = uiRegistry.getPrompt(prompt.key)}
132
- <dt class="prompt-term [ font-medium ]">
133
- {#if showWarningsInline && hasWarning(prompt)}
134
- <Tooltip align="start">
135
- <div class="icon" slot="icon">
136
- <WarningIconYellow size={16} />
137
- </div>
138
- {#each getWarnings(prompt) as r, i (i)}
139
- <p>
140
- {r.status === 'WARNING' ? 'Warning' : 'Disqualifying'}{#if section.title !== r.programName}&nbsp;for {r.programName}{/if}<br>
141
- {r.statusReason}
142
- </p>
143
- {/each}
144
- </Tooltip>
145
- {/if}
146
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
147
- <Tooltip align="start">
148
- <div class="icon" slot="icon">
149
- <WarningIconYellow size={16} />
150
- </div>
151
- <p>Correction needed<br>{prompt.invalidatedReason}</p>
152
- </Tooltip>
153
- {/if}
154
- {prompt.title}
155
- </dt>
156
- <dd class="prompt-answer flow" class:large={def?.displayMode === 'large'}>
157
- <RenderDisplayComponent {def} appRequestId={appRequest.id} appData={appData} prompt={prompt} configData={prompt.configurationData} gatheredConfigData={prompt.gatheredConfigData} />
158
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
159
- <Button kind="ghost" size="small" icon={Edit} iconDescription="Edit this answer" href={`/requests/${appRequest.id}/apply/${prompt.id}`} class="edit-button" />
160
- {/if}
161
- </dd>
162
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
163
- <div class="correction-notice">
164
- <InlineNotification kind="warning-alt" title="Correction needed" subtitle={prompt.invalidatedReason ?? ''} hideCloseButton lowContrast />
165
- </div>
166
- {/if}
167
- {/each}
168
- </dl>
169
- {/if}
170
-
171
- <!-- Nested subsections (e.g., Reviewer Questions) -->
172
- {#if section.subsections}
173
- {#each section.subsections as subsection (subsection.title)}
174
- <Panel title={subsection.title} {expandable} expanded>
175
- <dl class="prompt-list">
176
- {#each subsection.prompts as prompt (prompt.id)}
177
- {@const def = uiRegistry.getPrompt(prompt.key)}
178
- <dt class="prompt-term [ font-medium ]">
179
- {#if showWarningsInline && hasWarning(prompt)}
180
- <Tooltip align="start">
181
- <div class="icon" slot="icon">
182
- <WarningIconYellow size={16} />
183
- </div>
184
- {#each getWarnings(prompt) as r, i (i)}
185
- <p>
186
- {r.status === 'WARNING' ? 'Warning' : 'Disqualifying'}{#if section.title !== r.programName}&nbsp;for {r.programName}{/if}<br>
187
- {r.statusReason}
188
- </p>
189
- {/each}
190
- </Tooltip>
191
- {/if}
192
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
193
- <Tooltip align="start">
194
- <div class="icon" slot="icon">
195
- <WarningIconYellow size={16} />
196
- </div>
197
- <p>Correction needed<br>{prompt.invalidatedReason}</p>
198
- </Tooltip>
199
- {/if}
200
- {prompt.title}
201
- </dt>
202
- <dd class="prompt-answer flow" class:large={def?.displayMode === 'large'}>
203
- <RenderDisplayComponent {def} appRequestId={appRequest.id} appData={appData} prompt={prompt} configData={prompt.configurationData} gatheredConfigData={prompt.gatheredConfigData} />
204
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
205
- <Button kind="ghost" size="small" icon={Edit} iconDescription="Edit this answer" href={`/requests/${appRequest.id}/apply/${prompt.id}`} class="edit-button" />
206
- {/if}
207
- </dd>
208
- {#if showCorrectionsInline && canMakeCorrections && needsCorrection(prompt)}
209
- <div class="correction-notice">
210
- <InlineNotification kind="warning-alt" title="Correction needed" subtitle={prompt.invalidatedReason ?? ''} hideCloseButton lowContrast />
211
- </div>
212
- {/if}
213
- {/each}
214
- </dl>
215
- </Panel>
216
- {/each}
217
- {/if}
218
- </Panel>
219
- {/each}
220
- {:else}
221
- <Panel title="Prompts and Answers">
222
- <p>No prompts available for this application.</p>
223
- </Panel>
224
- {/if}
225
-
226
- <slot name="footer" />
227
- </div>
228
- {:else}
229
- <p>No application selected</p>
230
- {/if}
231
-
232
- <style>
233
- .app-view-subtitle {
234
- color: var(--cds-text-02);
235
- /* margin-top: -0.5rem; */
236
- margin-bottom: 1rem;
237
- }
238
-
239
- .status-list-item {
240
- border-bottom: 1px solid var(--cds-border-subtle);
241
- }
242
-
243
- .prompt-answer :global(dl) {
244
- padding-block-start:1em;
245
- display:grid;
246
- grid-template-columns: 1fr 1fr;
247
- row-gap:0.5rem;
248
- }
249
-
250
- .status-content dl {
251
- padding-block-start:1em;
252
- display:grid;
253
- grid-template-columns: 2fr 1fr;
254
- row-gap:0.5rem;
255
- }
256
-
257
- .status-list-item {
258
- border-color: var(--cds-border-subtle);
259
- }
260
-
261
- .status-list-label {
262
- color: var(--cds-text-01);
263
- }
264
-
265
- .prompt-list {
266
- display: grid;
267
- grid-template-columns: 1fr 1fr;
268
- align-items: stretch;
269
- row-gap: 0.5rem;
270
- }
271
- .prompt-list dt, .prompt-list dd {
272
- padding-bottom: 0.5rem;
273
- }
274
-
275
- .prompt-term {
276
- display: flex;
277
- gap:1em;
278
- color: var(--cds-text-01);
279
- border-bottom: 1px solid var(--cds-border-subtle);
280
- }
281
- .prompt-term:has(+ .prompt-answer.large) {
282
- border-bottom: none;
283
- }
284
-
285
- .prompt-answer {
286
- color: var(--cds-text-02);
287
- border-bottom: 1px solid var(--cds-border-subtle);
288
- }
289
- .prompt-answer.large {
290
- grid-column: span 2;
291
- }
292
-
293
- .correction-notice {
294
- grid-column: span 2;
295
- margin-bottom: 0.5rem;
296
- }
297
-
298
- .correction-notice :global(.bx--inline-notification) {
299
- max-width: 100%;
300
- }
301
-
302
- .prompt-answer :global(.edit-button) {
303
- float: right;
304
- margin-top: -0.5rem;
305
- --cds-icon-01: var(--cds-link-01);
306
- }
307
- </style>
@@ -1,28 +0,0 @@
1
- <script lang="ts">
2
- import { ScreenReaderOnly } from '@txstate-mws/svelte-components'
3
- </script>
4
-
5
- <svg style:display="none"></svg>
6
- <span {...$$restProps} class="{$$restProps.class} loader" aria-hidden="false"><ScreenReaderOnly>loading</ScreenReaderOnly></span>
7
-
8
- <style>
9
- .loader {
10
- width: 16px;
11
- height: 16px;
12
- border: 3px solid #FFF;
13
- border-bottom-color: transparent;
14
- border-radius: 50%;
15
- display: inline-block;
16
- box-sizing: border-box;
17
- animation: rotation 1s linear infinite;
18
- }
19
-
20
- @keyframes rotation {
21
- 0% {
22
- transform: rotate(0deg);
23
- }
24
- 100% {
25
- transform: rotate(360deg);
26
- }
27
- }
28
- </style>
@@ -1,41 +0,0 @@
1
- <script lang="ts">
2
- import { TagSet } from '@txstate-mws/carbon-svelte'
3
- import type { TagItem } from '@txstate-mws/carbon-svelte'
4
-
5
- export let title = ''
6
- export let subtitle = ''
7
- export let tags: TagItem[] | undefined = undefined
8
- </script>
9
-
10
- <section class="bg-[var(--cds-ui-01)] py-4 px-[16px] text-2xl mb-2">
11
- <div class="repel">
12
- <div class="max-w-lg flex flex-col flex-wrap justify-start">
13
- {#if title}
14
- <div class="title-block [ flex gap-[12px] ] ">
15
- <h2 class="text-[1.25rem] text-[var(--cds-text-01,#1A1A1A)] font-normal leading-7">
16
- {title}
17
- </h2>
18
- {#if tags}
19
- <TagSet tags={tags} />
20
- {/if}
21
- </div>
22
- {#if subtitle}
23
- <p class="text-sm text-[var(--cds-text-02)] leading-[18px] tracking-[0.16px] pt-2">
24
- {subtitle}
25
- </p>
26
- {/if}
27
- {/if}
28
- <!-- Optional content slot below title/subtitle -->
29
- {#if $$slots.default}
30
- <div class="mt-2">
31
- <slot />
32
- </div>
33
- {/if}
34
- </div>
35
- {#if $$slots['block-end']}
36
- <div class="block-end-slot">
37
- <slot name="block-end" />
38
- </div>
39
- {/if}
40
- </div>
41
- </section>
@@ -1,100 +0,0 @@
1
- <script lang="ts">
2
- import { ActionSet, Panel, TagSet } from '@txstate-mws/carbon-svelte'
3
- import Tab from "carbon-components-svelte/src/Tabs/Tab.svelte";
4
- import TabContent from "carbon-components-svelte/src/Tabs/TabContent.svelte";
5
- import Tabs from "carbon-components-svelte/src/Tabs/Tabs.svelte";
6
- import Tag from "carbon-components-svelte/src/Tag/Tag.svelte";
7
- import SettingsEdit from "carbon-icons-svelte/lib/SettingsEdit.svelte";
8
- import View from "carbon-icons-svelte/lib/View.svelte";
9
- import { invalidate } from '$app/navigation'
10
- import { api } from '../api'
11
- import { page } from '$app/stores'
12
- import type { UIRegistry } from '../registry'
13
- import { groupby, pluralize } from 'txstate-utils'
14
-
15
- export let program: any
16
- export let sharedProgramRequirements: any
17
- export let openModal: any
18
- export let onClick: any
19
- export let uiRegistry: UIRegistry
20
-
21
- const disablePeriodProgram = (requirementKey: string) => async () => {
22
- const res = await api.disablePeriodProgramRequirements($page.params.id!, requirementKey, true)
23
- await invalidate('api:getPeriodConfigurations')
24
- }
25
-
26
- const enablePeriodProgram = (requirementKey: string) => async () => {
27
- const res = await api.disablePeriodProgramRequirements($page.params.id!, requirementKey, false)
28
- await invalidate('api:getPeriodConfigurations')
29
- }
30
-
31
- $: enabledRequirements = Object.entries(groupby(program.requirements.filter(r => r.enabled), 'type'))
32
- $: disabledRequirements = program.requirements.filter(r => !r.enabled)
33
-
34
- </script>
35
- <Panel title={program.title} expandable expanded>
36
- {#each enabledRequirements as requrementEntries}
37
- {@const type = requrementEntries[0]}
38
- {@const requirements = requrementEntries[1]}
39
- <Panel title='' expandable expanded>
40
- <div style="display: content" slot="headerLeft">
41
- <TagSet tags={[{ label: `Applicant: ${type}`, type: 'purple' }]} />
42
- </div>
43
- <div style="display: content" slot="headerRight">
44
- <TagSet tags={[{ label: `${requirements.length} ${pluralize('requirement', requirements.length)}`, type: 'yellow' }]} />
45
- </div>
46
- <Tabs autoWidth>
47
- <Tab label={`Enabled Requirements (${enabledRequirements.length})`} />
48
- <Tab label={`Disabled Requirements (${disabledRequirements.length})`} />
49
- <svelte:fragment slot='content'>
50
- <TabContent>
51
- {#each requirements as requirement (requirement.key)}
52
- {@const reqDef = uiRegistry.getRequirement(requirement.key)}
53
- <Panel title={requirement.title} expandable noPrimaryAction actions={[{ label: 'Configure requirement', onClick: onClick('requirement', requirement), disabled: reqDef?.configureComponent == null || !requirement.configuration.actions.update }, { label: 'Disable Requirement', onClick: disablePeriodProgram(requirement.key) }]}>
54
- <div style="display: content" slot="headerLeft">
55
- <TagSet tags={[{ label: 'Requirement', type: 'yellow' }]} />
56
- </div>
57
- <!-- <Button on:click={onClick('requirement', requirement)} type="primary" size="small" icon={SettingsEdit} iconDescription="Edit Configuration" disabled={reqDef.configureComponent == null || !requirement.configuration.actions.update} /> -->
58
- <div style="display: content" slot="headerRight">
59
- {@const tags = sharedProgramRequirements[requirement.key]?.length > 1 ? [{ label: 'Shared', onClick: openModal(requirement.key) }] : []}
60
- <TagSet tags={tags} />
61
- </div>
62
-
63
- <ul class="prompts">
64
- {#each requirement.prompts as prompt (prompt.key)}
65
- {@const promptDef = uiRegistry.getPrompt(prompt.key)}
66
- <li class="prompt justify-between">
67
- <span>
68
- <Tag type='green'>Prompt</Tag>{prompt.title}
69
- </span>
70
- <ActionSet
71
- actions={[
72
- // { label: 'View', icon: View },
73
- { label: 'settings', icon: SettingsEdit, disabled: promptDef?.configureComponent == null || !prompt.configuration.actions.update, onClick: onClick('prompt', prompt) }
74
- ]}
75
- />
76
- </li>
77
- {/each}
78
- </ul>
79
- </Panel>
80
- {/each}
81
- </TabContent>
82
- <TabContent>
83
- {#each disabledRequirements as requirement (requirement.key)}
84
- <Panel title={requirement.title} actions={[{ label: 'Enable Requirement', onClick: enablePeriodProgram(requirement.key) }]}>
85
- Requirement: {requirement.title}
86
- <ul class="prompts">
87
- {#each requirement.prompts as prompt (prompt.key)}
88
- <li class="prompt">
89
- Prompt: {prompt.title}
90
- </li>
91
- {/each}
92
- </ul>
93
- </Panel>
94
- {/each}
95
- </TabContent>
96
- </svelte:fragment>
97
- </Tabs>
98
- </Panel>
99
- {/each}
100
- </Panel>
@@ -1,38 +0,0 @@
1
- <script lang="ts">
2
- import InlineNotification from "carbon-components-svelte/src/Notification/InlineNotification.svelte";
3
- import type { PromptDefinition } from '../registry'
4
-
5
- export let def: PromptDefinition | undefined
6
- export let appRequestId: string
7
- export let appData: Record<string, any>
8
- export let prompt: { key: string, answered: boolean, moot: boolean | null, invalidated: boolean | null, invalidatedReason: string | null }
9
- export let configData: Record<string, any>
10
- export let gatheredConfigData: Record<string, any>
11
- export let showMoot = false
12
- </script>
13
-
14
- <svelte:boundary onerror={e => console.error(e)}>
15
- {#if showMoot && prompt.moot}
16
- <em>Already disqualified.</em>
17
- {:else if !prompt.answered}
18
- <em>Incomplete</em>
19
- {:else if !def?.displayComponent}
20
- <em>No display component registered.</em>
21
- <pre>{JSON.stringify(appData[prompt.key] ?? {}, null, 2)}</pre>
22
- {:else}
23
- <svelte:component this={def.displayComponent} {appRequestId} data={appData[prompt.key]} appRequestData={appData} {configData} {gatheredConfigData} />
24
- {/if}
25
- {#if prompt.invalidated && (showMoot || !prompt.moot)}
26
- <InlineNotification kind="warning" title="Correction Needed" subtitle={prompt.invalidatedReason ?? undefined} class="mt-2" lowContrast hideCloseButton />
27
- {/if}
28
- {#snippet failed()}
29
- <div class="error">
30
- <div>Error Loading Component</div>
31
- <p>There was an error loading the display component for this prompt.</p>
32
- </div>
33
- {/snippet}
34
- </svelte:boundary>
35
-
36
- <style>
37
- .error div { font-weight: bold; }
38
- </style>
@@ -1,93 +0,0 @@
1
- <script lang="ts">
2
- import { base } from "$app/paths"
3
- import { ColumnList, FieldDate, FieldMultiselect, Pagination, type ActionItem } from "@txstate-mws/carbon-svelte"
4
- import { DateTime } from "luxon"
5
- import View from 'carbon-icons-svelte/lib/View.svelte'
6
- import DocExport from 'carbon-icons-svelte/lib/DocumentExport.svelte'
7
- import { downloadCsv } from "../csv"
8
- import type { AppRequest } from "../typed-client"
9
- import { pluralize } from "txstate-utils"
10
-
11
- export let data: AppRequest[]
12
- export let title: string
13
- export let subtitle: string
14
-
15
- const selectedActions = (rows: AppRequest[]): ActionItem[] => [
16
- {
17
- label: `Download ${rows.length} ${pluralize('application', rows.length)}`,
18
- // icon: TrashCan,
19
- onClick: () => { console.log(rows); downloadCsv(formatCSVData(rows)) }
20
- }
21
- ]
22
-
23
- function formatCSVData (d: AppRequest[]) {
24
- return d.map(d => ({
25
- Id: d.id,
26
- Period: d.period.name,
27
- 'TXST ID': d.applicant.otherInfo,
28
- Name: d.applicant.fullname,
29
- 'Date Submitted': DateTime.fromISO(d.createdAt).toFormat('f').replace(',', ''),
30
- Benefit: `"${d.applications.map(a => a.title).join(', ')}"`,
31
- 'Last Submitted': DateTime.fromISO(d.updatedAt).toFormat('f').replace(',', '')
32
- }))
33
- }
34
- </script>
35
-
36
- <div class="flow [ p-4 bg-gray-100 ]">
37
- <h2 class="[ text-lg ]">{title}</h2>
38
- <p class="[ text-gray-600 ]">{subtitle}</p>
39
- </div>
40
-
41
- <ColumnList
42
- searchable
43
- filterTitle='Request Filters'
44
- {selectedActions}
45
- listActions={[
46
- { label: 'Download', icon: DocExport, onClick: () => { console.log(data); downloadCsv(formatCSVData(data)) } }
47
- ]}
48
- columns={[
49
- { id: 'request', label: 'Request #', tags: (row) => [{ label: String(row.id), }] },
50
- { id: 'period', label: 'Period', render: r => r.period.name },
51
- { id: 'aNumber', label: 'TXST ID' },
52
- { id: 'name', label: 'Name', get: 'applicant.fullname' },
53
- { id: 'dateSubmitted', label: 'Date Submitted', render: r => DateTime.fromISO(r.createdAt).toFormat('f') },
54
- { id: 'benefit', label: 'Benefit', render: r => r.applications.map(a => a.title).join(', ') },
55
- { id: 'lastUpdated', label: 'Last Updated', render: r => DateTime.fromISO(r.updatedAt).toFormat('f') },
56
- ]}
57
- rows={data}
58
- title="App Requests"
59
-
60
- actions={r => [
61
- {
62
- label: 'View',
63
- icon: View,
64
- // href: `${base}/requests/${r.id}/apply`
65
- href: `${base}/requests/${r.id}/approve`
66
- }
67
- ]}
68
- >
69
- <svelte:fragment slot="filters">
70
- <FieldMultiselect
71
- path="period"
72
- labelText="Period"
73
- items={[]}
74
- placeholder="Choose one or more"
75
- />
76
- <FieldDate
77
- path='dateSubmitted'
78
- label='Date Submitted'
79
- />
80
- <FieldMultiselect
81
- path="test"
82
- labelText="Period"
83
- items={[]}
84
- placeholder="Choose one or more"
85
- />
86
- </svelte:fragment>
87
- </ColumnList>
88
-
89
- <Pagination
90
- totalItems={data.length}
91
- pageSize={25}
92
- chooseSize
93
- />
@@ -1,35 +0,0 @@
1
- <script lang="ts">
2
- import { BadgeNumber } from '@txstate-mws/carbon-svelte'
3
- import Accordion from "carbon-components-svelte/src/Accordion/Accordion.svelte";
4
- import AccordionItem from "carbon-components-svelte/src/Accordion/AccordionItem.svelte";
5
-
6
- export let items: { id: string, message: string }[] = []
7
- export let variant: 'warning' | 'error' = 'error'
8
- export let accordionTitle = 'Multiple items'
9
-
10
- $: badgeStyle = variant === 'warning'
11
- ? '--badge-bg: var(--yellow-01, #F3D690); --badge-text: #6F510C'
12
- : '--badge-bg: #FBE9EA; --badge-text: #a11c25'
13
- </script>
14
-
15
- {#if items.length === 1}
16
- <div class="flex items-center">
17
- <BadgeNumber value={1} class="mt-2 mr-2" style={badgeStyle} />
18
- <p class="mt-2 mb-0 text-sm">{items[0].message}</p>
19
- </div>
20
- {:else if items.length > 1}
21
- <div class="flex">
22
- <BadgeNumber value={items.length} class="mt-5 mr-2" style={badgeStyle} />
23
- <div class="mt-2 w-full">
24
- <Accordion align="start">
25
- <AccordionItem title={accordionTitle}>
26
- <ol class="list-decimal">
27
- {#each items as item (item.id)}
28
- <li>{item.message}</li>
29
- {/each}
30
- </ol>
31
- </AccordionItem>
32
- </Accordion>
33
- </div>
34
- </div>
35
- {/if}
@@ -1,20 +0,0 @@
1
- <script lang="ts">
2
- import WarningAltFilled from "carbon-icons-svelte/lib/WarningAltFilled.svelte";
3
- import type { ComponentProps } from 'svelte'
4
-
5
- interface $$Props extends ComponentProps<typeof WarningAltFilled> {}
6
- </script>
7
-
8
- <div>
9
- <WarningAltFilled {...$$restProps} />
10
- </div>
11
-
12
- <style>
13
- div :global(svg) {
14
- fill: var(--cds-support-03, rgba(239, 200, 108, 1)) !important;
15
- }
16
-
17
- div :global([data-icon-path="inner-path"]) {
18
- fill: black;
19
- }
20
- </style>