-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsurvey.interface.ts
More file actions
348 lines (324 loc) · 11 KB
/
survey.interface.ts
File metadata and controls
348 lines (324 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
// Copyright The Linux Foundation and each contributor to LFX.
// SPDX-License-Identifier: MIT
import { CommitteeReference } from './committee.interface';
/**
* Minimal shape required to evaluate the effective survey status.
* @description Decoupled from `Survey`/`UserSurvey` so both interfaces (and any
* future survey-shaped value) can be passed without forcing a `Pick<>` at
* every call site or coupling status helpers to either interface's evolution.
*/
export interface SurveyStatusInput {
survey_status: string | null | undefined;
survey_cutoff_date: string | null | undefined;
}
/**
* Minimal shape required to evaluate the display status, which adds the
* `response_status` override on top of {@link SurveyStatusInput}.
*/
export interface SurveyDisplayStatusInput extends SurveyStatusInput {
response_status?: string | null;
}
/**
* User's survey participation
* @description Represents a user's participation in a survey - aligns with lfx-pcc IndividualSurveyResponse
*/
export interface UserSurvey {
/** Unique survey identifier */
survey_id: string;
/** Display title of the survey */
survey_title: string;
/** Current status of the survey (raw API value, may be uppercase like 'OPEN'/'SENT' or null; use getEffectiveSurveyStatus to normalize) */
survey_status: string | null;
/** Associated committees with allowed voting statuses */
committees: CommitteeReference[];
/** Survey deadline/cutoff date */
survey_cutoff_date: string;
/** User's response status (raw API value, may be uppercase or null; lowercase and compare to `SurveyResponseStatus` when normalizing this field) */
response_status: string | null;
/** Timestamp when user submitted their response (null if not responded) */
response_datetime: string | null;
}
/**
* Committee reference within a survey entity
* @description Committee data with response metrics and NPS scores
*/
export interface SurveyCommittee {
/** Committee ID */
committee_id: string;
/** Committee UID */
committee_uid: string;
/** Committee display name */
committee_name: string;
/** Project ID */
project_id: string;
/** Project UID */
project_uid: string;
/** Project display name */
project_name: string;
/** Total recipients for this committee */
total_recipients: number;
/** Total responses from this committee */
total_responses: number;
/** NPS score value */
nps_value: number;
/** Number of detractors */
num_detractors: number;
/** Number of passives */
num_passives: number;
/** Number of promoters */
num_promoters: number;
}
/**
* Survey dashboard entity
* @description Represents a survey in the dashboard/list view from the query service
*/
export interface Survey {
/** Unique survey identifier */
uid: string;
/** Display title of the survey */
survey_title: string;
/** Current status of the survey */
survey_status: string;
/** Survey deadline/cutoff date */
survey_cutoff_date: string;
/** Whether this is an NPS survey */
is_nps_survey: boolean;
/** Whether this is a project-level survey */
is_project_survey: boolean;
/** Associated committees */
committees: SurveyCommittee[];
/** Primary project UID (flattened from committees for filtering) */
project_uid?: string;
/** Project display name (enriched for filtering) */
project_name?: string;
/** Project URL slug (enriched for filtering) */
project_slug?: string;
/** Whether the project is a foundation (top-level entity) */
is_foundation?: boolean;
/** Parent project UID (for subprojects under a foundation) */
parent_project_uid?: string;
/** Committee category */
committee_category: string;
/** Total responses received */
total_responses: number;
/** Total recipients */
total_recipients: number;
/** Creation timestamp */
created_at: string;
/** Last modification timestamp */
last_modified_at: string;
/** Name of the creator */
creator_name: string;
/** Response collection status (e.g., 'closed' when responses are no longer accepted) */
response_status?: string;
/** Top-level NPS score from detail API (-100 to +100) */
nps_value?: number;
/** Number of promoters from detail API */
num_promoters?: number;
/** Number of passives from detail API */
num_passives?: number;
/** Number of detractors from detail API */
num_detractors?: number;
}
/**
* NPS breakdown data
* @description Breakdown of NPS responses into promoters, passives, and detractors
*/
export interface NpsBreakdown {
/** Number of promoters (score 9-10) */
promoters: number;
/** Number of passives (score 7-8) */
passives: number;
/** Number of detractors (score 0-6) */
detractors: number;
/** Number of non-responses */
nonResponses: number;
}
/**
* Survey comment from a participant
* @description Represents an individual comment submitted with a survey response
*/
export interface SurveyComment {
/** Unique comment identifier */
id: string;
/** Comment text content */
comment: string;
/** Timestamp when comment was submitted */
submitted_at: string;
}
/**
* Survey participation statistics
* @description Statistics about survey participation and response rates
*/
export interface SurveyParticipationStats {
/** Total number of eligible participants */
eligibleParticipants: number;
/** Total number of responses received */
totalResponses: number;
/** Participation rate as a percentage (0-100) */
participationRate: number;
}
/**
* Detailed survey results for the results drawer
* @description Extended survey data including NPS results and comments for display in results drawer
*/
export interface SurveyResultsDetail extends Survey {
/** NPS score (-100 to +100) - only for NPS surveys */
nps_score?: number;
/** NPS response breakdown - only for NPS surveys */
nps_breakdown?: NpsBreakdown;
/** Additional comments from participants */
additional_comments?: SurveyComment[];
}
/**
* NPS Gauge size options
* @description Available size presets for the NPS gauge component
*/
export type NpsGaugeSize = 'small' | 'medium' | 'large';
// ============================================================================
// Survey API Request Interfaces
// ============================================================================
/**
* Request body for creating a survey
* @description Aligns with LFX v2 survey service API contract
* @see https://github.com/linuxfoundation/lfx-v2-survey-service
*/
export interface CreateSurveyRequest {
/** SurveyMonkey template ID (required) */
survey_monkey_id: string;
/** Survey title (required) */
survey_title: string;
/** Whether to send immediately (required) */
send_immediately: boolean;
/** Scheduled send date in ISO 8601 format (required when send_immediately is false) */
survey_send_date: string;
/** Survey cutoff/close date in ISO 8601 format (required) */
survey_cutoff_date: string;
/** Reminder frequency in days (required) */
survey_reminder_rate_days: number;
/** Email subject line (required) */
email_subject: string;
/** HTML email body (required) */
email_body: string;
/** Plain text email body (required) */
email_body_text: string;
/** V2 committee UID (required) */
committee_uid: string;
/** Whether committee voting members are eligible (required) */
committee_voting_enabled: boolean;
/** Whether this is a project-level survey (false for committee-level surveys) */
is_project_survey?: boolean;
/** Stage filter for survey audience (optional) */
stage_filter?: string;
/** Username of the creator (enriched server-side from OIDC session) */
creator_username?: string;
/** Display name of the creator (enriched server-side from OIDC session) */
creator_name?: string;
/** Auth0 user ID of the creator (enriched server-side from OIDC session) */
creator_id?: string;
}
// ============================================================================
// Survey Manage Form Interfaces
// ============================================================================
/**
* Survey manage mode
* @description Determines if we're creating or editing a survey
*/
export type SurveyManageMode = 'create' | 'edit';
/**
* Survey type for survey creation
* @description Determines the type of survey being created
*/
export type SurveyType = 'nps' | 'standard';
/**
* Survey reminder frequency
* @description How often to send reminder emails
*/
export type SurveyReminderFrequency = 'none' | 'once' | 'weekly' | 'daily';
/**
* Survey distribution method
* @description When the survey should be distributed
*/
export type SurveyDistributionMethod = 'immediate' | 'scheduled';
/**
* Survey reminder type
* @description How reminders should be sent
*/
export type SurveyReminderType = 'automatic' | 'manual';
/**
* Survey form data structure
* @description Represents the form data for creating/editing a survey
*/
export interface SurveyFormData {
// Step 1: Audience & Type
/** Title of the survey */
title: string;
/** Selected committees/groups */
committees: CommitteeReference[];
/** Target audience filter (who receives the survey) */
audience: string;
/** Selected survey template */
surveyTemplate: string;
// Step 2: Timing & Reminders
/** Distribution method (immediate or scheduled) */
distributionMethod: SurveyDistributionMethod;
/** Scheduled date (only when distributionMethod is 'scheduled') */
scheduledDate: Date | null;
/** Survey cutoff/close date */
cutoffDate: Date | null;
/** Reminder type (automatic or manual) */
reminderType: SurveyReminderType;
/** Reminder frequency setting (only when reminderType is 'automatic') */
reminderFrequency: SurveyReminderFrequency;
// Step 3: Email Draft
/** Email subject line */
emailSubject: string;
/** Email body content */
emailBody: string;
}
/**
* Survey review form values
* @description Raw form values extracted for the review step display
*/
export interface SurveyReviewFormValue {
/** Selected survey template */
surveyTemplate: string;
/** Selected committees/groups */
committees: CommitteeReference[];
/** Distribution method (immediate or scheduled) */
distributionMethod: SurveyDistributionMethod;
/** Scheduled date (only when distributionMethod is 'scheduled') */
scheduledDate: Date | null;
/** Survey cutoff/close date */
cutoffDate: Date | null;
/** Reminder type (automatic or manual) */
reminderType: SurveyReminderType;
/** Reminder frequency value as string */
reminderFrequency: string;
/** Email subject line */
emailSubject: string;
/** Email body content */
emailBody: string;
}
/**
* Survey review data for display
* @description Formatted data for the review step
*/
export interface SurveyReviewData {
/** Display title */
title: string;
/** Committee/group name */
committeeName: string;
/** Audience description */
audienceLabel: string;
/** Survey type label */
surveyTypeLabel: string;
/** Formatted close date */
closeDateFormatted: string;
/** Reminder frequency label */
reminderLabel: string;
/** Email subject */
emailSubject: string;
/** Email body preview */
emailBodyPreview: string;
}