Skip to content

Commit

Permalink
chore: Implementing text when saving scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
wrt95 committed Nov 29, 2024
1 parent 2063c2e commit 8e0ec51
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.savingContainer {
display: flex;
align-items: center;
gap: var(--fds-spacing-1);
margin-top: var(--fds-spacing-4);
}

.savedIcon {
font-size: var(--fds-sizing-8);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { SaveStatus, type SaveStatusProps } from './SaveStatus';
import { textMock } from '@studio/testing/mocks/i18nMock';

const defaultProps: SaveStatusProps = {
isPending: true,
isSaved: true,
};

describe('SaveStatus', () => {
it('should render pending status with spinner', () => {
renderSaveStatus({
componentProps: {
isSaved: false,
},
});

expect(
screen.getByText(textMock('settings_modal.maskinporten_tab_save_scopes_pending')),
).toBeInTheDocument();

expect(
screen.getByTitle(textMock('settings_modal.maskinporten_tab_save_scopes_pending_spinner')),
).toBeInTheDocument();
});

it('should render saved status with checkmark icon', () => {
renderSaveStatus({
componentProps: {
isPending: false,
},
});
expect(
screen.getByText(textMock('settings_modal.maskinporten_tab_save_scopes_complete')),
).toBeInTheDocument();
});

it('should render nothing when neither pending nor saved', () => {
const { container } = renderSaveStatus({
componentProps: {
isPending: false,
isSaved: false,
},
});
expect(container).toBeEmptyDOMElement();
});
});

type Props = {
componentProps: Partial<SaveStatusProps>;
};
const renderSaveStatus = (props: Partial<Props> = {}) => {
return render(<SaveStatus {...defaultProps} {...props.componentProps} />);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { type ReactElement } from 'react';
import classes from './SaveStatus.module.css';
import { StudioParagraph, StudioSpinner } from '@studio/components';
import { useTranslation } from 'react-i18next';
import { CheckmarkIcon } from '@studio/icons';

export type SaveStatusProps = {
isPending: boolean;
isSaved: boolean;
};

export const SaveStatus = ({ isPending, isSaved }: SaveStatusProps): ReactElement => {
const { t } = useTranslation();

if (isPending) {
return (
<SaveStatusContent
text={t('settings_modal.maskinporten_tab_save_scopes_pending')}
isPending
/>
);
}
if (isSaved) {
return <SaveStatusContent text={t('settings_modal.maskinporten_tab_save_scopes_complete')} />;
}
return null;
};

type SaveStatusContentProps = {
text: string;
isPending?: boolean;
};

const SaveStatusContent = ({ text, isPending = false }: SaveStatusContentProps): ReactElement => {
const { t } = useTranslation();

return (
<div className={classes.savingContainer}>
<StudioParagraph size='sm'>{text}</StudioParagraph>
{isPending ? (
<StudioSpinner
spinnerTitle={t('settings_modal.maskinporten_tab_save_scopes_pending_spinner')}
size='sm'
/>
) : (
<CheckmarkIcon className={classes.savedIcon} />
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SaveStatus } from './SaveStatus';
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { type ChangeEvent, type ReactElement } from 'react';
import classes from './ScopeList.module.css';

import {
StudioCheckboxTable,
type StudioCheckboxTableRowElement,
Expand All @@ -25,6 +24,7 @@ import { GetInTouchWith } from 'app-shared/getInTouch';
import { EmailContactProvider } from 'app-shared/getInTouch/providers';
import { LoggedInTitle } from '../LoggedInTitle';
import { useUpdateSelectedMaskinportenScopesMutation } from 'app-development/hooks/mutations/useUpdateSelectedMaskinportenScopesMutation';
import { SaveStatus } from '../SaveStatus';

export type ScopeListProps = {
maskinPortenScopes: MaskinportenScope[];
Expand All @@ -33,8 +33,11 @@ export type ScopeListProps = {

export const ScopeList = ({ maskinPortenScopes, selectedScopes }: ScopeListProps): ReactElement => {
const { t } = useTranslation();
const { mutate: mutateSelectedMaskinportenScopes } =
useUpdateSelectedMaskinportenScopesMutation();
const {
mutate: mutateSelectedMaskinportenScopes,
isPending: isPendingSaveScopes,
isSuccess: scopesSaved,
} = useUpdateSelectedMaskinportenScopesMutation();

const checkboxTableRowElements: StudioCheckboxTableRowElement[] = mapScopesToRowElements(
maskinPortenScopes,
Expand Down Expand Up @@ -103,6 +106,7 @@ export const ScopeList = ({ maskinPortenScopes, selectedScopes }: ScopeListProps
))}
</StudioCheckboxTable.Body>
</StudioCheckboxTable>
<SaveStatus isPending={isPendingSaveScopes} isSaved={scopesSaved} />
</div>
);
};
Expand Down
3 changes: 3 additions & 0 deletions frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,9 @@
"settings_modal.maskinporten_tab_description": "Maskinporten autentiserer og autoriserer API-er som skal brukes i apper. I Maskinporten kan du lage hvilke scopes en app skal ha fra og til andre systemer, for eksempel tilgang til persondata.",
"settings_modal.maskinporten_tab_login_with_ansattporten": "Logg inn med Ansattporten",
"settings_modal.maskinporten_tab_login_with_description": "Med Ansattporten logger du inn på vegne av virksomheten. Her kan du se og velge scopes.",
"settings_modal.maskinporten_tab_save_scopes_complete": "Lagret",
"settings_modal.maskinporten_tab_save_scopes_pending": "Lagrer...",
"settings_modal.maskinporten_tab_save_scopes_pending_spinner": "Lagrer scopes",
"settings_modal.maskinporten_tab_title": "Velg scopes fra Maskinporten",
"settings_modal.policy_tab_heading": "Tilganger",
"settings_modal.setup_tab_heading": "Oppsett",
Expand Down

0 comments on commit 8e0ec51

Please sign in to comment.