Skip to content

Commit a0bb9b4

Browse files
authored
Cleans up and collocates versions and features (#3640)
* cleans up and collocates versions and features * adds qa suggestions
1 parent ff46fdf commit a0bb9b4

File tree

13 files changed

+94
-72
lines changed

13 files changed

+94
-72
lines changed

src/features/applicationMetadata/ApplicationMetadataProvider.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import type { UseQueryOptions } from '@tanstack/react-query';
77
import { delayedContext } from 'src/core/contexts/delayedContext';
88
import { createQueryContext } from 'src/core/contexts/queryContext';
99
import { onEntryValuesThatHaveState } from 'src/features/applicationMetadata/appMetadataUtils';
10-
import { MINIMUM_APPLICATION_VERSION } from 'src/features/applicationMetadata/minVersion';
1110
import { VersionErrorOrChildren } from 'src/features/applicationMetadata/VersionErrorOrChildren';
1211
import { useNavigationParam } from 'src/hooks/navigation';
1312
import { fetchApplicationMetadata } from 'src/queries/queries';
14-
import { isAtLeastVersion } from 'src/utils/versionCompare';
13+
import { isMinimumApplicationVersion } from 'src/utils/versioning/versions';
1514
import type { ApplicationMetadata, IncomingApplicationMetadata } from 'src/features/applicationMetadata/types';
1615

1716
// Also used for prefetching @see appPrefetcher.ts
@@ -24,12 +23,7 @@ export function getApplicationMetadataQueryDef(instanceGuid: string | undefined)
2423

2524
return {
2625
...data,
27-
isValidVersion:
28-
!!data.altinnNugetVersion &&
29-
isAtLeastVersion({
30-
actualVersion: data.altinnNugetVersion,
31-
minimumVersion: MINIMUM_APPLICATION_VERSION.build,
32-
}),
26+
isValidVersion: isMinimumApplicationVersion(data.altinnNugetVersion),
3327
onEntry,
3428
isStatelessApp: isStatelessApp(!!instanceGuid, onEntry.show),
3529
logoOptions: data.logo,

src/features/applicationMetadata/VersionErrorOrChildren.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React from 'react';
22
import type { PropsWithChildren } from 'react';
33

44
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
5-
import { MINIMUM_APPLICATION_VERSION } from 'src/features/applicationMetadata/minVersion';
65
import { InstantiationErrorPage } from 'src/features/instantiate/containers/InstantiationErrorPage';
76
import { Lang } from 'src/features/language/Lang';
7+
import { MINIMUM_APPLICATION_VERSION_NAME } from 'src/utils/versioning/versions';
88

99
export function VersionErrorOrChildren({ children }: PropsWithChildren) {
1010
const { isValidVersion } = useApplicationMetadata();
@@ -21,7 +21,7 @@ export function VersionErrorOrChildren({ children }: PropsWithChildren) {
2121
<br />
2222
<Lang
2323
id='version_error.min_backend_version'
24-
params={[MINIMUM_APPLICATION_VERSION.name]}
24+
params={[MINIMUM_APPLICATION_VERSION_NAME]}
2525
/>
2626
</>
2727
}

src/features/applicationMetadata/minVersion.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/features/attachments/AttachmentsStorePlugin.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { ContextNotProvided } from 'src/core/contexts/context';
1111
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
1212
import { isAttachmentUploaded, isDataPostError } from 'src/features/attachments/index';
1313
import { sortAttachmentsByName } from 'src/features/attachments/sortAttachments';
14-
import { appSupportsNewAttachmentAPI, attachmentSelector } from 'src/features/attachments/tools';
14+
import { attachmentSelector } from 'src/features/attachments/tools';
1515
import { FileScanResults } from 'src/features/attachments/types';
1616
import { FD } from 'src/features/formData/FormDataWrite';
1717
import { dataModelPairsToObject } from 'src/features/formData/types';
@@ -28,6 +28,7 @@ import { useWaitForState } from 'src/hooks/useWaitForState';
2828
import { nodesProduce } from 'src/utils/layout/NodesContext';
2929
import { NodeDataPlugin } from 'src/utils/layout/plugins/NodeDataPlugin';
3030
import { splitDashedKey } from 'src/utils/splitDashedKey';
31+
import { appSupportsNewAttachmentAPI } from 'src/utils/versioning/versions';
3132
import type {
3233
DataPostResponse,
3334
IAttachment,
@@ -296,7 +297,7 @@ export class AttachmentsStorePlugin extends NodeDataPlugin<AttachmentsStorePlugi
296297
const { mutateAsync: uploadAttachment } = useAttachmentsUploadMutation();
297298

298299
const applicationMetadata = useApplicationMetadata();
299-
const supportsNewAttachmentAPI = appSupportsNewAttachmentAPI(applicationMetadata);
300+
const supportsNewAttachmentAPI = appSupportsNewAttachmentAPI(applicationMetadata.altinnNugetVersion);
300301

301302
const setAttachmentsInDataModel = useSetAttachmentInDataModel();
302303
const lock = FD.useLocking('__attachment__upload__');

src/features/attachments/tools.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { sortAttachmentsByName } from 'src/features/attachments/sortAttachments';
2-
import { isAtLeastVersion } from 'src/utils/versionCompare';
3-
import type { ApplicationMetadata } from 'src/features/applicationMetadata/types';
42
import type { IAttachment } from 'src/features/attachments/index';
53
import type { NodesContext } from 'src/utils/layout/NodesContext';
64

@@ -17,7 +15,3 @@ export const attachmentSelector = (nodeId: string) => (state: NodesContext) => {
1715
}
1816
return emptyArray;
1917
};
20-
21-
export function appSupportsNewAttachmentAPI({ altinnNugetVersion }: ApplicationMetadata) {
22-
return !altinnNugetVersion || isAtLeastVersion({ actualVersion: altinnNugetVersion, minimumVersion: '8.5.0.153' });
23-
}

src/features/instance/useProcessNext.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ import { useOptimisticallyUpdateProcess, useProcessQuery } from 'src/features/in
1212
import { Lang } from 'src/features/language/Lang';
1313
import { useCurrentLanguage } from 'src/features/language/LanguageProvider';
1414
import { useUpdateInitialValidations } from 'src/features/validation/backendValidation/backendValidationQuery';
15-
import { appSupportsIncrementalValidationFeatures } from 'src/features/validation/backendValidation/backendValidationUtils';
1615
import { useOnFormSubmitValidation } from 'src/features/validation/callbacks/onFormSubmitValidation';
1716
import { Validation } from 'src/features/validation/validationContext';
1817
import { TaskKeys, useNavigateToTask } from 'src/hooks/useNavigatePage';
1918
import { doProcessNext } from 'src/queries/queries';
20-
import { isAtLeastVersion } from 'src/utils/versionCompare';
21-
import type { ApplicationMetadata } from 'src/features/applicationMetadata/types';
19+
import {
20+
appSupportsIncrementalValidationFeatures,
21+
appSupportsUnlockingOnProcessNextFailure,
22+
} from 'src/utils/versioning/versions';
2223
import type { BackendValidationIssue } from 'src/features/validation';
2324
import type { IActionType, IProcess, ProblemDetails } from 'src/types/shared';
2425
import type { HttpClientError } from 'src/utils/network/sharedNetworking';
@@ -44,12 +45,15 @@ export function useProcessNext({ action }: ProcessNextProps = {}) {
4445
const updateInitialValidations = useUpdateInitialValidations();
4546
const setShowAllBackendErrors = Validation.useSetShowAllBackendErrors();
4647
const onSubmitFormValidation = useOnFormSubmitValidation();
47-
const applicationMetadata = useApplicationMetadata();
4848
const queryClient = useQueryClient();
4949
const displayError = useDisplayError();
5050
const hasPendingScans = useHasPendingScans();
5151
const optimisticallyUpdateProcess = useOptimisticallyUpdateProcess();
5252

53+
const altinnNugetVersion = useApplicationMetadata().altinnNugetVersion;
54+
const isUnlockingOnProcessNextSupported = appSupportsUnlockingOnProcessNextFailure(altinnNugetVersion);
55+
const isIncrementalValidationSupported = appSupportsIncrementalValidationFeatures(altinnNugetVersion);
56+
5357
return useMutation({
5458
scope: { id: 'process/next' },
5559
mutationKey: getProcessNextMutationKey(action),
@@ -76,7 +80,7 @@ export function useProcessNext({ action }: ProcessNextProps = {}) {
7680
} else if (
7781
error.response?.status === 500 &&
7882
error.response?.data?.['detail'] === 'Pdf generation failed' &&
79-
appSupportsUnlockingOnProcessNextFailure(applicationMetadata)
83+
isUnlockingOnProcessNextSupported
8084
) {
8185
// If process next fails due to the PDF generator failing, don't show unknown error if the app unlocks data elements
8286
toast(<Lang id='process_error.submit_error_please_retry' />, { type: 'error', autoClose: false });
@@ -100,7 +104,7 @@ export function useProcessNext({ action }: ProcessNextProps = {}) {
100104
navigateToTask(task);
101105
} else if (validationIssues) {
102106
// Set initial validation to validation issues from process/next and make all errors visible
103-
updateInitialValidations(validationIssues, !appSupportsIncrementalValidationFeatures(applicationMetadata));
107+
updateInitialValidations(validationIssues, !isIncrementalValidationSupported);
104108

105109
const hasValidationErrors = await onSubmitFormValidation(true);
106110
if (!hasValidationErrors) {
@@ -111,7 +115,7 @@ export function useProcessNext({ action }: ProcessNextProps = {}) {
111115
onError: async (error: HttpClientError<ProblemDetails | undefined>) => {
112116
window.logError('Process next failed:\n', error);
113117

114-
if (!appSupportsUnlockingOnProcessNextFailure(applicationMetadata)) {
118+
if (!isUnlockingOnProcessNextSupported) {
115119
displayError(error);
116120
return;
117121
}
@@ -132,10 +136,6 @@ export function useProcessNext({ action }: ProcessNextProps = {}) {
132136
});
133137
}
134138

135-
function appSupportsUnlockingOnProcessNextFailure({ altinnNugetVersion }: ApplicationMetadata) {
136-
return !altinnNugetVersion || isAtLeastVersion({ actualVersion: altinnNugetVersion, minimumVersion: '8.1.0.115' });
137-
}
138-
139139
export function getTargetTaskFromProcess(processData: IProcess | undefined) {
140140
if (!processData) {
141141
return undefined;

src/features/language/LanguageProvider.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useGetAppLanguageQuery } from 'src/features/language/textResources/useG
77
import { useProfileQuery } from 'src/features/profile/ProfileProvider';
88
import { useIsAllowAnonymous } from 'src/features/stateless/getAllowAnonymous';
99
import { useLocalStorageState } from 'src/hooks/useLocalStorageState';
10-
import { isAtLeastVersion } from 'src/utils/versionCompare';
10+
import { appSupportsFetchAppLanguagesInAnonymous } from 'src/utils/versioning/versions';
1111

1212
interface LanguageCtx {
1313
current: string;
@@ -91,15 +91,9 @@ export const SetShouldFetchAppLanguages = () => {
9191
// We make the same assumption as in ProfileProvider that the user is logged in when the app does not allow anonymous.
9292
const userIsAuthenticated = useIsAllowAnonymous(false);
9393
const { altinnNugetVersion } = useApplicationMetadata();
94-
const appSupportsFetchAppLanguagesInAnonymous =
95-
altinnNugetVersion &&
96-
isAtLeastVersion({
97-
actualVersion: altinnNugetVersion,
98-
minimumVersion: '8.5.6.180',
99-
});
10094

10195
const setShouldFetchAppLanguages = useCtx().setShouldFetchAppLanguages;
102-
const shouldFetchAppLanguages = appSupportsFetchAppLanguagesInAnonymous || userIsAuthenticated;
96+
const shouldFetchAppLanguages = appSupportsFetchAppLanguagesInAnonymous(altinnNugetVersion) || userIsAuthenticated;
10397
useEffect(() => {
10498
setShouldFetchAppLanguages(shouldFetchAppLanguages);
10599
}, [shouldFetchAppLanguages, setShouldFetchAppLanguages]);

src/features/validation/backendValidation/backendValidationQuery.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import { useCurrentDataModelGuid } from 'src/features/datamodel/useBindingSchema
1111
import { useLaxInstanceId } from 'src/features/instance/InstanceContext';
1212
import { useProcessQuery } from 'src/features/instance/useProcessQuery';
1313
import { useCurrentLanguage } from 'src/features/language/LanguageProvider';
14-
import { appSupportsIncrementalValidationFeatures } from 'src/features/validation/backendValidation/backendValidationUtils';
1514
import { useAsRef } from 'src/hooks/useAsRef';
1615
import { fetchBackendValidationsForDataElement } from 'src/queries/queries';
16+
import { appSupportsIncrementalValidationFeatures } from 'src/utils/versioning/versions';
1717
import type { fetchBackendValidations } from 'src/queries/queries';
1818

1919
/**
@@ -132,7 +132,9 @@ export function useBackendValidationQuery<TResult = BackendValidationIssue[]>(
132132
) {
133133
const queryKey = useBackendValidationQueryKey();
134134
const { fetchBackendValidations, fetchBackendValidationsForDataElement } = useAppQueries();
135-
const hasIncrementalValidationFeatures = appSupportsIncrementalValidationFeatures(useApplicationMetadata());
135+
const hasIncrementalValidationFeatures = appSupportsIncrementalValidationFeatures(
136+
useApplicationMetadata().altinnNugetVersion,
137+
);
136138
const currentDataElementID = useCurrentDataModelGuid();
137139
const instanceId = useLaxInstanceId();
138140
const currentLanguage = useAsRef(useCurrentLanguage()).current;

src/features/validation/backendValidation/backendValidationUtils.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import { BackendValidationSeverity, BuiltInValidationIssueSources, ValidationMas
77
import { validationTexts } from 'src/features/validation/backendValidation/validationTexts';
88
import { useIsPdf } from 'src/hooks/useIsPdf';
99
import { TaskKeys } from 'src/hooks/useNavigatePage';
10-
import { isAtLeastVersion } from 'src/utils/versionCompare';
11-
import type { ApplicationMetadata } from 'src/features/applicationMetadata/types';
1210
import type { TextReference } from 'src/features/language/useLanguage';
1311
import type {
1412
BackendFieldValidatorGroups,
@@ -179,20 +177,3 @@ export function mapValidatorGroupsToDataModelValidations(
179177

180178
return backendValidations;
181179
}
182-
183-
/**
184-
* TODO(Subform): Make sure we reference the correct version here, and in applicationMetadataMock
185-
*
186-
* Prior to app-lib version 8.5.0 there was no way of identifying validation messages that were not run incrementally (ITaskValidator),
187-
* this led to an edge case where if an ITaskValidator returned a validation message with a field, we could not
188-
* distinguish this from a regular custom backend validation which does runs incrementally. The problem is that we block
189-
* submit when we have custom backend validation errors until they are fixed, but since ITaskValidator is not run
190-
* incrementally it would never get fixed until the user refreshed the page. This issue was somewhat mitigated
191-
* by the old dataElement validation API which did not run ITaskValidators.
192-
*
193-
* Therefore, if this function returns false, this means that the app does not make this distinction, but
194-
* has the old API available, so this needs to be used for backwards compatibility.
195-
*/
196-
export function appSupportsIncrementalValidationFeatures({ altinnNugetVersion }: ApplicationMetadata) {
197-
return !altinnNugetVersion || isAtLeastVersion({ actualVersion: altinnNugetVersion, minimumVersion: '8.5.0.141' });
198-
}

src/layout/PDFPreviewButton/PDFPreviewButtonComponent.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,18 @@ import { useApplicationMetadata } from 'src/features/applicationMetadata/Applica
77
import { useStrictInstanceId } from 'src/features/instance/InstanceContext';
88
import { NodesInternal } from 'src/utils/layout/NodesContext';
99
import { useItemWhenType } from 'src/utils/layout/useNodeItem';
10-
import { isAtLeastVersion } from 'src/utils/versionCompare';
10+
import { appSupportsPdfPreviewButton, FEATURE_VERSION_MAP } from 'src/utils/versioning/versions';
1111
import type { NodeValidationProps } from 'src/layout/layout';
1212

1313
export function PDFPreviewButtonRenderLayoutValidator({ intermediateItem }: NodeValidationProps<'PDFPreviewButton'>) {
1414
const instanceId = useStrictInstanceId();
1515
const addError = NodesInternal.useAddError();
1616
const applicationMetadata = useApplicationMetadata();
17-
const minimumBackendVersion = '8.5.0.157';
18-
const backendVersionOK = isAtLeastVersion({
19-
actualVersion: applicationMetadata.altinnNugetVersion ?? '',
20-
minimumVersion: minimumBackendVersion,
21-
});
17+
const isPdfPreviewButtonSupported = appSupportsPdfPreviewButton(applicationMetadata.altinnNugetVersion);
2218

2319
useEffect(() => {
24-
if (!backendVersionOK) {
25-
const error = `Need to be on at least backend version: ${minimumBackendVersion} to user this component`;
20+
if (!isPdfPreviewButtonSupported) {
21+
const error = `Need to be on at least backend version: ${FEATURE_VERSION_MAP.PDF_PREVIEW_BUTTON} to use this component`;
2622
addError(error, intermediateItem.id, 'node');
2723
window.logErrorOnce(`Validation error for '${intermediateItem.id}': ${error}`);
2824
}
@@ -32,7 +28,7 @@ export function PDFPreviewButtonRenderLayoutValidator({ intermediateItem }: Node
3228
addError(error, intermediateItem.id, 'node');
3329
window.logErrorOnce(`Validation error for '${intermediateItem.id}': ${error}`);
3430
}
35-
}, [addError, backendVersionOK, instanceId, intermediateItem.id]);
31+
}, [addError, isPdfPreviewButtonSupported, instanceId, intermediateItem.id]);
3632

3733
return null;
3834
}

0 commit comments

Comments
 (0)