@transcend-io/mcp-server-assessment 0.5.30 → 2.0.0

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,4 +1,4 @@
1
- import { PaginationSchema, TranscendGraphQLBase, createListResult, createToolResult, defineTool, z } from "@transcend-io/mcp-server-base";
1
+ import { OffsetPaginationSchema, TranscendGraphQLBase, assertOffsetInRange, createListResult, createToolResult, defineTool, derivePageInfo, describeNoMatches, z } from "@transcend-io/mcp-server-base";
2
2
  import { AssessmentFormStatus, AssessmentFormTemplateStatus, ScopeName } from "@transcend-io/privacy-types";
3
3
  //#region src/tools/assessments_add_section.ts
4
4
  const AddSectionSchema = z.object({
@@ -100,7 +100,7 @@ async function resolveTemplateToGroupId(graphql, templateId) {
100
100
  const CreateAssessmentSchema = z.object({
101
101
  title: z.string().describe("Title of the assessment"),
102
102
  assessmentGroupId: z.string().optional().describe("ID of the assessment group to create the assessment in (preferred). Use assessments_list_groups to find available groups."),
103
- templateId: z.string().optional().describe("ID of the assessment template. If assessmentGroupId is not provided, the first group using this template will be used."),
103
+ templateId: z.string().optional().describe("Fallback for when no group is known. Lands the assessment in whichever group happens to be first among those built from this template, so never use it when the user named a group."),
104
104
  assigneeIds: z.array(z.string()).optional().describe("Array of user IDs to assign the assessment to")
105
105
  });
106
106
  function createAssessmentsCreateTool(clients) {
@@ -108,7 +108,7 @@ function createAssessmentsCreateTool(clients) {
108
108
  const { dashboardUrl } = clients;
109
109
  return defineTool({
110
110
  name: "assessments_create",
111
- description: "Create a new privacy assessment within an assessment group. Assessment groups are linked to templates. You can provide either an assessmentGroupId directly, or a templateId to auto-resolve the first matching group. Use assessments_list_groups to find available groups. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
111
+ description: "Create a new privacy assessment inside an assessment group. Prefer assessmentGroupId, resolved by name through assessments_list_groups. templateId is a fallback that lands in whichever group happens to be first among those built from that template, so never use it when the user named a particular group. Surface the returned `url` verbatim; never build assessment URLs from IDs.",
112
112
  category: "Assessments",
113
113
  readOnly: false,
114
114
  annotations: {
@@ -158,7 +158,7 @@ function createAssessmentsCreateGroupTool(clients) {
158
158
  const { dashboardUrl } = clients;
159
159
  return defineTool({
160
160
  name: "assessments_create_group",
161
- description: "Create a new assessment group linked to a template. Assessment groups are containers for assessments. The response includes a `groupUrl` field with the canonical admin-dashboard link to the group — surface that to the user verbatim.",
161
+ description: "Create a new assessment group linked to a template. Assessment groups are containers for assessments. Surface the returned `groupUrl` verbatim.",
162
162
  category: "Assessments",
163
163
  readOnly: false,
164
164
  annotations: {
@@ -303,13 +303,52 @@ function createAssessmentsGetTool(clients) {
303
303
  //#endregion
304
304
  //#region src/tools/assessments_list.ts
305
305
  const AssessmentStatusEnum = z.nativeEnum(AssessmentFormStatus);
306
- const ListAssessmentsSchema = z.object({ status: AssessmentStatusEnum.optional().describe("Filter by assessment status") }).merge(PaginationSchema);
306
+ /**
307
+ * Accepts a bare date or a full timestamp, since the GraphQL `Date` scalar
308
+ * takes both and callers phrase deadlines either way.
309
+ */
310
+ const isoDate = (field) => z.string().regex(/^\d{4}-\d{2}-\d{2}([T ].*)?$/, { message: `${field} must be an ISO 8601 date, e.g. 2026-01-31 or 2026-01-31T00:00:00Z` }).optional();
311
+ /**
312
+ * An optional list filter that rejects `[]`.
313
+ *
314
+ * Empty arrays are dropped during filter assembly, so a caller that resolved a
315
+ * lookup to nothing and passed the result through would have its filter read as
316
+ * "no filter given" and get back every assessment in the organization — the
317
+ * widest possible answer to a query that should have matched none.
318
+ */
319
+ const idList = (description) => z.array(z.string()).min(1, { message: "Pass at least one value, or omit the filter entirely." }).optional().describe(description);
320
+ /** Caller-facing sort names mapped onto `AssessmentFormRawOrderField`. */
321
+ const SORT_FIELDS = {
322
+ title: "title",
323
+ status: "statusRank",
324
+ submittedAt: "submittedAt"
325
+ };
326
+ const ListAssessmentsSchema = z.object({
327
+ statuses: z.array(AssessmentStatusEnum).min(1, { message: "Pass at least one status, or omit the filter entirely." }).optional().describe("Lifecycle statuses to include. Omit for every status."),
328
+ text: z.string().optional().describe("Free-text match on the assessment title"),
329
+ ids: idList("Specific assessment form IDs to fetch"),
330
+ assigneeIds: idList("Transcend user IDs the form is assigned to. Resolve names with `admin_list_users`."),
331
+ reviewerIds: idList("Transcend user IDs reviewing the form. Resolve names with `admin_list_users`."),
332
+ externalAssigneeEmails: idList("Email addresses of external (vendor) assignees"),
333
+ assessmentGroupIds: idList("Groups the forms belong to; see `assessments_list_groups`"),
334
+ createdAfter: isoDate("createdAfter").describe("Only forms created strictly after this date"),
335
+ createdBefore: isoDate("createdBefore").describe("Only forms created on or before this date"),
336
+ dueAfter: isoDate("dueAfter").describe("Only forms due strictly after this date"),
337
+ dueBefore: isoDate("dueBefore").describe("Only forms due on or before this date. Use for overdue."),
338
+ sortBy: z.enum([
339
+ "title",
340
+ "status",
341
+ "submittedAt"
342
+ ], { message: "sortBy must be one of: title, status, submittedAt" }).optional().describe("Column to sort on; the API offers no creation-date sort. Omit for its default order."),
343
+ sortDirection: z.enum(["ASC", "DESC"], { message: "sortDirection must be ASC or DESC" }).optional().default("ASC").describe("Sort direction. Only applied alongside `sortBy`."),
344
+ includeDetails: z.boolean().optional().default(false).describe("Also return assignees, reviewers, due/updated/submitted dates and lock state.")
345
+ }).merge(OffsetPaginationSchema);
307
346
  function createAssessmentsListTool(clients) {
308
347
  const graphql = clients.graphql;
309
348
  const { dashboardUrl } = clients;
310
349
  return defineTool({
311
350
  name: "assessments_list",
312
- description: "List all privacy assessments in your organization. Supports filtering by status. Each row includes a `url` field with the canonical admin-dashboard link for that assessment — surface those to the user verbatim and do not construct assessment URLs from raw IDs. Note: Cursor pagination is not supported (max 100 results).",
351
+ description: "List all assessments in your organization. Surface the `url` on each row verbatim; never build assessment URLs from IDs.",
313
352
  category: "Assessments",
314
353
  readOnly: true,
315
354
  annotations: {
@@ -318,34 +357,94 @@ function createAssessmentsListTool(clients) {
318
357
  idempotentHint: true
319
358
  },
320
359
  zodSchema: ListAssessmentsSchema,
321
- handler: async ({ status, limit, cursor }) => {
360
+ handler: async ({ statuses, text, ids, assigneeIds, reviewerIds, externalAssigneeEmails, assessmentGroupIds, createdAfter, createdBefore, dueAfter, dueBefore, sortBy, sortDirection, includeDetails, limit, offset }) => {
361
+ const filterBy = {
362
+ ...statuses?.length && { statuses },
363
+ ...text && { text },
364
+ ...ids?.length && { ids },
365
+ ...assigneeIds?.length && { assigneeIds },
366
+ ...reviewerIds?.length && { reviewerIds },
367
+ ...externalAssigneeEmails?.length && { externalAssigneeEmails },
368
+ ...assessmentGroupIds?.length && { assessmentGroupIds },
369
+ ...createdAfter && { createdAtAfter: createdAfter },
370
+ ...createdBefore && { createdAtBefore: createdBefore },
371
+ ...dueAfter && { dueDateAfter: dueAfter },
372
+ ...dueBefore && { dueDateBefore: dueBefore }
373
+ };
374
+ const appliedFilters = Object.entries({
375
+ statuses: statuses?.length,
376
+ text,
377
+ ids: ids?.length,
378
+ assigneeIds: assigneeIds?.length,
379
+ reviewerIds: reviewerIds?.length,
380
+ externalAssigneeEmails: externalAssigneeEmails?.length,
381
+ assessmentGroupIds: assessmentGroupIds?.length,
382
+ createdAfter,
383
+ createdBefore,
384
+ dueAfter,
385
+ dueBefore
386
+ }).filter(([, value]) => Boolean(value)).map(([name]) => name);
322
387
  const result = await graphql.listAssessments({
323
388
  first: limit,
324
- after: cursor,
325
- filterBy: status ? { statuses: [status] } : void 0
389
+ offset,
390
+ filterBy,
391
+ includeDetails,
392
+ ...sortBy && {
393
+ sortField: SORT_FIELDS[sortBy],
394
+ sortDirection
395
+ }
396
+ });
397
+ const totalCount = result.totalCount ?? 0;
398
+ assertOffsetInRange({
399
+ subject: "assessment",
400
+ offset,
401
+ totalCount,
402
+ appliedFilters
326
403
  });
327
- return createListResult(result.nodes.map((node) => ({
404
+ const nodesWithLinks = result.nodes.map((node) => ({
328
405
  ...node,
329
406
  ...buildAssessmentLinks({
330
407
  dashboardUrl,
331
408
  assessmentFormId: node.id
332
409
  })
333
- })), {
334
- totalCount: result.totalCount,
335
- hasNextPage: result.pageInfo?.hasNextPage
410
+ }));
411
+ return createListResult(nodesWithLinks, {
412
+ totalCount,
413
+ hasNextPage: result.pageInfo?.hasNextPage,
414
+ paginationNote: describeOutcome({
415
+ returned: nodesWithLinks.length,
416
+ totalCount,
417
+ offset,
418
+ limit,
419
+ appliedFilters
420
+ })
336
421
  });
337
422
  }
338
423
  });
339
424
  }
425
+ /**
426
+ * Tells the caller which of three situations it is in: nothing matched, more
427
+ * pages remain, or this is everything. Without this an empty `data` array reads
428
+ * the same as a filter typo, and the agent reports "no assessments" to the user.
429
+ */
430
+ function describeOutcome({ returned, totalCount, offset, limit, appliedFilters }) {
431
+ if (totalCount === 0) return describeNoMatches("assessments", appliedFilters);
432
+ if (offset + returned < totalCount) return `Showing ${returned} of ${totalCount} matches. Fetch the next page with offset ${offset + limit}.`;
433
+ return offset === 0 ? `Showing all ${returned} match${returned === 1 ? "" : "es"}. No further pages.` : `Showing the last ${returned} of ${totalCount} matches. No further pages.`;
434
+ }
340
435
  //#endregion
341
436
  //#region src/tools/assessments_list_groups.ts
342
- const ListGroupsSchema = PaginationSchema;
437
+ const ListGroupsSchema = OffsetPaginationSchema.extend({
438
+ text: z.string().optional().describe("Free-text match on the group title and description"),
439
+ ids: z.array(z.string()).min(1, { message: "Pass at least one group ID, or omit the filter entirely." }).optional().describe("Specific group IDs, e.g. the `assessmentGroupId` on an `assessments_list` row"),
440
+ templateIds: z.array(z.string()).min(1, { message: "Pass at least one template ID, or omit the filter entirely." }).optional().describe("Groups built from these templates; see `assessments_list_templates`")
441
+ });
343
442
  function createAssessmentsListGroupsTool(clients) {
344
443
  const graphql = clients.graphql;
345
444
  const { dashboardUrl } = clients;
346
445
  return defineTool({
347
446
  name: "assessments_list_groups",
348
- description: "List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments. Each row includes a `groupUrl` field with the canonical admin-dashboard link — surface those to the user verbatim.",
447
+ description: "List all assessment groups. Groups are containers for assessments and are linked to templates. Use this to find the right group ID for creating assessments. To reach the template behind a form, pass its `assessmentGroupId` as `ids` and read `assessmentFormTemplate`. Surface the `groupUrl` on each row verbatim.",
349
448
  category: "Assessments",
350
449
  readOnly: true,
351
450
  annotations: {
@@ -354,29 +453,52 @@ function createAssessmentsListGroupsTool(clients) {
354
453
  idempotentHint: true
355
454
  },
356
455
  zodSchema: ListGroupsSchema,
357
- handler: async ({ limit, cursor }) => {
456
+ handler: async ({ limit, offset, text, ids, templateIds }) => {
358
457
  const result = await graphql.listAssessmentGroups({
359
458
  first: limit,
360
- after: cursor
459
+ offset,
460
+ filterBy: {
461
+ ...text && { text },
462
+ ...ids?.length && { ids },
463
+ ...templateIds?.length && { templateIds }
464
+ }
361
465
  });
362
- return createListResult(result.nodes.map((node) => ({
466
+ const nodesWithLinks = result.nodes.map((node) => ({
363
467
  ...node,
364
468
  groupUrl: buildAssessmentGroupUrl(dashboardUrl, node.id)
365
- })), {
469
+ }));
470
+ const appliedFilters = Object.entries({
471
+ text,
472
+ ids: ids?.length,
473
+ templateIds: templateIds?.length
474
+ }).filter(([, value]) => Boolean(value)).map(([name]) => name);
475
+ const totalCount = result.totalCount ?? 0;
476
+ assertOffsetInRange({
477
+ subject: "assessment group",
478
+ offset,
479
+ totalCount,
480
+ appliedFilters
481
+ });
482
+ return createListResult(nodesWithLinks, {
366
483
  totalCount: result.totalCount,
367
- hasNextPage: result.pageInfo?.hasNextPage
484
+ hasNextPage: result.pageInfo?.hasNextPage,
485
+ ...totalCount === 0 && { paginationNote: describeNoMatches("assessment groups", appliedFilters) }
368
486
  });
369
487
  }
370
488
  });
371
489
  }
372
490
  //#endregion
373
491
  //#region src/tools/assessments_list_templates.ts
374
- const ListTemplatesSchema = PaginationSchema;
492
+ const ListTemplatesSchema = OffsetPaginationSchema.extend({
493
+ text: z.string().optional().describe("Free-text match on the template title and description"),
494
+ ids: z.array(z.string()).min(1, { message: "Pass at least one template ID, or omit the filter entirely." }).optional().describe("Specific template IDs to fetch"),
495
+ statuses: z.array(z.enum(["DRAFT", "PUBLISHED"])).min(1, { message: "Pass at least one status, or omit the filter entirely." }).optional().describe("Publication statuses to include. Omit for both.")
496
+ });
375
497
  function createAssessmentsListTemplatesTool(clients) {
376
498
  const graphql = clients.graphql;
377
499
  return defineTool({
378
500
  name: "assessments_list_templates",
379
- description: "List all available assessment templates. Note: Cursor pagination is not supported by the Transcend API for templates - use limit to control results (max 100).",
501
+ description: "List the blank assessment templates. Only `PUBLISHED` ones can build new assessments.",
380
502
  category: "Assessments",
381
503
  readOnly: true,
382
504
  annotations: {
@@ -385,14 +507,32 @@ function createAssessmentsListTemplatesTool(clients) {
385
507
  idempotentHint: true
386
508
  },
387
509
  zodSchema: ListTemplatesSchema,
388
- handler: async ({ limit, cursor }) => {
510
+ handler: async ({ limit, offset, text, ids, statuses }) => {
389
511
  const result = await graphql.listAssessmentTemplates({
390
512
  first: limit,
391
- after: cursor
513
+ offset,
514
+ filterBy: {
515
+ ...text && { text },
516
+ ...ids?.length && { ids },
517
+ ...statuses?.length && { statuses }
518
+ }
519
+ });
520
+ const appliedFilters = Object.entries({
521
+ text,
522
+ ids: ids?.length,
523
+ statuses: statuses?.length
524
+ }).filter(([, value]) => Boolean(value)).map(([name]) => name);
525
+ const totalCount = result.totalCount ?? 0;
526
+ assertOffsetInRange({
527
+ subject: "template",
528
+ offset,
529
+ totalCount,
530
+ appliedFilters
392
531
  });
393
532
  return createListResult(result.nodes, {
394
533
  totalCount: result.totalCount,
395
- hasNextPage: result.pageInfo?.hasNextPage
534
+ hasNextPage: result.pageInfo?.hasNextPage,
535
+ ...totalCount === 0 && { paginationNote: describeNoMatches("templates", appliedFilters) }
396
536
  });
397
537
  }
398
538
  });
@@ -401,9 +541,9 @@ function createAssessmentsListTemplatesTool(clients) {
401
541
  //#region src/tools/assessments_prefill.ts
402
542
  const PrefillSchema = z.object({
403
543
  title: z.string().describe("Title for the new assessment form"),
404
- templateId: z.string().optional().describe("Template ID to create the form from. Will auto-resolve to the first matching assessment group."),
405
- assessmentGroupId: z.string().optional().describe("Assessment group ID (alternative to templateId)"),
406
- answers: z.record(z.string(), z.union([z.string(), z.array(z.string())])).describe("Map of answers keyed by question title or referenceId. Values should be strings for text/single-select, or arrays of strings for multi-select."),
544
+ templateId: z.string().optional().describe("Fallback for when no group is known. Lands the form in whichever group happens to be first among those built from this template, so never use it when the user named a group."),
545
+ assessmentGroupId: z.string().optional().describe("Group to create the form in (preferred). Resolve by name with `assessments_list_groups`."),
546
+ answers: z.record(z.string(), z.union([z.string(), z.array(z.string())])).describe("Map of answers keyed by question title or referenceId, both of which come from assessments_export_template on the template you are creating from. A string for text and single-select, an array for multi-select. Select answers must match the option text exactly."),
407
547
  assigneeIds: z.array(z.string()).optional().describe("Internal user IDs to assign the form to (optional)"),
408
548
  assigneeEmails: z.array(z.string()).optional().describe("External email addresses to assign the form to (optional)"),
409
549
  reviewerIds: z.array(z.string()).optional().describe("User IDs to set as reviewers (optional)"),
@@ -413,7 +553,7 @@ function createAssessmentsPrefillTool(clients) {
413
553
  const graphql = clients.graphql;
414
554
  return defineTool({
415
555
  name: "assessments_prefill",
416
- description: "Convenience tool: Create a new assessment form, AI-prefill all the answers, and assign it to a reviewer. Combines: create form → get questions → answer each question → assign reviewers → optionally submit for review. Provide answers as a map of {questionTitle: answer} or {referenceId: answer}. For SINGLE_SELECT/MULTI_SELECT, the answer should match the exact text of the answer option(s). For text questions, provide the free-text answer string. For multi-select, provide an array of answer option values.",
556
+ description: "Create an assessment form, fill in the answers you supply, and assign it for review in one call. Combines: create form → read its questions → answer each → assign reviewers → optionally submit. The answers are yours to provide; nothing is generated for you.",
417
557
  category: "Assessments",
418
558
  readOnly: false,
419
559
  annotations: {
@@ -569,7 +709,7 @@ function createAssessmentsSubmitResponseTool(clients) {
569
709
  const { dashboardUrl } = clients;
570
710
  return defineTool({
571
711
  name: "assessments_submit_response",
572
- description: "Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status. The response includes a `url` field pointing at the assessment-group page where reviewers can find the submitted form — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
712
+ description: "Submit an assessment form for review. Optionally specify which sections to submit. This transitions the assessment toward the IN_REVIEW status. The returned `url` points at the assessment-group page where reviewers find the submitted form — surface it verbatim; never build assessment URLs from IDs.",
573
713
  category: "Assessments",
574
714
  readOnly: false,
575
715
  annotations: {
@@ -613,7 +753,7 @@ function createAssessmentsUpdateTool(clients) {
613
753
  const { dashboardUrl } = clients;
614
754
  return defineTool({
615
755
  name: "assessments_update",
616
- description: "Update an existing assessment. The response includes a `url` field with the canonical admin-dashboard link — surface that to the user verbatim and do not construct assessment URLs from raw IDs.",
756
+ description: "Update an existing assessment. Surface the returned `url` verbatim; never build assessment URLs from IDs.",
617
757
  category: "Assessments",
618
758
  readOnly: false,
619
759
  annotations: {
@@ -711,7 +851,7 @@ const ASSESSMENT_OAUTH_SCOPES = [
711
851
  //#endregion
712
852
  //#region src/__generated__/gql.ts
713
853
  const documents = {
714
- "\n query AssessmentsList($first: Int, $filterBy: AssessmentFormFiltersInput) {\n assessmentForms(first: $first, filterBy: $filterBy) {\n nodes {\n id\n title\n status\n createdAt\n assessmentGroup {\n id\n }\n }\n totalCount\n }\n }\n": {
854
+ "\n query AssessmentsList(\n $first: Int\n $offset: Int\n $filterBy: AssessmentFormFiltersInput\n $orderBy: [AssessmentFormRawOrder!]\n $includeDetails: Boolean!\n ) {\n assessmentForms(first: $first, offset: $offset, filterBy: $filterBy, orderBy: $orderBy) {\n nodes {\n id\n title\n status\n createdAt\n assessmentGroup {\n id\n title\n }\n dueDate @include(if: $includeDetails)\n updatedAt @include(if: $includeDetails)\n submittedAt @include(if: $includeDetails)\n isArchived @include(if: $includeDetails)\n isLocked @include(if: $includeDetails)\n assignees @include(if: $includeDetails) {\n id\n name\n email\n }\n reviewers @include(if: $includeDetails) {\n id\n name\n email\n }\n externalAssignees @include(if: $includeDetails) {\n id\n email\n }\n }\n totalCount\n }\n }\n": {
715
855
  "kind": "Document",
716
856
  "definitions": [{
717
857
  "kind": "OperationDefinition",
@@ -720,39 +860,102 @@ const documents = {
720
860
  "kind": "Name",
721
861
  "value": "AssessmentsList"
722
862
  },
723
- "variableDefinitions": [{
724
- "kind": "VariableDefinition",
725
- "variable": {
726
- "kind": "Variable",
727
- "name": {
728
- "kind": "Name",
729
- "value": "first"
863
+ "variableDefinitions": [
864
+ {
865
+ "kind": "VariableDefinition",
866
+ "variable": {
867
+ "kind": "Variable",
868
+ "name": {
869
+ "kind": "Name",
870
+ "value": "first"
871
+ }
872
+ },
873
+ "type": {
874
+ "kind": "NamedType",
875
+ "name": {
876
+ "kind": "Name",
877
+ "value": "Int"
878
+ }
730
879
  }
731
880
  },
732
- "type": {
733
- "kind": "NamedType",
734
- "name": {
735
- "kind": "Name",
736
- "value": "Int"
881
+ {
882
+ "kind": "VariableDefinition",
883
+ "variable": {
884
+ "kind": "Variable",
885
+ "name": {
886
+ "kind": "Name",
887
+ "value": "offset"
888
+ }
889
+ },
890
+ "type": {
891
+ "kind": "NamedType",
892
+ "name": {
893
+ "kind": "Name",
894
+ "value": "Int"
895
+ }
737
896
  }
738
- }
739
- }, {
740
- "kind": "VariableDefinition",
741
- "variable": {
742
- "kind": "Variable",
743
- "name": {
744
- "kind": "Name",
745
- "value": "filterBy"
897
+ },
898
+ {
899
+ "kind": "VariableDefinition",
900
+ "variable": {
901
+ "kind": "Variable",
902
+ "name": {
903
+ "kind": "Name",
904
+ "value": "filterBy"
905
+ }
906
+ },
907
+ "type": {
908
+ "kind": "NamedType",
909
+ "name": {
910
+ "kind": "Name",
911
+ "value": "AssessmentFormFiltersInput"
912
+ }
746
913
  }
747
914
  },
748
- "type": {
749
- "kind": "NamedType",
750
- "name": {
751
- "kind": "Name",
752
- "value": "AssessmentFormFiltersInput"
915
+ {
916
+ "kind": "VariableDefinition",
917
+ "variable": {
918
+ "kind": "Variable",
919
+ "name": {
920
+ "kind": "Name",
921
+ "value": "orderBy"
922
+ }
923
+ },
924
+ "type": {
925
+ "kind": "ListType",
926
+ "type": {
927
+ "kind": "NonNullType",
928
+ "type": {
929
+ "kind": "NamedType",
930
+ "name": {
931
+ "kind": "Name",
932
+ "value": "AssessmentFormRawOrder"
933
+ }
934
+ }
935
+ }
936
+ }
937
+ },
938
+ {
939
+ "kind": "VariableDefinition",
940
+ "variable": {
941
+ "kind": "Variable",
942
+ "name": {
943
+ "kind": "Name",
944
+ "value": "includeDetails"
945
+ }
946
+ },
947
+ "type": {
948
+ "kind": "NonNullType",
949
+ "type": {
950
+ "kind": "NamedType",
951
+ "name": {
952
+ "kind": "Name",
953
+ "value": "Boolean"
954
+ }
955
+ }
753
956
  }
754
957
  }
755
- }],
958
+ ],
756
959
  "selectionSet": {
757
960
  "kind": "SelectionSet",
758
961
  "selections": [{
@@ -761,33 +964,64 @@ const documents = {
761
964
  "kind": "Name",
762
965
  "value": "assessmentForms"
763
966
  },
764
- "arguments": [{
765
- "kind": "Argument",
766
- "name": {
767
- "kind": "Name",
768
- "value": "first"
769
- },
770
- "value": {
771
- "kind": "Variable",
967
+ "arguments": [
968
+ {
969
+ "kind": "Argument",
772
970
  "name": {
773
971
  "kind": "Name",
774
972
  "value": "first"
973
+ },
974
+ "value": {
975
+ "kind": "Variable",
976
+ "name": {
977
+ "kind": "Name",
978
+ "value": "first"
979
+ }
775
980
  }
776
- }
777
- }, {
778
- "kind": "Argument",
779
- "name": {
780
- "kind": "Name",
781
- "value": "filterBy"
782
981
  },
783
- "value": {
784
- "kind": "Variable",
982
+ {
983
+ "kind": "Argument",
984
+ "name": {
985
+ "kind": "Name",
986
+ "value": "offset"
987
+ },
988
+ "value": {
989
+ "kind": "Variable",
990
+ "name": {
991
+ "kind": "Name",
992
+ "value": "offset"
993
+ }
994
+ }
995
+ },
996
+ {
997
+ "kind": "Argument",
785
998
  "name": {
786
999
  "kind": "Name",
787
1000
  "value": "filterBy"
1001
+ },
1002
+ "value": {
1003
+ "kind": "Variable",
1004
+ "name": {
1005
+ "kind": "Name",
1006
+ "value": "filterBy"
1007
+ }
1008
+ }
1009
+ },
1010
+ {
1011
+ "kind": "Argument",
1012
+ "name": {
1013
+ "kind": "Name",
1014
+ "value": "orderBy"
1015
+ },
1016
+ "value": {
1017
+ "kind": "Variable",
1018
+ "name": {
1019
+ "kind": "Name",
1020
+ "value": "orderBy"
1021
+ }
788
1022
  }
789
1023
  }
790
- }],
1024
+ ],
791
1025
  "selectionSet": {
792
1026
  "kind": "SelectionSet",
793
1027
  "selections": [{
@@ -824,15 +1058,307 @@ const documents = {
824
1058
  "kind": "Field",
825
1059
  "name": {
826
1060
  "kind": "Name",
827
- "value": "createdAt"
1061
+ "value": "createdAt"
1062
+ }
1063
+ },
1064
+ {
1065
+ "kind": "Field",
1066
+ "name": {
1067
+ "kind": "Name",
1068
+ "value": "assessmentGroup"
1069
+ },
1070
+ "selectionSet": {
1071
+ "kind": "SelectionSet",
1072
+ "selections": [{
1073
+ "kind": "Field",
1074
+ "name": {
1075
+ "kind": "Name",
1076
+ "value": "id"
1077
+ }
1078
+ }, {
1079
+ "kind": "Field",
1080
+ "name": {
1081
+ "kind": "Name",
1082
+ "value": "title"
1083
+ }
1084
+ }]
1085
+ }
1086
+ },
1087
+ {
1088
+ "kind": "Field",
1089
+ "name": {
1090
+ "kind": "Name",
1091
+ "value": "dueDate"
1092
+ },
1093
+ "directives": [{
1094
+ "kind": "Directive",
1095
+ "name": {
1096
+ "kind": "Name",
1097
+ "value": "include"
1098
+ },
1099
+ "arguments": [{
1100
+ "kind": "Argument",
1101
+ "name": {
1102
+ "kind": "Name",
1103
+ "value": "if"
1104
+ },
1105
+ "value": {
1106
+ "kind": "Variable",
1107
+ "name": {
1108
+ "kind": "Name",
1109
+ "value": "includeDetails"
1110
+ }
1111
+ }
1112
+ }]
1113
+ }]
1114
+ },
1115
+ {
1116
+ "kind": "Field",
1117
+ "name": {
1118
+ "kind": "Name",
1119
+ "value": "updatedAt"
1120
+ },
1121
+ "directives": [{
1122
+ "kind": "Directive",
1123
+ "name": {
1124
+ "kind": "Name",
1125
+ "value": "include"
1126
+ },
1127
+ "arguments": [{
1128
+ "kind": "Argument",
1129
+ "name": {
1130
+ "kind": "Name",
1131
+ "value": "if"
1132
+ },
1133
+ "value": {
1134
+ "kind": "Variable",
1135
+ "name": {
1136
+ "kind": "Name",
1137
+ "value": "includeDetails"
1138
+ }
1139
+ }
1140
+ }]
1141
+ }]
1142
+ },
1143
+ {
1144
+ "kind": "Field",
1145
+ "name": {
1146
+ "kind": "Name",
1147
+ "value": "submittedAt"
1148
+ },
1149
+ "directives": [{
1150
+ "kind": "Directive",
1151
+ "name": {
1152
+ "kind": "Name",
1153
+ "value": "include"
1154
+ },
1155
+ "arguments": [{
1156
+ "kind": "Argument",
1157
+ "name": {
1158
+ "kind": "Name",
1159
+ "value": "if"
1160
+ },
1161
+ "value": {
1162
+ "kind": "Variable",
1163
+ "name": {
1164
+ "kind": "Name",
1165
+ "value": "includeDetails"
1166
+ }
1167
+ }
1168
+ }]
1169
+ }]
1170
+ },
1171
+ {
1172
+ "kind": "Field",
1173
+ "name": {
1174
+ "kind": "Name",
1175
+ "value": "isArchived"
1176
+ },
1177
+ "directives": [{
1178
+ "kind": "Directive",
1179
+ "name": {
1180
+ "kind": "Name",
1181
+ "value": "include"
1182
+ },
1183
+ "arguments": [{
1184
+ "kind": "Argument",
1185
+ "name": {
1186
+ "kind": "Name",
1187
+ "value": "if"
1188
+ },
1189
+ "value": {
1190
+ "kind": "Variable",
1191
+ "name": {
1192
+ "kind": "Name",
1193
+ "value": "includeDetails"
1194
+ }
1195
+ }
1196
+ }]
1197
+ }]
1198
+ },
1199
+ {
1200
+ "kind": "Field",
1201
+ "name": {
1202
+ "kind": "Name",
1203
+ "value": "isLocked"
1204
+ },
1205
+ "directives": [{
1206
+ "kind": "Directive",
1207
+ "name": {
1208
+ "kind": "Name",
1209
+ "value": "include"
1210
+ },
1211
+ "arguments": [{
1212
+ "kind": "Argument",
1213
+ "name": {
1214
+ "kind": "Name",
1215
+ "value": "if"
1216
+ },
1217
+ "value": {
1218
+ "kind": "Variable",
1219
+ "name": {
1220
+ "kind": "Name",
1221
+ "value": "includeDetails"
1222
+ }
1223
+ }
1224
+ }]
1225
+ }]
1226
+ },
1227
+ {
1228
+ "kind": "Field",
1229
+ "name": {
1230
+ "kind": "Name",
1231
+ "value": "assignees"
1232
+ },
1233
+ "directives": [{
1234
+ "kind": "Directive",
1235
+ "name": {
1236
+ "kind": "Name",
1237
+ "value": "include"
1238
+ },
1239
+ "arguments": [{
1240
+ "kind": "Argument",
1241
+ "name": {
1242
+ "kind": "Name",
1243
+ "value": "if"
1244
+ },
1245
+ "value": {
1246
+ "kind": "Variable",
1247
+ "name": {
1248
+ "kind": "Name",
1249
+ "value": "includeDetails"
1250
+ }
1251
+ }
1252
+ }]
1253
+ }],
1254
+ "selectionSet": {
1255
+ "kind": "SelectionSet",
1256
+ "selections": [
1257
+ {
1258
+ "kind": "Field",
1259
+ "name": {
1260
+ "kind": "Name",
1261
+ "value": "id"
1262
+ }
1263
+ },
1264
+ {
1265
+ "kind": "Field",
1266
+ "name": {
1267
+ "kind": "Name",
1268
+ "value": "name"
1269
+ }
1270
+ },
1271
+ {
1272
+ "kind": "Field",
1273
+ "name": {
1274
+ "kind": "Name",
1275
+ "value": "email"
1276
+ }
1277
+ }
1278
+ ]
1279
+ }
1280
+ },
1281
+ {
1282
+ "kind": "Field",
1283
+ "name": {
1284
+ "kind": "Name",
1285
+ "value": "reviewers"
1286
+ },
1287
+ "directives": [{
1288
+ "kind": "Directive",
1289
+ "name": {
1290
+ "kind": "Name",
1291
+ "value": "include"
1292
+ },
1293
+ "arguments": [{
1294
+ "kind": "Argument",
1295
+ "name": {
1296
+ "kind": "Name",
1297
+ "value": "if"
1298
+ },
1299
+ "value": {
1300
+ "kind": "Variable",
1301
+ "name": {
1302
+ "kind": "Name",
1303
+ "value": "includeDetails"
1304
+ }
1305
+ }
1306
+ }]
1307
+ }],
1308
+ "selectionSet": {
1309
+ "kind": "SelectionSet",
1310
+ "selections": [
1311
+ {
1312
+ "kind": "Field",
1313
+ "name": {
1314
+ "kind": "Name",
1315
+ "value": "id"
1316
+ }
1317
+ },
1318
+ {
1319
+ "kind": "Field",
1320
+ "name": {
1321
+ "kind": "Name",
1322
+ "value": "name"
1323
+ }
1324
+ },
1325
+ {
1326
+ "kind": "Field",
1327
+ "name": {
1328
+ "kind": "Name",
1329
+ "value": "email"
1330
+ }
1331
+ }
1332
+ ]
828
1333
  }
829
1334
  },
830
1335
  {
831
1336
  "kind": "Field",
832
1337
  "name": {
833
1338
  "kind": "Name",
834
- "value": "assessmentGroup"
1339
+ "value": "externalAssignees"
835
1340
  },
1341
+ "directives": [{
1342
+ "kind": "Directive",
1343
+ "name": {
1344
+ "kind": "Name",
1345
+ "value": "include"
1346
+ },
1347
+ "arguments": [{
1348
+ "kind": "Argument",
1349
+ "name": {
1350
+ "kind": "Name",
1351
+ "value": "if"
1352
+ },
1353
+ "value": {
1354
+ "kind": "Variable",
1355
+ "name": {
1356
+ "kind": "Name",
1357
+ "value": "includeDetails"
1358
+ }
1359
+ }
1360
+ }]
1361
+ }],
836
1362
  "selectionSet": {
837
1363
  "kind": "SelectionSet",
838
1364
  "selections": [{
@@ -841,6 +1367,12 @@ const documents = {
841
1367
  "kind": "Name",
842
1368
  "value": "id"
843
1369
  }
1370
+ }, {
1371
+ "kind": "Field",
1372
+ "name": {
1373
+ "kind": "Name",
1374
+ "value": "email"
1375
+ }
844
1376
  }]
845
1377
  }
846
1378
  }
@@ -1376,7 +1908,7 @@ const documents = {
1376
1908
  }
1377
1909
  }]
1378
1910
  },
1379
- "\n query AssessmentsListGroups($first: Int) {\n assessmentGroups(first: $first) {\n nodes {\n id\n title\n assessmentFormTemplate {\n id\n title\n }\n }\n totalCount\n }\n }\n": {
1911
+ "\n query AssessmentsListGroups($first: Int, $offset: Int, $filterBy: AssessmentGroupFiltersInput) {\n assessmentGroups(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n title\n description\n assessmentFormTemplate {\n id\n title\n }\n }\n totalCount\n }\n }\n": {
1380
1912
  "kind": "Document",
1381
1913
  "definitions": [{
1382
1914
  "kind": "OperationDefinition",
@@ -1385,23 +1917,59 @@ const documents = {
1385
1917
  "kind": "Name",
1386
1918
  "value": "AssessmentsListGroups"
1387
1919
  },
1388
- "variableDefinitions": [{
1389
- "kind": "VariableDefinition",
1390
- "variable": {
1391
- "kind": "Variable",
1392
- "name": {
1393
- "kind": "Name",
1394
- "value": "first"
1920
+ "variableDefinitions": [
1921
+ {
1922
+ "kind": "VariableDefinition",
1923
+ "variable": {
1924
+ "kind": "Variable",
1925
+ "name": {
1926
+ "kind": "Name",
1927
+ "value": "first"
1928
+ }
1929
+ },
1930
+ "type": {
1931
+ "kind": "NamedType",
1932
+ "name": {
1933
+ "kind": "Name",
1934
+ "value": "Int"
1935
+ }
1395
1936
  }
1396
1937
  },
1397
- "type": {
1398
- "kind": "NamedType",
1399
- "name": {
1400
- "kind": "Name",
1401
- "value": "Int"
1938
+ {
1939
+ "kind": "VariableDefinition",
1940
+ "variable": {
1941
+ "kind": "Variable",
1942
+ "name": {
1943
+ "kind": "Name",
1944
+ "value": "offset"
1945
+ }
1946
+ },
1947
+ "type": {
1948
+ "kind": "NamedType",
1949
+ "name": {
1950
+ "kind": "Name",
1951
+ "value": "Int"
1952
+ }
1953
+ }
1954
+ },
1955
+ {
1956
+ "kind": "VariableDefinition",
1957
+ "variable": {
1958
+ "kind": "Variable",
1959
+ "name": {
1960
+ "kind": "Name",
1961
+ "value": "filterBy"
1962
+ }
1963
+ },
1964
+ "type": {
1965
+ "kind": "NamedType",
1966
+ "name": {
1967
+ "kind": "Name",
1968
+ "value": "AssessmentGroupFiltersInput"
1969
+ }
1402
1970
  }
1403
1971
  }
1404
- }],
1972
+ ],
1405
1973
  "selectionSet": {
1406
1974
  "kind": "SelectionSet",
1407
1975
  "selections": [{
@@ -1410,20 +1978,50 @@ const documents = {
1410
1978
  "kind": "Name",
1411
1979
  "value": "assessmentGroups"
1412
1980
  },
1413
- "arguments": [{
1414
- "kind": "Argument",
1415
- "name": {
1416
- "kind": "Name",
1417
- "value": "first"
1418
- },
1419
- "value": {
1420
- "kind": "Variable",
1981
+ "arguments": [
1982
+ {
1983
+ "kind": "Argument",
1421
1984
  "name": {
1422
1985
  "kind": "Name",
1423
1986
  "value": "first"
1987
+ },
1988
+ "value": {
1989
+ "kind": "Variable",
1990
+ "name": {
1991
+ "kind": "Name",
1992
+ "value": "first"
1993
+ }
1994
+ }
1995
+ },
1996
+ {
1997
+ "kind": "Argument",
1998
+ "name": {
1999
+ "kind": "Name",
2000
+ "value": "offset"
2001
+ },
2002
+ "value": {
2003
+ "kind": "Variable",
2004
+ "name": {
2005
+ "kind": "Name",
2006
+ "value": "offset"
2007
+ }
2008
+ }
2009
+ },
2010
+ {
2011
+ "kind": "Argument",
2012
+ "name": {
2013
+ "kind": "Name",
2014
+ "value": "filterBy"
2015
+ },
2016
+ "value": {
2017
+ "kind": "Variable",
2018
+ "name": {
2019
+ "kind": "Name",
2020
+ "value": "filterBy"
2021
+ }
1424
2022
  }
1425
2023
  }
1426
- }],
2024
+ ],
1427
2025
  "selectionSet": {
1428
2026
  "kind": "SelectionSet",
1429
2027
  "selections": [{
@@ -1449,6 +2047,13 @@ const documents = {
1449
2047
  "value": "title"
1450
2048
  }
1451
2049
  },
2050
+ {
2051
+ "kind": "Field",
2052
+ "name": {
2053
+ "kind": "Name",
2054
+ "value": "description"
2055
+ }
2056
+ },
1452
2057
  {
1453
2058
  "kind": "Field",
1454
2059
  "name": {
@@ -1794,7 +2399,7 @@ const documents = {
1794
2399
  }
1795
2400
  }]
1796
2401
  },
1797
- "\n query AssessmentsListTemplates($first: Int) {\n assessmentFormTemplates(first: $first) {\n nodes {\n id\n title\n description\n }\n totalCount\n }\n }\n": {
2402
+ "\n query AssessmentsListTemplates(\n $first: Int\n $offset: Int\n $filterBy: AssessmentFormTemplateFiltersInput\n ) {\n assessmentFormTemplates(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n title\n description\n status\n source\n isArchived\n createdAt\n updatedAt\n }\n totalCount\n }\n }\n": {
1798
2403
  "kind": "Document",
1799
2404
  "definitions": [{
1800
2405
  "kind": "OperationDefinition",
@@ -1803,23 +2408,59 @@ const documents = {
1803
2408
  "kind": "Name",
1804
2409
  "value": "AssessmentsListTemplates"
1805
2410
  },
1806
- "variableDefinitions": [{
1807
- "kind": "VariableDefinition",
1808
- "variable": {
1809
- "kind": "Variable",
1810
- "name": {
1811
- "kind": "Name",
1812
- "value": "first"
2411
+ "variableDefinitions": [
2412
+ {
2413
+ "kind": "VariableDefinition",
2414
+ "variable": {
2415
+ "kind": "Variable",
2416
+ "name": {
2417
+ "kind": "Name",
2418
+ "value": "first"
2419
+ }
2420
+ },
2421
+ "type": {
2422
+ "kind": "NamedType",
2423
+ "name": {
2424
+ "kind": "Name",
2425
+ "value": "Int"
2426
+ }
1813
2427
  }
1814
2428
  },
1815
- "type": {
1816
- "kind": "NamedType",
1817
- "name": {
1818
- "kind": "Name",
1819
- "value": "Int"
2429
+ {
2430
+ "kind": "VariableDefinition",
2431
+ "variable": {
2432
+ "kind": "Variable",
2433
+ "name": {
2434
+ "kind": "Name",
2435
+ "value": "offset"
2436
+ }
2437
+ },
2438
+ "type": {
2439
+ "kind": "NamedType",
2440
+ "name": {
2441
+ "kind": "Name",
2442
+ "value": "Int"
2443
+ }
2444
+ }
2445
+ },
2446
+ {
2447
+ "kind": "VariableDefinition",
2448
+ "variable": {
2449
+ "kind": "Variable",
2450
+ "name": {
2451
+ "kind": "Name",
2452
+ "value": "filterBy"
2453
+ }
2454
+ },
2455
+ "type": {
2456
+ "kind": "NamedType",
2457
+ "name": {
2458
+ "kind": "Name",
2459
+ "value": "AssessmentFormTemplateFiltersInput"
2460
+ }
1820
2461
  }
1821
2462
  }
1822
- }],
2463
+ ],
1823
2464
  "selectionSet": {
1824
2465
  "kind": "SelectionSet",
1825
2466
  "selections": [{
@@ -1828,20 +2469,50 @@ const documents = {
1828
2469
  "kind": "Name",
1829
2470
  "value": "assessmentFormTemplates"
1830
2471
  },
1831
- "arguments": [{
1832
- "kind": "Argument",
1833
- "name": {
1834
- "kind": "Name",
1835
- "value": "first"
1836
- },
1837
- "value": {
1838
- "kind": "Variable",
2472
+ "arguments": [
2473
+ {
2474
+ "kind": "Argument",
1839
2475
  "name": {
1840
2476
  "kind": "Name",
1841
2477
  "value": "first"
2478
+ },
2479
+ "value": {
2480
+ "kind": "Variable",
2481
+ "name": {
2482
+ "kind": "Name",
2483
+ "value": "first"
2484
+ }
2485
+ }
2486
+ },
2487
+ {
2488
+ "kind": "Argument",
2489
+ "name": {
2490
+ "kind": "Name",
2491
+ "value": "offset"
2492
+ },
2493
+ "value": {
2494
+ "kind": "Variable",
2495
+ "name": {
2496
+ "kind": "Name",
2497
+ "value": "offset"
2498
+ }
2499
+ }
2500
+ },
2501
+ {
2502
+ "kind": "Argument",
2503
+ "name": {
2504
+ "kind": "Name",
2505
+ "value": "filterBy"
2506
+ },
2507
+ "value": {
2508
+ "kind": "Variable",
2509
+ "name": {
2510
+ "kind": "Name",
2511
+ "value": "filterBy"
2512
+ }
1842
2513
  }
1843
2514
  }
1844
- }],
2515
+ ],
1845
2516
  "selectionSet": {
1846
2517
  "kind": "SelectionSet",
1847
2518
  "selections": [{
@@ -1873,6 +2544,41 @@ const documents = {
1873
2544
  "kind": "Name",
1874
2545
  "value": "description"
1875
2546
  }
2547
+ },
2548
+ {
2549
+ "kind": "Field",
2550
+ "name": {
2551
+ "kind": "Name",
2552
+ "value": "status"
2553
+ }
2554
+ },
2555
+ {
2556
+ "kind": "Field",
2557
+ "name": {
2558
+ "kind": "Name",
2559
+ "value": "source"
2560
+ }
2561
+ },
2562
+ {
2563
+ "kind": "Field",
2564
+ "name": {
2565
+ "kind": "Name",
2566
+ "value": "isArchived"
2567
+ }
2568
+ },
2569
+ {
2570
+ "kind": "Field",
2571
+ "name": {
2572
+ "kind": "Name",
2573
+ "value": "createdAt"
2574
+ }
2575
+ },
2576
+ {
2577
+ "kind": "Field",
2578
+ "name": {
2579
+ "kind": "Name",
2580
+ "value": "updatedAt"
2581
+ }
1876
2582
  }
1877
2583
  ]
1878
2584
  }
@@ -2726,9 +3432,24 @@ function normalizeQuestion(q) {
2726
3432
  ...q.displayLogic && { displayLogic: q.displayLogic }
2727
3433
  };
2728
3434
  }
3435
+ /**
3436
+ * Assessment index. `AssessmentFormsPayload` exposes `totalCount` but no
3437
+ * `pageInfo`, so paging is offset-based and `hasNextPage` has to be derived
3438
+ * from `offset + nodes.length < totalCount`.
3439
+ *
3440
+ * The people, dates and lock state behind `@include(if: $includeDetails)`
3441
+ * roughly triple the bytes per row, so a caller who only wants titles and
3442
+ * statuses does not pay for them.
3443
+ */
2729
3444
  const ListAssessmentsDoc = graphql(`
2730
- query AssessmentsList($first: Int, $filterBy: AssessmentFormFiltersInput) {
2731
- assessmentForms(first: $first, filterBy: $filterBy) {
3445
+ query AssessmentsList(
3446
+ $first: Int
3447
+ $offset: Int
3448
+ $filterBy: AssessmentFormFiltersInput
3449
+ $orderBy: [AssessmentFormRawOrder!]
3450
+ $includeDetails: Boolean!
3451
+ ) {
3452
+ assessmentForms(first: $first, offset: $offset, filterBy: $filterBy, orderBy: $orderBy) {
2732
3453
  nodes {
2733
3454
  id
2734
3455
  title
@@ -2736,6 +3457,26 @@ const ListAssessmentsDoc = graphql(`
2736
3457
  createdAt
2737
3458
  assessmentGroup {
2738
3459
  id
3460
+ title
3461
+ }
3462
+ dueDate @include(if: $includeDetails)
3463
+ updatedAt @include(if: $includeDetails)
3464
+ submittedAt @include(if: $includeDetails)
3465
+ isArchived @include(if: $includeDetails)
3466
+ isLocked @include(if: $includeDetails)
3467
+ assignees @include(if: $includeDetails) {
3468
+ id
3469
+ name
3470
+ email
3471
+ }
3472
+ reviewers @include(if: $includeDetails) {
3473
+ id
3474
+ name
3475
+ email
3476
+ }
3477
+ externalAssignees @include(if: $includeDetails) {
3478
+ id
3479
+ email
2739
3480
  }
2740
3481
  }
2741
3482
  totalCount
@@ -2809,11 +3550,12 @@ const UpdateAssessmentFormAssigneesDoc = graphql(`
2809
3550
  }
2810
3551
  `);
2811
3552
  const ListAssessmentGroupsDoc = graphql(`
2812
- query AssessmentsListGroups($first: Int) {
2813
- assessmentGroups(first: $first) {
3553
+ query AssessmentsListGroups($first: Int, $offset: Int, $filterBy: AssessmentGroupFiltersInput) {
3554
+ assessmentGroups(first: $first, offset: $offset, filterBy: $filterBy) {
2814
3555
  nodes {
2815
3556
  id
2816
3557
  title
3558
+ description
2817
3559
  assessmentFormTemplate {
2818
3560
  id
2819
3561
  title
@@ -2863,12 +3605,21 @@ const UpdateAssessmentFormDoc = graphql(`
2863
3605
  }
2864
3606
  `);
2865
3607
  const ListAssessmentTemplatesDoc = graphql(`
2866
- query AssessmentsListTemplates($first: Int) {
2867
- assessmentFormTemplates(first: $first) {
3608
+ query AssessmentsListTemplates(
3609
+ $first: Int
3610
+ $offset: Int
3611
+ $filterBy: AssessmentFormTemplateFiltersInput
3612
+ ) {
3613
+ assessmentFormTemplates(first: $first, offset: $offset, filterBy: $filterBy) {
2868
3614
  nodes {
2869
3615
  id
2870
3616
  title
2871
3617
  description
3618
+ status
3619
+ source
3620
+ isArchived
3621
+ createdAt
3622
+ updatedAt
2872
3623
  }
2873
3624
  totalCount
2874
3625
  }
@@ -2977,24 +3728,64 @@ const GetAssessmentFormTemplateDoc = graphql(`
2977
3728
  }
2978
3729
  `);
2979
3730
  var AssessmentsMixin = class extends TranscendGraphQLBase {
3731
+ /**
3732
+ * Page the assessment index. `first`/`offset` map straight onto the query;
3733
+ * `hasNextPage` is derived because the payload carries no `pageInfo`.
3734
+ *
3735
+ * `includeDetails` gates the assignee, reviewer, date and lock fields so the
3736
+ * cheap listing stays cheap.
3737
+ */
2980
3738
  async listAssessments(options) {
2981
- const data = await this.makeRequest(ListAssessmentsDoc, {
2982
- first: Math.min(options?.first ?? 50, 100),
2983
- filterBy: options?.filterBy?.statuses ? { statuses: options.filterBy.statuses } : null
2984
- });
3739
+ const first = Math.min(options?.first ?? 50, 100);
3740
+ const offset = options?.offset ?? 0;
3741
+ const filterBy = options?.filterBy;
3742
+ const includeDetails = options?.includeDetails ?? false;
3743
+ const { nodes, totalCount } = (await this.makeRequest(ListAssessmentsDoc, {
3744
+ first,
3745
+ offset,
3746
+ includeDetails,
3747
+ filterBy: filterBy && Object.keys(filterBy).length > 0 ? filterBy : null,
3748
+ orderBy: options?.sortField ? [{
3749
+ field: options.sortField,
3750
+ direction: options.sortDirection ?? "ASC"
3751
+ }] : null
3752
+ })).assessmentForms;
2985
3753
  return {
2986
- nodes: data.assessmentForms.nodes.map((node) => ({
3754
+ nodes: nodes.map((node) => ({
2987
3755
  id: node.id,
2988
3756
  title: node.title,
2989
3757
  status: node.status,
2990
3758
  createdAt: node.createdAt,
2991
- assessmentGroupId: node.assessmentGroup?.id
3759
+ assessmentGroupId: node.assessmentGroup?.id,
3760
+ assessmentGroupTitle: node.assessmentGroup?.title,
3761
+ ...includeDetails && {
3762
+ dueDate: node.dueDate ?? null,
3763
+ updatedAt: node.updatedAt ?? void 0,
3764
+ submittedAt: node.submittedAt ?? void 0,
3765
+ isArchived: node.isArchived,
3766
+ isLocked: node.isLocked,
3767
+ assignees: node.assignees?.map((user) => ({
3768
+ id: user.id,
3769
+ name: user.name,
3770
+ email: user.email
3771
+ })),
3772
+ reviewers: node.reviewers?.map((user) => ({
3773
+ id: user.id,
3774
+ name: user.name,
3775
+ email: user.email
3776
+ })),
3777
+ externalAssignees: node.externalAssignees?.map((assignee) => ({
3778
+ id: assignee.id,
3779
+ email: assignee.email
3780
+ }))
3781
+ }
2992
3782
  })),
2993
- pageInfo: {
2994
- hasNextPage: data.assessmentForms.nodes.length < data.assessmentForms.totalCount,
2995
- hasPreviousPage: false
2996
- },
2997
- totalCount: data.assessmentForms.totalCount
3783
+ pageInfo: derivePageInfo({
3784
+ offset,
3785
+ nodeCount: nodes.length,
3786
+ totalCount
3787
+ }),
3788
+ totalCount
2998
3789
  };
2999
3790
  }
3000
3791
  async getAssessment(id) {
@@ -3043,22 +3834,35 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
3043
3834
  async updateAssessmentFormAssignees(input) {
3044
3835
  return (await this.makeRequest(UpdateAssessmentFormAssigneesDoc, { input })).updateAssessmentFormAssignees.assessmentForm;
3045
3836
  }
3837
+ /**
3838
+ * Page the group index. Like `assessmentForms`, `AssessmentGroupsPayload`
3839
+ * carries no `pageInfo`, so `hasNextPage` is derived from the offset.
3840
+ */
3046
3841
  async listAssessmentGroups(options) {
3047
- const data = await this.makeRequest(ListAssessmentGroupsDoc, { first: Math.min(options?.first ?? 50, 100) });
3842
+ const first = Math.min(options?.first ?? 50, 100);
3843
+ const offset = options?.offset ?? 0;
3844
+ const filterBy = options?.filterBy;
3845
+ const { nodes, totalCount } = (await this.makeRequest(ListAssessmentGroupsDoc, {
3846
+ first,
3847
+ offset,
3848
+ filterBy: filterBy && Object.keys(filterBy).length > 0 ? filterBy : null
3849
+ })).assessmentGroups;
3048
3850
  return {
3049
- nodes: data.assessmentGroups.nodes.map((node) => ({
3851
+ nodes: nodes.map((node) => ({
3050
3852
  id: node.id,
3051
3853
  title: node.title,
3854
+ description: node.description,
3052
3855
  assessmentFormTemplate: node.assessmentFormTemplate ? {
3053
3856
  id: node.assessmentFormTemplate.id,
3054
3857
  title: node.assessmentFormTemplate.title
3055
3858
  } : void 0
3056
3859
  })),
3057
- pageInfo: {
3058
- hasNextPage: data.assessmentGroups.nodes.length < data.assessmentGroups.totalCount,
3059
- hasPreviousPage: false
3060
- },
3061
- totalCount: data.assessmentGroups.totalCount
3860
+ pageInfo: derivePageInfo({
3861
+ offset,
3862
+ nodeCount: nodes.length,
3863
+ totalCount
3864
+ }),
3865
+ totalCount
3062
3866
  };
3063
3867
  }
3064
3868
  async createAssessmentGroup(input) {
@@ -3093,22 +3897,36 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
3093
3897
  assessmentGroupId: form.assessmentGroup?.id
3094
3898
  };
3095
3899
  }
3900
+ /**
3901
+ * Page the template index. Same derived `hasNextPage` as the other assessment
3902
+ * lists, since `AssessmentFormTemplatesPayload` carries no `pageInfo`.
3903
+ */
3096
3904
  async listAssessmentTemplates(options) {
3097
- const data = await this.makeRequest(ListAssessmentTemplatesDoc, { first: Math.min(options?.first ?? 50, 100) });
3905
+ const first = Math.min(options?.first ?? 50, 100);
3906
+ const offset = options?.offset ?? 0;
3907
+ const filterBy = options?.filterBy;
3908
+ const { nodes, totalCount } = (await this.makeRequest(ListAssessmentTemplatesDoc, {
3909
+ first,
3910
+ offset,
3911
+ filterBy: filterBy && Object.keys(filterBy).length > 0 ? filterBy : null
3912
+ })).assessmentFormTemplates;
3098
3913
  return {
3099
- nodes: data.assessmentFormTemplates.nodes.map((t) => ({
3914
+ nodes: nodes.map((t) => ({
3100
3915
  id: t.id,
3101
3916
  title: t.title,
3102
3917
  description: t.description ?? void 0,
3103
- version: "1.0.0",
3104
- isActive: true,
3105
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
3918
+ status: t.status,
3919
+ source: t.source,
3920
+ isArchived: t.isArchived,
3921
+ createdAt: t.createdAt,
3922
+ updatedAt: t.updatedAt
3106
3923
  })),
3107
- pageInfo: {
3108
- hasNextPage: data.assessmentFormTemplates.nodes.length < data.assessmentFormTemplates.totalCount,
3109
- hasPreviousPage: false
3110
- },
3111
- totalCount: data.assessmentFormTemplates.totalCount
3924
+ pageInfo: derivePageInfo({
3925
+ offset,
3926
+ nodeCount: nodes.length,
3927
+ totalCount
3928
+ }),
3929
+ totalCount
3112
3930
  };
3113
3931
  }
3114
3932
  async submitAssessmentForReview(input) {
@@ -3192,4 +4010,4 @@ var AssessmentsMixin = class extends TranscendGraphQLBase {
3192
4010
  //#endregion
3193
4011
  export { buildAssessmentGroupUrl as _, UpdateAssessmentSchema as a, AnswerQuestionValueSchema as b, ListTemplatesSchema as c, ListAssessmentsSchema as d, GetAssessmentSchema as f, CreateAssessmentSchema as g, CreateGroupSchema as h, UpdateAssigneesSchema as i, ListGroupsSchema as l, CreateTemplateSchema as m, ASSESSMENT_OAUTH_SCOPES as n, SubmitResponseSchema as o, ExportTemplateSchema as p, getAssessmentTools as r, PrefillSchema as s, AssessmentsMixin as t, AssessmentStatusEnum as u, buildAssessmentLinks as v, AddSectionSchema as x, AnswerQuestionSchema as y };
3194
4012
 
3195
- //# sourceMappingURL=graphql-1BG4iWhF.mjs.map
4013
+ //# sourceMappingURL=graphql-D1ksNLBL.mjs.map