From b0a942b6fc58b5d5b8d1dd8b235c0134e84b04de Mon Sep 17 00:00:00 2001 From: Gil Gardosh Date: Wed, 22 Jul 2026 16:39:22 +0300 Subject: [PATCH 1/2] Defer `missingInfoSuggestions` --- .../src/components/charges/charges-table.tsx | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/packages/client/src/components/charges/charges-table.tsx b/packages/client/src/components/charges/charges-table.tsx index 28de1577b..4d6a73e63 100644 --- a/packages/client/src/components/charges/charges-table.tsx +++ b/packages/client/src/components/charges/charges-table.tsx @@ -16,6 +16,7 @@ import { import { AccountantStatus, ChargeForChargesTableFieldsFragmentDoc, + ChargesTableSuggestionsFieldsFragmentDoc, MissingChargeInfo, type ChargeForChargesTableFieldsFragment, } from '../../gql/graphql.js'; @@ -37,6 +38,21 @@ import { columns } from './columns.js'; import { DownloadChargesCsv } from './download-charges-csv.js'; import { shouldHaveCounterparty, shouldHaveTaxCategory, shouldHaveVat } from './utils.js'; +// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen +/* GraphQL */ ` + fragment ChargesTableSuggestionsFields on Charge { + id + missingInfoSuggestions { + description + tags { + id + name + namePath + } + } + } +`; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen /* GraphQL */ ` fragment ChargeForChargesTableFields on Charge { @@ -93,16 +109,7 @@ import { shouldHaveCounterparty, shouldHaveTaxCategory, shouldHaveVat } from './ missingInfo } } - ... on Charge { - missingInfoSuggestions { - description - tags { - id - name - namePath - } - } - } + ...ChargesTableSuggestionsFields @defer } `; @@ -125,6 +132,14 @@ export interface ChargeRow { export function convertChargeFragmentToTableRow( fragmentData: ChargeForChargesTableFieldsFragment, ): ChargeRow { + // The suggestions fragment is deferred — its fields are absent from the + // payload until the patch arrives, so unwrap defensively. + const missingInfoSuggestions = getFragmentData( + ChargesTableSuggestionsFieldsFragmentDoc, + // each charge subtype carries its own variant ref, which the overloads + // can't distribute over — the runtime is an identity unwrap either way + fragmentData as FragmentType, + )?.missingInfoSuggestions; return { id: fragmentData.id, onChange: () => {}, @@ -174,7 +189,7 @@ export function convertChargeFragmentToTableRow( chargeId: fragmentData.id, value: fragmentData.userDescription?.trim() ?? undefined, isMissing: fragmentData.validationData?.missingInfo.includes(MissingChargeInfo.Description), - suggestedDescription: fragmentData.missingInfoSuggestions?.description?.trim() ?? undefined, + suggestedDescription: missingInfoSuggestions?.description?.trim() ?? undefined, }, tags: { chargeId: fragmentData.id, @@ -184,7 +199,7 @@ export function convertChargeFragmentToTableRow( namePath: tag.namePath ?? undefined, })), suggestedTags: - fragmentData.missingInfoSuggestions?.tags.map(tag => ({ + missingInfoSuggestions?.tags.map(tag => ({ id: tag.id, name: tag.name, namePath: tag.namePath ?? undefined, From 17a854373395661d2c3199432fd9237c66e8f6e8 Mon Sep 17 00:00:00 2001 From: Gil Gardosh Date: Wed, 22 Jul 2026 17:39:31 +0300 Subject: [PATCH 2/2] changeset --- .changeset/dark-parrots-tell.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/dark-parrots-tell.md diff --git a/.changeset/dark-parrots-tell.md b/.changeset/dark-parrots-tell.md new file mode 100644 index 000000000..d392072af --- /dev/null +++ b/.changeset/dark-parrots-tell.md @@ -0,0 +1,8 @@ +--- +'@accounter/client': patch +--- + +- Extracted `missingInfoSuggestions` into a dedicated `ChargesTableSuggestionsFields` fragment. +- Applied `@defer` to the suggestions fragment spread inside `ChargeForChargesTableFields`. +- Updated `convertChargeFragmentToTableRow` to read suggestions via `getFragmentData` and handle the + deferred (initially-absent) fields safely.