@reqquest/ui 1.11.0 → 1.12.1
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/README.md +23 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/keys.d.ts +47 -0
- package/dist/keys.js +1 -0
- package/dist/registry.d.ts +84 -13
- package/dist/registry.js +61 -11
- package/dist/typed-client/schema.d.ts +147 -0
- package/dist/typed-client/schema.graphql +127 -0
- package/dist/typed-client/schema.js +12 -0
- package/dist/typed-client/types.d.ts +55 -0
- package/dist/typed-client/types.js +759 -610
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,7 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
This library provides a set of Svelte components and utilities for building ReqQuest projects. You'll especially find the `api` useful for creating graphQL queries. In the future we will provide a small component library to help you build your prompts.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Registering your prompts
|
|
6
|
+
|
|
7
|
+
Every prompt your API defines needs a Svelte component registered here, and nothing links the two
|
|
8
|
+
automatically. Use the keyed form of `UIConfig` so a prompt you forget to register is a build error
|
|
9
|
+
rather than a broken screen:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const config = {
|
|
13
|
+
appName: 'My Program',
|
|
14
|
+
prompts: {
|
|
15
|
+
proof_of_residence_prompt: { formComponent: ResidencePrompt, displayComponent: ResidenceDisplay }
|
|
16
|
+
}
|
|
17
|
+
} satisfies UIConfig
|
|
18
|
+
export const uiRegistry = new UIRegistry(config)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
That check only has teeth once a key declaration augmenting `@reqquest/ui` is in your `src`. It is
|
|
22
|
+
generated on the **API** side, by the analyzer that ships with `@reqquest/api` — see
|
|
23
|
+
[docs/downstream-setup.md](../docs/downstream-setup.md). Without it, keys stay `string`, an
|
|
24
|
+
unregistered prompt renders an inline "unavailable" notice at runtime, and you find out when a user
|
|
25
|
+
reaches the screen.
|
|
26
|
+
|
|
27
|
+
# Developing this library
|
|
6
28
|
|
|
7
29
|
To develop the UI library, you'll want to work with the full demo, so `docker compose up --build` in the root of the repo. Similarly the test suite is combined with API tests, so run `./test.sh` in the root of the repo.
|
|
8
30
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/keys.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downstream projects augment this interface to teach the UI which keys their API registers. Once
|
|
3
|
+
* augmented, `UIConfig` rejects a component registered under an unknown key, and requires one for
|
|
4
|
+
* every prompt the API defines.
|
|
5
|
+
*
|
|
6
|
+
* This is a separate interface from the one in '@reqquest/api' by necessity: `@reqquest/ui` cannot
|
|
7
|
+
* depend on the API package without pulling fastify, mysql2 and type-graphql into a browser build.
|
|
8
|
+
* The generated declaration is plain string literals with no dependencies, so the same analyzer can
|
|
9
|
+
* emit one file augmenting each package:
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* node node_modules/@reqquest/api/dist/analysis/cli.js <api-project> \
|
|
13
|
+
* --emit-keys src/keys.generated.d.ts --module '@reqquest/ui'
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // src/keys.generated.d.ts - GENERATED, commit it
|
|
18
|
+
* export {}
|
|
19
|
+
* declare module '@reqquest/ui' {
|
|
20
|
+
* interface ReqQuestKeys {
|
|
21
|
+
* prompts: 'state_residence_prompt' | 'ssn_value_prompt'
|
|
22
|
+
* requirements: 'state_residence_req'
|
|
23
|
+
* programs: 'adopt_a_pet_program'
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* The `export {}` is load-bearing - without a top-level import or export the file is a global script
|
|
29
|
+
* and `declare module` REPLACES '@reqquest/ui' rather than augmenting it - and the file has to fall
|
|
30
|
+
* inside your tsconfig `include`, or it augments nothing and keys silently stay `string`.
|
|
31
|
+
*
|
|
32
|
+
* Regenerate when definitions change and gate it with `--check-keys`; a stale declaration offers keys
|
|
33
|
+
* the API no longer has.
|
|
34
|
+
*
|
|
35
|
+
* Leaving a slot unaugmented degrades its key type to `string`, so augmenting is entirely optional.
|
|
36
|
+
*/
|
|
37
|
+
export interface ReqQuestKeys {
|
|
38
|
+
}
|
|
39
|
+
type Slot<S extends keyof any> = ReqQuestKeys extends Record<S, infer T> ? T : never;
|
|
40
|
+
type SlotUnion<S extends keyof any> = [Slot<S>] extends [never] ? string : Extract<Slot<S>, string>;
|
|
41
|
+
/** Every prompt key in this application, or `string` when the `prompts` slot is not augmented. */
|
|
42
|
+
export type PromptKey = SlotUnion<'prompts'>;
|
|
43
|
+
/** Every requirement key in this application, or `string` when the `requirements` slot is not augmented. */
|
|
44
|
+
export type RequirementKey = SlotUnion<'requirements'>;
|
|
45
|
+
/** Every program key in this application, or `string` when the `programs` slot is not augmented. */
|
|
46
|
+
export type ProgramKey = SlotUnion<'programs'>;
|
|
47
|
+
export {};
|
package/dist/keys.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { LayoutStructureNode, LayoutStructureNodeRoot, UserProfile } from '@txstate-mws/carbon-svelte';
|
|
2
2
|
import type { Component } from 'svelte';
|
|
3
|
+
import type { ProgramKey, PromptKey, RequirementKey } from './keys.js';
|
|
3
4
|
export interface PromptLoader {
|
|
4
5
|
skeletonComponent: Component<any>;
|
|
5
6
|
/**
|
|
@@ -11,10 +12,10 @@ export interface PromptLoader {
|
|
|
11
12
|
export type Loader = PromptLoader | boolean;
|
|
12
13
|
export interface ProgramDefinition {
|
|
13
14
|
/**
|
|
14
|
-
* The key
|
|
15
|
-
*
|
|
15
|
+
* The key of the program this decorates. Autocompletes and rejects unknown keys once the project
|
|
16
|
+
* generates a key declaration; plain `string` until then.
|
|
16
17
|
*/
|
|
17
|
-
key:
|
|
18
|
+
key: ProgramKey;
|
|
18
19
|
/**
|
|
19
20
|
* An icon to represent this program in the navigation.
|
|
20
21
|
*/
|
|
@@ -22,10 +23,10 @@ export interface ProgramDefinition {
|
|
|
22
23
|
}
|
|
23
24
|
export interface RequirementDefinition {
|
|
24
25
|
/**
|
|
25
|
-
* The key
|
|
26
|
-
*
|
|
26
|
+
* The key of the requirement this decorates. Autocompletes and rejects unknown keys once the
|
|
27
|
+
* project generates a key declaration; plain `string` until then.
|
|
27
28
|
*/
|
|
28
|
-
key:
|
|
29
|
+
key: RequirementKey;
|
|
29
30
|
/**
|
|
30
31
|
* An icon to represent this requirement in the navigation. Requirements do not appear
|
|
31
32
|
* in the navigation in the applicant's view.
|
|
@@ -41,7 +42,11 @@ export interface RequirementDefinition {
|
|
|
41
42
|
configureDisplayComponent?: Component;
|
|
42
43
|
}
|
|
43
44
|
export interface PromptDefinition {
|
|
44
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The key of the prompt this renders. Autocompletes and rejects unknown keys once the project
|
|
47
|
+
* generates a key declaration; plain `string` until then.
|
|
48
|
+
*/
|
|
49
|
+
key: PromptKey;
|
|
45
50
|
/**
|
|
46
51
|
* The component that will be used to render the form for this prompt.
|
|
47
52
|
*
|
|
@@ -160,11 +165,37 @@ export interface Terminologies {
|
|
|
160
165
|
/**
|
|
161
166
|
* A type for the config object that should be exported from a CMS instance's admin/local/index.js
|
|
162
167
|
* to configure how that instance should work.
|
|
168
|
+
*
|
|
169
|
+
* Each of the three definition lists accepts either an array or a keyed object. **Prefer the keyed
|
|
170
|
+
* object.** An array can only reject a key the API does not have; it can never require the keys the
|
|
171
|
+
* API *does* have, so a prompt added on the API side and forgotten here compiles cleanly and fails
|
|
172
|
+
* in front of an applicant. The keyed form turns that into a build error, and also rejects
|
|
173
|
+
* duplicate keys, which an array silently resolves last-wins.
|
|
174
|
+
*
|
|
175
|
+
* `prompts` is the only list whose coverage is *required*, because it is the only one that is load
|
|
176
|
+
* bearing: a `PromptDefinition` supplies the component that renders the screen. `requirements` and
|
|
177
|
+
* `programs` carry optional decoration - an icon, a configuration component - and leaving one out
|
|
178
|
+
* is a supported choice, so their keyed form is partial. Both still reject unknown keys.
|
|
179
|
+
*
|
|
180
|
+
* This degrades on its own: `PromptKey` is `string` until a project generates a key declaration
|
|
181
|
+
* (see keys.ts), and `{ [K in string]: ... }` requires nothing - so an unaugmented project keeps
|
|
182
|
+
* working exactly as before.
|
|
183
|
+
*
|
|
184
|
+
* The type parameters exist for repos holding several applications, where the generated union spans
|
|
185
|
+
* all of them and no single config could satisfy it. Generate per-application aliases with the
|
|
186
|
+
* analyzer's `--groups` flag and instantiate against one, e.g.
|
|
187
|
+
* `UIConfig<SimplePromptKey, SimpleRequirementKey, SimpleProgramKey>`.
|
|
163
188
|
*/
|
|
164
|
-
export interface UIConfig {
|
|
165
|
-
programs: ProgramDefinition[]
|
|
166
|
-
|
|
167
|
-
|
|
189
|
+
export interface UIConfig<PK extends string = PromptKey, RK extends string = RequirementKey, GK extends string = ProgramKey> {
|
|
190
|
+
programs: ProgramDefinition[] | {
|
|
191
|
+
[K in GK]?: Omit<ProgramDefinition, 'key'>;
|
|
192
|
+
};
|
|
193
|
+
requirements: RequirementDefinition[] | {
|
|
194
|
+
[K in RK]?: Omit<RequirementDefinition, 'key'>;
|
|
195
|
+
};
|
|
196
|
+
prompts: PromptDefinition[] | {
|
|
197
|
+
[K in PK]: Omit<PromptDefinition, 'key'>;
|
|
198
|
+
};
|
|
168
199
|
/**
|
|
169
200
|
*
|
|
170
201
|
* @param login
|
|
@@ -273,18 +304,58 @@ export interface UIConfigWithDefaults extends UIConfig {
|
|
|
273
304
|
terminology: Required<Terminologies>;
|
|
274
305
|
plural: Required<Terminologies>;
|
|
275
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Any `UIConfig`, whichever key unions it was written against. `UIRegistry` accepts this rather
|
|
309
|
+
* than `UIConfig` itself: a `UIConfig<SimplePromptKey>` is not assignable to `UIConfig<PromptKey>`
|
|
310
|
+
* when the unions differ, and TypeScript does not allow a generic constructor to bridge them.
|
|
311
|
+
*
|
|
312
|
+
* Nothing is lost by widening here. Exhaustiveness is enforced where the config literal is written
|
|
313
|
+
* (`const config: UIConfig<SimplePromptKey, ...> = { ... }`), which is the only place that knows
|
|
314
|
+
* which application it belongs to.
|
|
315
|
+
*/
|
|
316
|
+
export type AnyUIConfig = Omit<UIConfig, 'programs' | 'requirements' | 'prompts'> & {
|
|
317
|
+
programs: ProgramDefinition[] | Record<string, Omit<ProgramDefinition, 'key'> | undefined>;
|
|
318
|
+
requirements: RequirementDefinition[] | Record<string, Omit<RequirementDefinition, 'key'> | undefined>;
|
|
319
|
+
prompts: PromptDefinition[] | Record<string, Omit<PromptDefinition, 'key'>>;
|
|
320
|
+
};
|
|
276
321
|
export declare class UIRegistry {
|
|
277
|
-
config: UIConfig;
|
|
278
322
|
protected promptMap: Record<string, PromptDefinition>;
|
|
279
323
|
protected requirementMap: Record<string, RequirementDefinition>;
|
|
280
324
|
protected programMap: Record<string, ProgramDefinition>;
|
|
281
325
|
protected userLookup?: (login: string) => Promise<UserProfile | undefined>;
|
|
282
326
|
protected lang: Required<Terminologies>;
|
|
283
327
|
protected plural: Required<Terminologies>;
|
|
284
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Widened to `AnyUIConfig` rather than `UIConfig`: a narrow `UIConfig<SimplePromptKey>` is not
|
|
330
|
+
* assignable to `UIConfig<PromptKey>` when the unions differ. Keeping the three definition lists
|
|
331
|
+
* on the type (instead of `Omit`ing them away) matters for consumers that read
|
|
332
|
+
* `uiRegistry.config.prompts` - dropping them would be a breaking change.
|
|
333
|
+
*/
|
|
334
|
+
config: AnyUIConfig;
|
|
335
|
+
constructor(config: AnyUIConfig);
|
|
285
336
|
getWord(key: keyof Terminologies, count?: number, inclusive?: boolean): string;
|
|
286
337
|
getPlural(key: keyof Terminologies): string;
|
|
287
338
|
getPrompt(key: string): PromptDefinition | undefined;
|
|
288
339
|
getRequirement(key: string): RequirementDefinition | undefined;
|
|
289
340
|
getProgram(key: string): ProgramDefinition | undefined;
|
|
341
|
+
/**
|
|
342
|
+
* `UIConfig` keeps this UI in step with the API it was built against.
|
|
343
|
+
* Keys arrive here from the API at runtime, so these stay `string` rather than the key unions.
|
|
344
|
+
*/
|
|
345
|
+
protected warnedMissing: Set<string>;
|
|
346
|
+
/**
|
|
347
|
+
* This is the ONLY runtime signal that the UI is missing a definition, so it is deliberately NOT
|
|
348
|
+
* gated on a dev-only build flag. Coverage is enforced at build time (see UIConfig's keyed form),
|
|
349
|
+
* but that gate lives in this repo's tooling and does not ship to downstream projects - a project
|
|
350
|
+
* that never wires its own type check has nothing but this line. Staying silent in production is
|
|
351
|
+
* how a missing prompt turns into an unexplained blank spot on an applicant's form.
|
|
352
|
+
* The `warnedMissing` set keeps it to one line per key, so a list of 200 prompts cannot spam.
|
|
353
|
+
*
|
|
354
|
+
* Severity splits by kind because the kinds are not equally load-bearing. A `PromptDefinition`
|
|
355
|
+
* supplies the component that actually renders the screen, so a missing one breaks a page.
|
|
356
|
+
* `RequirementDefinition` and `ProgramDefinition` carry only optional decoration - an icon, a
|
|
357
|
+
* configuration component - and every consumer optional-chains them. Leaving one unregistered is
|
|
358
|
+
* a supported choice, so it warns rather than errors.
|
|
359
|
+
*/
|
|
360
|
+
protected warnIfMissing<T>(kind: string, key: string, definition: T | undefined): T | undefined;
|
|
290
361
|
}
|
package/dist/registry.js
CHANGED
|
@@ -1,23 +1,46 @@
|
|
|
1
1
|
import { plural } from 'txstate-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Accepts either shape of a definition list and returns a key -> definition map. The keyed form
|
|
4
|
+
* carries its key in the object key, so it is grafted back on to keep every consumer's
|
|
5
|
+
* `definition.key` working.
|
|
6
|
+
*/
|
|
7
|
+
function toDefinitionMap(definitions) {
|
|
8
|
+
const map = {};
|
|
9
|
+
if (Array.isArray(definitions)) {
|
|
10
|
+
for (const definition of definitions)
|
|
11
|
+
map[definition.key] = definition;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
// an explicit `undefined` value is a hole in a partial record, not a registration
|
|
15
|
+
for (const [key, definition] of Object.entries(definitions)) {
|
|
16
|
+
if (definition != null)
|
|
17
|
+
map[key] = { ...definition, key };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return map;
|
|
21
|
+
}
|
|
2
22
|
export class UIRegistry {
|
|
3
|
-
config;
|
|
4
23
|
promptMap = {};
|
|
5
24
|
requirementMap = {};
|
|
6
25
|
programMap = {};
|
|
7
26
|
userLookup;
|
|
8
27
|
lang;
|
|
9
28
|
plural;
|
|
29
|
+
/**
|
|
30
|
+
* Widened to `AnyUIConfig` rather than `UIConfig`: a narrow `UIConfig<SimplePromptKey>` is not
|
|
31
|
+
* assignable to `UIConfig<PromptKey>` when the unions differ. Keeping the three definition lists
|
|
32
|
+
* on the type (instead of `Omit`ing them away) matters for consumers that read
|
|
33
|
+
* `uiRegistry.config.prompts` - dropping them would be a breaking change.
|
|
34
|
+
*/
|
|
35
|
+
config;
|
|
10
36
|
constructor(config) {
|
|
11
37
|
this.config = config;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.requirementMap[requirement.key] = requirement;
|
|
16
|
-
for (const program of config.programs)
|
|
17
|
-
this.programMap[program.key] = program;
|
|
38
|
+
this.promptMap = toDefinitionMap(config.prompts);
|
|
39
|
+
this.requirementMap = toDefinitionMap(config.requirements);
|
|
40
|
+
this.programMap = toDefinitionMap(config.programs);
|
|
18
41
|
this.userLookup = config.userLookup;
|
|
19
42
|
this.lang = {
|
|
20
|
-
appRequest: config.terminology?.appRequest ?? (
|
|
43
|
+
appRequest: config.terminology?.appRequest ?? (Object.keys(this.programMap).length > 1 ? 'App Request' : 'Application'),
|
|
21
44
|
login: config.terminology?.login ?? 'Login',
|
|
22
45
|
period: config.terminology?.period ?? 'Period'
|
|
23
46
|
};
|
|
@@ -33,12 +56,39 @@ export class UIRegistry {
|
|
|
33
56
|
return this.plural[key];
|
|
34
57
|
}
|
|
35
58
|
getPrompt(key) {
|
|
36
|
-
return this.promptMap[key];
|
|
59
|
+
return this.warnIfMissing('prompt', key, this.promptMap[key]);
|
|
37
60
|
}
|
|
38
61
|
getRequirement(key) {
|
|
39
|
-
return this.requirementMap[key];
|
|
62
|
+
return this.warnIfMissing('requirement', key, this.requirementMap[key]);
|
|
40
63
|
}
|
|
41
64
|
getProgram(key) {
|
|
42
|
-
return this.programMap[key];
|
|
65
|
+
return this.warnIfMissing('program', key, this.programMap[key]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* `UIConfig` keeps this UI in step with the API it was built against.
|
|
69
|
+
* Keys arrive here from the API at runtime, so these stay `string` rather than the key unions.
|
|
70
|
+
*/
|
|
71
|
+
warnedMissing = new Set();
|
|
72
|
+
/**
|
|
73
|
+
* This is the ONLY runtime signal that the UI is missing a definition, so it is deliberately NOT
|
|
74
|
+
* gated on a dev-only build flag. Coverage is enforced at build time (see UIConfig's keyed form),
|
|
75
|
+
* but that gate lives in this repo's tooling and does not ship to downstream projects - a project
|
|
76
|
+
* that never wires its own type check has nothing but this line. Staying silent in production is
|
|
77
|
+
* how a missing prompt turns into an unexplained blank spot on an applicant's form.
|
|
78
|
+
* The `warnedMissing` set keeps it to one line per key, so a list of 200 prompts cannot spam.
|
|
79
|
+
*
|
|
80
|
+
* Severity splits by kind because the kinds are not equally load-bearing. A `PromptDefinition`
|
|
81
|
+
* supplies the component that actually renders the screen, so a missing one breaks a page.
|
|
82
|
+
* `RequirementDefinition` and `ProgramDefinition` carry only optional decoration - an icon, a
|
|
83
|
+
* configuration component - and every consumer optional-chains them. Leaving one unregistered is
|
|
84
|
+
* a supported choice, so it warns rather than errors.
|
|
85
|
+
*/
|
|
86
|
+
warnIfMissing(kind, key, definition) {
|
|
87
|
+
if (definition == null && !this.warnedMissing.has(kind + ':' + key)) {
|
|
88
|
+
this.warnedMissing.add(kind + ':' + key);
|
|
89
|
+
const log = kind === 'prompt' ? console.error : console.warn;
|
|
90
|
+
log(`[reqquest] The API returned a ${kind} \`${key}\` that this UI has no definition for. Add it to your UIConfig, or regenerate your key declaration if the API has changed.`);
|
|
91
|
+
}
|
|
92
|
+
return definition;
|
|
43
93
|
}
|
|
44
94
|
}
|
|
@@ -8,6 +8,8 @@ export type Scalars = {
|
|
|
8
8
|
String: string;
|
|
9
9
|
};
|
|
10
10
|
export interface Access {
|
|
11
|
+
/** Current user is permitted to create announcements. */
|
|
12
|
+
createAnnouncement: Scalars['Boolean'];
|
|
11
13
|
/** Current user may create a new app request on behalf of another user and should be shown the Create App Request button on the reviewer dashboard or main app request list. */
|
|
12
14
|
createAppRequestOther: Scalars['Boolean'];
|
|
13
15
|
/** Current user may create a new app request for themselves and should be shown the Create App Request button. */
|
|
@@ -16,6 +18,10 @@ export interface Access {
|
|
|
16
18
|
createPeriod: Scalars['Boolean'];
|
|
17
19
|
/** Current user is permitted to create new roles in the role management UI. */
|
|
18
20
|
createRole: Scalars['Boolean'];
|
|
21
|
+
/** Current user is permitted to delete announcements. */
|
|
22
|
+
deleteAnnouncement: Scalars['Boolean'];
|
|
23
|
+
/** Current user is permitted to update announcements. */
|
|
24
|
+
updateAnnouncement: Scalars['Boolean'];
|
|
19
25
|
/** The current user, if any. */
|
|
20
26
|
user: (AccessUser | null);
|
|
21
27
|
/** Current user is permitted to view the app request list. */
|
|
@@ -154,6 +160,27 @@ export interface AccessUserIdentifier {
|
|
|
154
160
|
label: Scalars['String'];
|
|
155
161
|
__typename: 'AccessUserIdentifier';
|
|
156
162
|
}
|
|
163
|
+
/** A site-wide announcement shown to users, optionally limited to a date range. */
|
|
164
|
+
export interface Announcement {
|
|
165
|
+
/** The content of the announcement in HTML. */
|
|
166
|
+
body: Scalars['String'];
|
|
167
|
+
/** Whether the announcement has been turned on. A disabled announcement never displays, regardless of its date range. */
|
|
168
|
+
enabled: Scalars['Boolean'];
|
|
169
|
+
/** The announcement will not display after this date. Null means it displays until it is disabled. */
|
|
170
|
+
end: (Scalars['DateTime'] | null);
|
|
171
|
+
id: Scalars['ID'];
|
|
172
|
+
/** URL the announcement directs the user to for more information. */
|
|
173
|
+
link: (Scalars['String'] | null);
|
|
174
|
+
/** The text to display for the link. */
|
|
175
|
+
linkText: (Scalars['String'] | null);
|
|
176
|
+
/** The announcement will not display before this date. Null means it displays as soon as it is enabled. */
|
|
177
|
+
start: (Scalars['DateTime'] | null);
|
|
178
|
+
/** Short headline for the announcement. */
|
|
179
|
+
subject: Scalars['String'];
|
|
180
|
+
/** The type of announcement, toggleable or date range */
|
|
181
|
+
type: Scalars['String'];
|
|
182
|
+
__typename: 'Announcement';
|
|
183
|
+
}
|
|
157
184
|
/** Represents a group of applications all being applied for at the same time. As part of the request, multiple applications will be created and either eliminated as ineligible or submitted for approval. */
|
|
158
185
|
export interface AppRequest {
|
|
159
186
|
/** Actions the user can take on this app request. */
|
|
@@ -370,6 +397,8 @@ export type ApplicationPhase = 'ACCEPTANCE' | 'APPROVAL' | 'COMPLETE' | 'PREAPPR
|
|
|
370
397
|
/** The specific instance of a requirement on a particular application. Stores the status of the requirement, e.g. being satisfied or not. */
|
|
371
398
|
export interface ApplicationRequirement {
|
|
372
399
|
application: Application;
|
|
400
|
+
/** The prompt keys the requirement named as responsible for its current status. Used to attach status indicators to the specific answers at fault instead of every prompt the requirement consults. Null when the requirement did not name any, in which case all of its prompts are implicated. */
|
|
401
|
+
blame: (Scalars['String'][] | null);
|
|
373
402
|
/** The configuration data for this requirement in the app request's period. */
|
|
374
403
|
configurationData: (Scalars['JsonData'] | null);
|
|
375
404
|
/** An internal description of the requirement. Probably not shown to users. */
|
|
@@ -482,9 +511,13 @@ export interface Mutation {
|
|
|
482
511
|
completeRequest: ValidatedAppRequestResponse;
|
|
483
512
|
/** Make an offer on the app request. If all applications are ineligible, or if there are no acceptance requirements, the applications will advance to the non-blocking workflow, or absent that, be marked complete. */
|
|
484
513
|
completeReview: ValidatedAppRequestResponse;
|
|
514
|
+
/** Create a new site-wide announcement. */
|
|
515
|
+
createAnnouncement: ValidatedAnnouncementResponse;
|
|
485
516
|
/** Create a new app request. */
|
|
486
517
|
createAppRequest: ValidatedAppRequestResponse;
|
|
487
518
|
createPeriod: ValidatedPeriodResponse;
|
|
519
|
+
/** Delete an existing site-wide announcement. */
|
|
520
|
+
deleteAnnouncement: ValidatedResponse;
|
|
488
521
|
/** Delete an existing note. */
|
|
489
522
|
deleteNote: Scalars['Boolean'];
|
|
490
523
|
deletePeriod: ValidatedResponse;
|
|
@@ -515,6 +548,8 @@ export interface Mutation {
|
|
|
515
548
|
submitAppRequest: ValidatedAppRequestResponse;
|
|
516
549
|
/** Toggle an existing note's persistent status. */
|
|
517
550
|
togglePersistence: ValidatedNoteResponse;
|
|
551
|
+
/** Update an existing site-wide announcement. */
|
|
552
|
+
updateAnnouncement: ValidatedAnnouncementResponse;
|
|
518
553
|
updateConfiguration: ValidatedConfigurationResponse;
|
|
519
554
|
/** Update the content of an existing note. */
|
|
520
555
|
updateNote: ValidatedNoteResponse;
|
|
@@ -684,6 +719,8 @@ export interface Query {
|
|
|
684
719
|
*/
|
|
685
720
|
access: Access;
|
|
686
721
|
accessUsers: AccessUser[];
|
|
722
|
+
/** Retrieve site-wide announcements. Applicants only ever see currently active announcements; users with the Announcement view control see them all. */
|
|
723
|
+
announcements: Announcement[];
|
|
687
724
|
/** 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. */
|
|
688
725
|
appRequestActivity: AppRequestActivity[];
|
|
689
726
|
appRequestIndexes: IndexCategory[];
|
|
@@ -730,6 +767,8 @@ export interface RequirementPrompt {
|
|
|
730
767
|
moot: Scalars['Boolean'];
|
|
731
768
|
/** A human readable title for the prompt in the navigation. You probably want it to be shorter than the full title. If not provided, the title will be used. */
|
|
732
769
|
navTitle: Scalars['String'];
|
|
770
|
+
/** True when this row exists only because its requirement listed the prompt in `promptKeysNoDisplay` - a dependency it reads but does not own. Such a row must not be rendered beneath that requirement; the prompt is displayed under the requirement that does own it. This is not derivable from `visibility`: a no-display row is UNREACHABLE, but so is a prompt whose own requirement resolved before reaching it, and that one is still the requirement's to show. */
|
|
771
|
+
noDisplay: Scalars['Boolean'];
|
|
733
772
|
optOut: Scalars['Boolean'];
|
|
734
773
|
/** Preload data that has been generated according to the prompt definition. For example, a prompt might query the database for answers given in previous requests or query an external API to learn facts about the user. */
|
|
735
774
|
preloadData: (Scalars['JsonData'] | null);
|
|
@@ -754,6 +793,14 @@ export interface RoleActions {
|
|
|
754
793
|
update: Scalars['Boolean'];
|
|
755
794
|
__typename: 'RoleActions';
|
|
756
795
|
}
|
|
796
|
+
export interface ValidatedAnnouncementResponse {
|
|
797
|
+
/** The created or updated announcement. Null when validateOnly was true or when validation errors prevented the operation. */
|
|
798
|
+
announcement: (Announcement | null);
|
|
799
|
+
messages: MutationMessage[];
|
|
800
|
+
/** True if the mutation succeeded (e.g. saved data or passed validation), even if there were warnings. */
|
|
801
|
+
success: Scalars['Boolean'];
|
|
802
|
+
__typename: 'ValidatedAnnouncementResponse';
|
|
803
|
+
}
|
|
757
804
|
export interface ValidatedAppRequestResponse {
|
|
758
805
|
appRequest: (AppRequest | null);
|
|
759
806
|
messages: MutationMessage[];
|
|
@@ -790,6 +837,8 @@ export interface ValidatedResponse {
|
|
|
790
837
|
__typename: 'ValidatedResponse';
|
|
791
838
|
}
|
|
792
839
|
export interface AccessGenqlSelection {
|
|
840
|
+
/** Current user is permitted to create announcements. */
|
|
841
|
+
createAnnouncement?: boolean | number;
|
|
793
842
|
/** Current user may create a new app request on behalf of another user and should be shown the Create App Request button on the reviewer dashboard or main app request list. */
|
|
794
843
|
createAppRequestOther?: boolean | number;
|
|
795
844
|
/** Current user may create a new app request for themselves and should be shown the Create App Request button. */
|
|
@@ -798,6 +847,10 @@ export interface AccessGenqlSelection {
|
|
|
798
847
|
createPeriod?: boolean | number;
|
|
799
848
|
/** Current user is permitted to create new roles in the role management UI. */
|
|
800
849
|
createRole?: boolean | number;
|
|
850
|
+
/** Current user is permitted to delete announcements. */
|
|
851
|
+
deleteAnnouncement?: boolean | number;
|
|
852
|
+
/** Current user is permitted to update announcements. */
|
|
853
|
+
updateAnnouncement?: boolean | number;
|
|
801
854
|
/** The current user, if any. */
|
|
802
855
|
user?: AccessUserGenqlSelection;
|
|
803
856
|
/** Current user is permitted to view the app request list. */
|
|
@@ -1010,6 +1063,54 @@ export interface AccessUserIdentifierInput {
|
|
|
1010
1063
|
id: Scalars['ID'];
|
|
1011
1064
|
label: Scalars['String'];
|
|
1012
1065
|
}
|
|
1066
|
+
/** A site-wide announcement shown to users, optionally limited to a date range. */
|
|
1067
|
+
export interface AnnouncementGenqlSelection {
|
|
1068
|
+
/** The content of the announcement in HTML. */
|
|
1069
|
+
body?: boolean | number;
|
|
1070
|
+
/** Whether the announcement has been turned on. A disabled announcement never displays, regardless of its date range. */
|
|
1071
|
+
enabled?: boolean | number;
|
|
1072
|
+
/** The announcement will not display after this date. Null means it displays until it is disabled. */
|
|
1073
|
+
end?: boolean | number;
|
|
1074
|
+
id?: boolean | number;
|
|
1075
|
+
/** URL the announcement directs the user to for more information. */
|
|
1076
|
+
link?: boolean | number;
|
|
1077
|
+
/** The text to display for the link. */
|
|
1078
|
+
linkText?: boolean | number;
|
|
1079
|
+
/** The announcement will not display before this date. Null means it displays as soon as it is enabled. */
|
|
1080
|
+
start?: boolean | number;
|
|
1081
|
+
/** Short headline for the announcement. */
|
|
1082
|
+
subject?: boolean | number;
|
|
1083
|
+
/** The type of announcement, toggleable or date range */
|
|
1084
|
+
type?: boolean | number;
|
|
1085
|
+
__typename?: boolean | number;
|
|
1086
|
+
__scalar?: boolean | number;
|
|
1087
|
+
}
|
|
1088
|
+
export interface AnnouncementFilters {
|
|
1089
|
+
/** Return only the announcements that should be displayed at this moment: enabled OR within their date range. */
|
|
1090
|
+
active?: (Scalars['Boolean'] | null);
|
|
1091
|
+
/** Return only enabled (true) or only disabled (false) announcements. */
|
|
1092
|
+
enabled?: (Scalars['Boolean'] | null);
|
|
1093
|
+
/** Return the announcements with these IDs. */
|
|
1094
|
+
ids?: (Scalars['ID'][] | null);
|
|
1095
|
+
}
|
|
1096
|
+
export interface AnnouncementUpdate {
|
|
1097
|
+
/** The content of the announcement in HTML. Unsafe markup is stripped on save. */
|
|
1098
|
+
body?: (Scalars['String'] | null);
|
|
1099
|
+
/** Whether the announcement has been turned on. */
|
|
1100
|
+
enabled?: (Scalars['Boolean'] | null);
|
|
1101
|
+
/** The announcement will not display after this date. Null means it displays until it is disabled. */
|
|
1102
|
+
end?: (Scalars['DateTime'] | null);
|
|
1103
|
+
/** URL the announcement directs the user to for more information. */
|
|
1104
|
+
link?: (Scalars['String'] | null);
|
|
1105
|
+
/** The text to display for the link. Required when a link is given. */
|
|
1106
|
+
linkText?: (Scalars['String'] | null);
|
|
1107
|
+
/** The announcement will not display before this date. Null means it displays as soon as it is enabled. */
|
|
1108
|
+
start?: (Scalars['DateTime'] | null);
|
|
1109
|
+
/** Short headline for the announcement. */
|
|
1110
|
+
subject?: (Scalars['String'] | null);
|
|
1111
|
+
/** The type of announcement, toggleable or date range */
|
|
1112
|
+
type?: (Scalars['String'] | null);
|
|
1113
|
+
}
|
|
1013
1114
|
/** Represents a group of applications all being applied for at the same time. As part of the request, multiple applications will be created and either eliminated as ineligible or submitted for approval. */
|
|
1014
1115
|
export interface AppRequestGenqlSelection {
|
|
1015
1116
|
/** Actions the user can take on this app request. */
|
|
@@ -1308,6 +1409,8 @@ export interface ApplicationMetricTimingGenqlSelection {
|
|
|
1308
1409
|
/** The specific instance of a requirement on a particular application. Stores the status of the requirement, e.g. being satisfied or not. */
|
|
1309
1410
|
export interface ApplicationRequirementGenqlSelection {
|
|
1310
1411
|
application?: ApplicationGenqlSelection;
|
|
1412
|
+
/** The prompt keys the requirement named as responsible for its current status. Used to attach status indicators to the specific answers at fault instead of every prompt the requirement consults. Null when the requirement did not name any, in which case all of its prompts are implicated. */
|
|
1413
|
+
blame?: boolean | number;
|
|
1311
1414
|
/** The configuration data for this requirement in the app request's period. */
|
|
1312
1415
|
configurationData?: boolean | number;
|
|
1313
1416
|
/** An internal description of the requirement. Probably not shown to users. */
|
|
@@ -1501,6 +1604,13 @@ export interface MutationGenqlSelection {
|
|
|
1501
1604
|
appRequestId: Scalars['ID'];
|
|
1502
1605
|
};
|
|
1503
1606
|
});
|
|
1607
|
+
/** Create a new site-wide announcement. */
|
|
1608
|
+
createAnnouncement?: (ValidatedAnnouncementResponseGenqlSelection & {
|
|
1609
|
+
__args: {
|
|
1610
|
+
announcement: AnnouncementUpdate;
|
|
1611
|
+
validateOnly?: (Scalars['Boolean'] | null);
|
|
1612
|
+
};
|
|
1613
|
+
});
|
|
1504
1614
|
/** Create a new app request. */
|
|
1505
1615
|
createAppRequest?: (ValidatedAppRequestResponseGenqlSelection & {
|
|
1506
1616
|
__args: {
|
|
@@ -1516,6 +1626,12 @@ export interface MutationGenqlSelection {
|
|
|
1516
1626
|
validateOnly?: (Scalars['Boolean'] | null);
|
|
1517
1627
|
};
|
|
1518
1628
|
});
|
|
1629
|
+
/** Delete an existing site-wide announcement. */
|
|
1630
|
+
deleteAnnouncement?: (ValidatedResponseGenqlSelection & {
|
|
1631
|
+
__args: {
|
|
1632
|
+
announcementId: Scalars['ID'];
|
|
1633
|
+
};
|
|
1634
|
+
});
|
|
1519
1635
|
/** Delete an existing note. */
|
|
1520
1636
|
deleteNote?: {
|
|
1521
1637
|
__args: {
|
|
@@ -1635,6 +1751,14 @@ export interface MutationGenqlSelection {
|
|
|
1635
1751
|
noteId: Scalars['ID'];
|
|
1636
1752
|
};
|
|
1637
1753
|
});
|
|
1754
|
+
/** Update an existing site-wide announcement. */
|
|
1755
|
+
updateAnnouncement?: (ValidatedAnnouncementResponseGenqlSelection & {
|
|
1756
|
+
__args: {
|
|
1757
|
+
announcement: AnnouncementUpdate;
|
|
1758
|
+
announcementId: Scalars['ID'];
|
|
1759
|
+
validateOnly?: (Scalars['Boolean'] | null);
|
|
1760
|
+
};
|
|
1761
|
+
});
|
|
1638
1762
|
updateConfiguration?: (ValidatedConfigurationResponseGenqlSelection & {
|
|
1639
1763
|
__args: {
|
|
1640
1764
|
data: Scalars['JsonData'];
|
|
@@ -1894,6 +2018,12 @@ export interface QueryGenqlSelection {
|
|
|
1894
2018
|
paged?: (Pagination | null);
|
|
1895
2019
|
};
|
|
1896
2020
|
});
|
|
2021
|
+
/** Retrieve site-wide announcements. Applicants only ever see currently active announcements; users with the Announcement view control see them all. */
|
|
2022
|
+
announcements?: (AnnouncementGenqlSelection & {
|
|
2023
|
+
__args?: {
|
|
2024
|
+
filter?: (AnnouncementFilters | null);
|
|
2025
|
+
};
|
|
2026
|
+
});
|
|
1897
2027
|
/** 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. */
|
|
1898
2028
|
appRequestActivity?: (AppRequestActivityGenqlSelection & {
|
|
1899
2029
|
__args: {
|
|
@@ -1994,6 +2124,8 @@ export interface RequirementPromptGenqlSelection {
|
|
|
1994
2124
|
moot?: boolean | number;
|
|
1995
2125
|
/** A human readable title for the prompt in the navigation. You probably want it to be shorter than the full title. If not provided, the title will be used. */
|
|
1996
2126
|
navTitle?: boolean | number;
|
|
2127
|
+
/** True when this row exists only because its requirement listed the prompt in `promptKeysNoDisplay` - a dependency it reads but does not own. Such a row must not be rendered beneath that requirement; the prompt is displayed under the requirement that does own it. This is not derivable from `visibility`: a no-display row is UNREACHABLE, but so is a prompt whose own requirement resolved before reaching it, and that one is still the requirement's to show. */
|
|
2128
|
+
noDisplay?: boolean | number;
|
|
1997
2129
|
optOut?: boolean | number;
|
|
1998
2130
|
/** Preload data that has been generated according to the prompt definition. For example, a prompt might query the database for answers given in previous requests or query an external API to learn facts about the user. */
|
|
1999
2131
|
preloadData?: {
|
|
@@ -2040,6 +2172,15 @@ export interface RoleActionsGenqlSelection {
|
|
|
2040
2172
|
__typename?: boolean | number;
|
|
2041
2173
|
__scalar?: boolean | number;
|
|
2042
2174
|
}
|
|
2175
|
+
export interface ValidatedAnnouncementResponseGenqlSelection {
|
|
2176
|
+
/** The created or updated announcement. Null when validateOnly was true or when validation errors prevented the operation. */
|
|
2177
|
+
announcement?: AnnouncementGenqlSelection;
|
|
2178
|
+
messages?: MutationMessageGenqlSelection;
|
|
2179
|
+
/** True if the mutation succeeded (e.g. saved data or passed validation), even if there were warnings. */
|
|
2180
|
+
success?: boolean | number;
|
|
2181
|
+
__typename?: boolean | number;
|
|
2182
|
+
__scalar?: boolean | number;
|
|
2183
|
+
}
|
|
2043
2184
|
export interface ValidatedAppRequestResponseGenqlSelection {
|
|
2044
2185
|
appRequest?: AppRequestGenqlSelection;
|
|
2045
2186
|
messages?: MutationMessageGenqlSelection;
|
|
@@ -2122,6 +2263,9 @@ export declare const isAccessUser: (obj?: {
|
|
|
2122
2263
|
export declare const isAccessUserIdentifier: (obj?: {
|
|
2123
2264
|
__typename?: any;
|
|
2124
2265
|
} | null) => obj is AccessUserIdentifier;
|
|
2266
|
+
export declare const isAnnouncement: (obj?: {
|
|
2267
|
+
__typename?: any;
|
|
2268
|
+
} | null) => obj is Announcement;
|
|
2125
2269
|
export declare const isAppRequest: (obj?: {
|
|
2126
2270
|
__typename?: any;
|
|
2127
2271
|
} | null) => obj is AppRequest;
|
|
@@ -2224,6 +2368,9 @@ export declare const isRequirementPromptActions: (obj?: {
|
|
|
2224
2368
|
export declare const isRoleActions: (obj?: {
|
|
2225
2369
|
__typename?: any;
|
|
2226
2370
|
} | null) => obj is RoleActions;
|
|
2371
|
+
export declare const isValidatedAnnouncementResponse: (obj?: {
|
|
2372
|
+
__typename?: any;
|
|
2373
|
+
} | null) => obj is ValidatedAnnouncementResponse;
|
|
2227
2374
|
export declare const isValidatedAppRequestResponse: (obj?: {
|
|
2228
2375
|
__typename?: any;
|
|
2229
2376
|
} | null) => obj is ValidatedAppRequestResponse;
|