Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(app-deploy): Frontend support for undeploying an application in a selected environment #14494

Open
wants to merge 24 commits into
base: main
Choose a base branch
from

Conversation

framitdavid
Copy link
Collaborator

@framitdavid framitdavid commented Jan 23, 2025

Description

This PR implements a context that allows users to choose between going to the app in the environment or undeploying the app. When the user selects the undeploy option, a dialog is shown to inform them of the consequences of undeploying the app. If the user proceeds, they are then prompted with a confirmation dialog to ensure they understand the impact of undeploying. This flow ensures that users are fully aware of the actions they are taking and the potential consequences.

⚡ Important Information
The backend is not fully implemented yet. As a result, clicking "Undeploy" currently results in a 404 error due to the endpoint not being available. Mirko is working on the backend part of this feature in a separate PR. The frontend is hidden behind feature flag as well.

Related Issue(s)

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing done (required) (Verified that we got 404 (since backend is not ready), with correct request payload)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)

Summary by CodeRabbit

Based on the comprehensive changes, here are the updated release notes:

  • New Features

    • Added a new "Undeploy App" functionality with a confirmation dialog.
    • Introduced a more options menu for deployment environments.
    • Enhanced deployment management with detailed consequence warnings.
    • Added a new UndeployConsequenceDialog for user confirmations.
    • Implemented a DeployMoreOptionsMenu for additional deployment actions.
  • Improvements

    • Refined deployment environment status display.
    • Added internationalization support for new deployment features.
    • Improved user experience for app management.
    • Enhanced styling for deployment-related components.
  • Bug Fixes

    • Removed deprecated undeploy components.
    • Updated styling for deployment-related components.
  • Documentation

    • Added comprehensive translations for new deployment features.
    • Included detailed user guidance for app undeployment process.

Copy link
Contributor

coderabbitai bot commented Jan 23, 2025

Warning

Rate limit exceeded

@framitdavid has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 33a1db6 and e7204ef.

📒 Files selected for processing (9)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.module.css (1 hunks)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/UndeployConsequenceDialog.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/ListItemWithLink.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/consequences.data.ts (1 hunks)
  • frontend/app-development/hooks/mutations/useUndeployMutation.ts (1 hunks)
  • frontend/language/src/nb.json (2 hunks)
📝 Walkthrough

Walkthrough

This pull request introduces a comprehensive implementation of an application undeployment feature across multiple frontend components. The changes include creating new components like ConfirmUndeployDialog, UndeployConsequenceDialog, and DeployMoreOptionsMenu, along with associated utility functions, tests, and internationalization updates. The implementation removes the previous placeholder UnDeploy component and replaces it with a more robust undeployment workflow that includes confirmation dialogs, consequence explanations, and mutation hooks for handling the undeployment process.

Changes

File Change Summary
frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/* New component with CSS, tests, and implementation for confirming app undeploy
frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/* New component for displaying deployment-related menu options
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/* New dialog component explaining consequences of undeploying an app
frontend/app-development/hooks/mutations/useUndeployMutation.ts New custom hook for handling app undeployment mutations
frontend/packages/shared/src/api/mutations.ts Added undeployAppFromEnv function for API undeployment
frontend/language/src/nb.json Updated translations for undeployment feature

Possibly related PRs

Suggested labels

quality/testing, skip-releasenotes, team/studio-domain1, skip-documentation

Suggested reviewers

  • mirkoSekulic
  • ErlingHauan

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added area/app-deploy Area: Related to deploying apps from Altinn Studio to Altinn Apps. solution/studio/designer Issues related to the Altinn Studio Designer solution. frontend labels Jan 23, 2025
@framitdavid framitdavid changed the title Feature/undeploy front end feat(app-deploy): Frontend support for undeploying an application in a selected environment Jan 23, 2025
@framitdavid framitdavid linked an issue Jan 23, 2025 that may be closed by this pull request
Copy link

codecov bot commented Jan 23, 2025

Codecov Report

Attention: Patch coverage is 96.34146% with 3 lines in your changes missing coverage. Please review.

Project coverage is 95.69%. Comparing base (fd014a5) to head (e7204ef).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ts/ConfirmUndeployDialog/ConfirmUndeployDialog.tsx 92.00% 2 Missing ⚠️
...Publish/components/DeploymentEnvironmentStatus.tsx 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #14494   +/-   ##
=======================================
  Coverage   95.69%   95.69%           
=======================================
  Files        1893     1902    +9     
  Lines       24634    24704   +70     
  Branches     2823     2825    +2     
=======================================
+ Hits        23573    23641   +68     
- Misses        800      802    +2     
  Partials      261      261           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@framitdavid framitdavid marked this pull request as ready for review January 23, 2025 13:26
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (13)
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/utils/isItemWithLink.test.ts (1)

4-14: Enhance test coverage with edge cases.

While the basic cases are covered, consider adding tests for:

  • Objects with undefined/null link values
  • Malformed input objects
  • Objects with unexpected link types
it('should return false for object with undefined link', () => {
  const item = { textKey: 'key', link: undefined };
  expect(isItemWithLink(item)).toBe(false);
});

it('should return false for malformed input', () => {
  const item = { textKey: 'key', link: null };
  expect(isItemWithLink(item)).toBe(false);
});
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.tsx (1)

9-18: Consider adding aria-label for better accessibility.

While the component structure is good, consider enhancing accessibility by adding an aria-label to the section div.

-  <div className={classes.section}>
+  <div className={classes.section} aria-label={title}>
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.test.tsx (1)

5-17: Enhance test coverage with additional test cases.

While the basic rendering test is good, consider adding tests for:

  • Empty title handling
  • Multiple children rendering
  • Long content truncation (if implemented)

Example additional test:

test('handles empty title gracefully', () => {
  const children = <li>Item 1</li>;
  render(<Section title="">{children}</Section>);
  expect(screen.getByRole('heading')).toBeInTheDocument();
});
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/consequences.data.ts (1)

38-38: Consider making the documentation URL language-agnostic.

The hardcoded Norwegian language path (/nb/) in the documentation URL might cause issues for users with different language preferences.

-        link: 'https://docs.altinn.studio//nb/altinn-studio/reference/logic/instantiation/',
+        link: 'https://docs.altinn.studio/altinn-studio/reference/logic/instantiation/',
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.tsx (1)

14-32: Consider adding error boundaries for robust error handling.

While the implementation is clean, consider wrapping the mapping operations in an error boundary to gracefully handle potential runtime errors (e.g., malformed data).

+import { ErrorBoundary } from '@studio/components';
+
 export const DialogContent = ({ environment }: DialogContentProps) => {
   const { t } = useTranslation();
   return (
     <>
+      <ErrorBoundary>
         {consequencesDialogData.map((section) => (
           <Section key={section.titleKey} title={t(section.titleKey)}>
             {section.items.map((item) =>
               isItemWithLink(item) ? (
                 <ListItemWithLink key={item.textKey} textKey={item.textKey} link={item.link} />
               ) : (
                 <StudioList.Item key={item.textKey}>{t(item.textKey)}</StudioList.Item>
               ),
             )}
           </Section>
         ))}
+      </ErrorBoundary>
       <ConfirmUndeployDialog environment={environment} />
     </>
   );
 };
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.test.tsx (1)

10-33: Enhance test coverage with edge cases.

While the basic test cases are good, consider adding tests for:

  • Empty sections or items
  • Missing translations
  • Verification of link rendering for ItemWithLink
it('should handle empty sections gracefully', () => {
  // Mock empty data
  jest.spyOn(consequencesModule, 'consequencesDialogData').mockReturnValue([
    { titleKey: 'empty_section', items: [] }
  ]);
  renderDialogContent('unit-test-env');
  expect(screen.getByRole('heading', { name: textMock('empty_section') })).toBeInTheDocument();
});

it('should render links correctly for ItemWithLink', () => {
  renderDialogContent('unit-test-env');
  // Find the link from consequencesDialogData
  const link = screen.getByRole('link', {
    name: textMock('app_deployment.unpublish_alternatives_change_access')
  });
  expect(link).toHaveAttribute('href', expect.stringContaining('docs.altinn.studio'));
});
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/UndeployConsequenceDialog.test.tsx (1)

10-27: Add test coverage for modal interactions and error states.

While the basic modal opening test is good, consider adding tests for:

  • Modal closing behavior
  • Error handling
  • Environment prop validation
it('should close modal when close button is clicked', async () => {
  const user = userEvent.setup();
  renderUndeployConsequenceDialog('production');
  
  // Open modal
  await user.click(screen.getByRole('button', {
    name: textMock('app_deployment.undeploy_button')
  }));
  
  // Close modal
  const closeButton = screen.getByRole('button', {
    name: textMock('common.close_button')
  });
  await user.click(closeButton);
  
  expect(screen.queryByRole('heading', {
    name: textMock('app_deployment.unpublish_consequence_dialog_title')
  })).not.toBeInTheDocument();
});

it('should validate environment prop', () => {
  const consoleError = jest.spyOn(console, 'error').mockImplementation();
  renderUndeployConsequenceDialog('');
  expect(consoleError).toHaveBeenCalled();
  consoleError.mockRestore();
});
frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.tsx (1)

8-11: Props type could be more descriptive

Consider renaming the props type to better reflect its purpose and adding JSDoc comments for better documentation.

-type DeployMoreOptionsMenuProps = {
+/**
+ * Props for the DeployMoreOptionsMenu component
+ * @property {string} environment - The deployment environment (e.g., 'production', 'staging')
+ * @property {string} linkToEnv - The URL to access the deployed application
+ */
+type DeploymentOptionsMenuProps = {
   environment: string;
   linkToEnv: string;
 };
frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.test.tsx (2)

7-19: Add keyboard interaction tests

While the click interactions are well tested, consider adding tests for keyboard navigation (Tab, Enter, Escape keys) to ensure accessibility compliance.

+  it('should handle keyboard navigation', async () => {
+    const user = userEvent.setup();
+    renderMenu(linkToEnv);
+    
+    // Tab to focus the trigger
+    await user.tab();
+    expect(screen.getByRole('button')).toHaveFocus();
+    
+    // Enter to open menu
+    await user.keyboard('{Enter}');
+    expect(screen.getAllByRole('listitem')).toHaveLength(2);
+    
+    // Escape to close menu
+    await user.keyboard('{Escape}');
+    expect(screen.queryByRole('listitem')).not.toBeInTheDocument();
+  });

49-51: Consider adding error boundary test cases

The renderMenu helper could be enhanced to test error scenarios.

-function renderMenu(linkToEnv: string): void {
+function renderMenu(linkToEnv: string, options = {}): void {
+  const { throwError = false } = options;
   render(<DeployMoreOptionsMenu linkToEnv={linkToEnv} environment='unit-test-env' />);
 }
+
+it('should handle errors gracefully', () => {
+  const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
+  expect(() => renderMenu('invalid-url', { throwError: true })).not.toThrow();
+  consoleSpy.mockRestore();
+});
frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.test.tsx (2)

53-72: Enhance mutation test coverage.

While the test verifies that the mutation is called, consider adding:

  1. Verification of the loading state during mutation
  2. Error handling test case
  3. Success callback test case

Example enhancement:

 it('should trigger undeploy when undeploy button is clicked', async () => {
   const user = userEvent.setup();
+  const onSuccessMock = jest.fn();
+  const onErrorMock = jest.fn();
   renderConfirmUndeployDialog();
   await openDialog();

   const mutateFunctionMock = jest.fn();
   (useUndeployMutation as jest.Mock).mockReturnValue({
     mutate: mutateFunctionMock,
+    isLoading: false,
   });

   const confirmTextField = getConfirmTextField();
   await user.type(confirmTextField, app);
   await user.click(getUndeployButton());

   expect(mutateFunctionMock).toBeCalledTimes(1);
   expect(mutateFunctionMock).toHaveBeenCalledWith(
     expect.objectContaining({ environment: 'unit-test-env' }),
-    expect.anything(),
+    expect.objectContaining({
+      onSuccess: expect.any(Function),
+      onError: expect.any(Function),
+    }),
   );
+
+  // Test loading state
+  (useUndeployMutation as jest.Mock).mockReturnValue({
+    mutate: mutateFunctionMock,
+    isLoading: true,
+  });
+  expect(getUndeployButton()).toBeDisabled();
 });
+
+it('should handle errors during undeploy', async () => {
+  const user = userEvent.setup();
+  const onErrorMock = jest.fn();
+  renderConfirmUndeployDialog();
+  await openDialog();
+
+  const mutateFunctionMock = jest.fn().mockImplementation((_, { onError }) => {
+    onError(new Error('Test error'));
+  });
+  (useUndeployMutation as jest.Mock).mockReturnValue({
+    mutate: mutateFunctionMock,
+  });
+
+  const confirmTextField = getConfirmTextField();
+  await user.type(confirmTextField, app);
+  await user.click(getUndeployButton());
+
+  expect(onErrorMock).toHaveBeenCalled();
+});

91-95: Consider additional test scenarios for the render function.

Add test cases for:

  1. Different environment values
  2. URL validation
  3. Provider context variations

Example:

+it('should handle different environment values', () => {
+  const environments = ['test', 'prod', 'staging'];
+  environments.forEach((env) => {
+    const { unmount } = renderConfirmUndeployDialog(env);
+    expect(screen.getByRole('dialog')).toBeInTheDocument();
+    unmount();
+  });
+});
+
+it('should validate URL in provider context', () => {
+  renderConfirmUndeployDialog('test-env', {
+    startUrl: `${APP_DEVELOPMENT_BASENAME}/invalid/path`,
+  });
+  expect(screen.getByRole('dialog')).toBeInTheDocument();
+});
frontend/language/src/nb.json (1)

134-140: Consider adding more specific consequences about data retention.

While the translations effectively communicate the immediate consequences of undeploying, consider adding information about:

  • Data retention policies
  • Whether the action can be reversed
  • How long the data remains accessible through the Storage API
  "app_deployment.unpublish_considerations_storage_api": "Du må hente ut data fra appens eksemplarer rett fra Storage API.",
+ "app_deployment.unpublish_considerations_data_retention": "Data vil være tilgjengelig i Storage API i X dager etter avpublisering.",
+ "app_deployment.unpublish_considerations_reversible": "Merk at avpublisering ikke kan angres.",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db69ab4 and 1f5d6eb.

📒 Files selected for processing (31)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.module.css (1 hunks)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/index.ts (1 hunks)
  • frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.module.css (1 hunks)
  • frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/DeploymentEnvironment.tsx (0 hunks)
  • frontend/app-development/features/appPublish/components/DeploymentEnvironmentStatus.module.css (0 hunks)
  • frontend/app-development/features/appPublish/components/DeploymentEnvironmentStatus.tsx (2 hunks)
  • frontend/app-development/features/appPublish/components/UnDeploy/UnDeploy.test.tsx (0 hunks)
  • frontend/app-development/features/appPublish/components/UnDeploy/UnDeploy.tsx (0 hunks)
  • frontend/app-development/features/appPublish/components/UnDeploy/index.ts (0 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/UndeployConsequenceDialog.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/UndeployConsequenceDialog.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/ListItemWithLink.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.module.css (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.test.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.tsx (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/index.ts (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/consequences.data.ts (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/utils/isItemWithLink.test.ts (1 hunks)
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/utils/isItemWithLink.ts (1 hunks)
  • frontend/app-development/hooks/mutations/useUndeployMutation.test.ts (1 hunks)
  • frontend/app-development/hooks/mutations/useUndeployMutation.ts (1 hunks)
  • frontend/language/src/nb.json (2 hunks)
  • frontend/packages/shared/src/api/mutations.ts (2 hunks)
  • frontend/packages/shared/src/api/paths.js (1 hunks)
  • frontend/packages/shared/src/mocks/queriesMock.ts (1 hunks)
💤 Files with no reviewable changes (5)
  • frontend/app-development/features/appPublish/components/UnDeploy/index.ts
  • frontend/app-development/features/appPublish/components/UnDeploy/UnDeploy.test.tsx
  • frontend/app-development/features/appPublish/components/DeploymentEnvironment.tsx
  • frontend/app-development/features/appPublish/components/UnDeploy/UnDeploy.tsx
  • frontend/app-development/features/appPublish/components/DeploymentEnvironmentStatus.module.css
✅ Files skipped from review due to trivial changes (5)
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.module.css
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/index.ts
  • frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/index.ts
  • frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.module.css
  • frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.module.css
🔇 Additional comments (17)
frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/utils/isItemWithLink.ts (1)

3-5: Well-implemented type guard!

The type guard implementation is clean, focused, and follows TypeScript best practices by correctly using the type predicate syntax.

frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/Section/Section.tsx (1)

5-8: LGTM! Well-structured props interface.

The props interface is clear and properly typed, following TypeScript best practices.

frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/consequences.data.ts (1)

3-14: LGTM! Well-structured type definitions.

The type definitions are clear, extensible, and follow TypeScript best practices. Good use of type composition with ItemWithLink extending Item.

frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.tsx (1)

10-13: LGTM! Clean prop type definition.

The prop type is well-defined and follows TypeScript best practices.

frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/components/DialogContent.test.tsx (1)

35-39: LGTM! Clean test helper implementation.

The helper function is well-structured and provides good reusability for the tests.

frontend/app-development/features/appPublish/components/UndeployConsequenceDialog/UndeployConsequenceDialog.test.tsx (1)

29-33: LGTM! Well-structured test helper.

The helper function provides a clean way to render the component with necessary context.

frontend/app-development/features/appPublish/components/DeployMoreOptionsMenu/DeployMoreOptionsMenu.tsx (2)

19-27: LGTM! Good accessibility implementation

The menu trigger button is properly implemented with:

  • Appropriate ARIA label for screen readers
  • Consistent button sizing
  • Clear visual feedback through the icon

34-46: LGTM! Secure external link implementation

The external link button correctly implements security best practices:

  • Uses rel="noopener noreferrer" for security
  • Opens in a new tab
  • Includes a visual indicator (ExternalLinkIcon)
frontend/app-development/features/appPublish/components/DeploymentEnvironmentStatus.tsx (1)

52-54: LGTM! Clean feature flag implementation

The DeployMoreOptionsMenu is properly gated behind both a feature flag and the presence of deployment version, ensuring controlled rollout.

frontend/app-development/features/appPublish/components/ConfirmUndeployDialog/ConfirmUndeployDialog.test.tsx (2)

1-12: Well-structured test setup with appropriate mocks and imports.

The test file follows testing best practices by:

  • Using appropriate testing libraries
  • Properly mocking the mutation hook
  • Organizing imports logically

75-89: Well-structured helper functions improving test maintainability.

The helper functions are:

  • Clearly named and focused
  • Reusable across test cases
  • Using proper testing-library queries
frontend/packages/shared/src/api/mutations.ts (1)

99-99: Clean implementation of undeployment mutation.

The mutation follows the established patterns:

  • Consistent parameter ordering (org, app, environment)
  • Uses POST method appropriately
  • Properly structured payload
frontend/packages/shared/src/api/paths.js (1)

103-103: Well-placed and consistent path definition.

The path:

  • Is grouped with related deployment paths
  • Follows the established URL pattern
  • Uses consistent parameter naming
frontend/packages/shared/src/mocks/queriesMock.ts (1)

253-253: Appropriate mock implementation.

The mock:

  • Follows the established mocking pattern
  • Returns a resolved promise as expected
  • Is properly placed in the mutations section
frontend/language/src/nb.json (3)

84-84: LGTM: Deploy menu translations are clear and consistent.

The translations for the deployment menu options are well-written and accurately describe the functionality:

  • "Åpne meny med tilgang til miljø og mulighet for avpublisering" clearly indicates the menu's purpose
  • "Gå til miljøet" is a concise action text

Also applies to: 89-89


124-128: LGTM: Undeploy button and confirmation dialog translations are clear and user-friendly.

The translations effectively guide users through the undeployment process:

  • Consistent use of "avpubliser" terminology
  • Clear confirmation dialog that requires typing the app name
  • Well-structured warning about the consequences

129-133: LGTM: Alternative actions are well explained.

The translations provide clear alternatives to undeploying:

  • Each alternative action is clearly explained
  • Good use of links in the text (e.g., <a>Endre innstillingen for tilgang eller oppstart</a>)
  • Maintains consistent terminology

Copy link
Member

@nkylstad nkylstad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks great! I saw that CodeRabbit had some interesting suggestions, and I have a few comments/suggestions as well for you to consider. Happy to approve this once you have looked over the comments 😊

{ textKey: 'app_deployment.unpublish_alternatives_make_unavailable' },
{
textKey: 'app_deployment.unpublish_alternatives_change_access',
link: 'https://docs.altinn.studio//nb/altinn-studio/reference/logic/instantiation/',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a double // before nb here. Don't think it actually causes an issue, but I think we have a utils function that returns the docs base path with the correct language that we might use instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

frontend/language/src/nb.json Outdated Show resolved Hide resolved
frontend/language/src/nb.json Outdated Show resolved Hide resolved
@framitdavid
Copy link
Collaborator Author

Overall, this looks great! I saw that CodeRabbit had some interesting suggestions, and I have a few comments/suggestions as well for you to consider. Happy to approve this once you have looked over the comments 😊

Yes, I saw the comments from CodeRabbit, many of them will be implemented asap. :)

@framitdavid framitdavid requested a review from nkylstad January 23, 2025 15:49
Copy link
Member

@nkylstad nkylstad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!
Added one nitpick comment, up to you if it's with doing anything with 😊

{ textKey: 'app_deployment.unpublish_alternatives_make_unavailable' },
{
textKey: 'app_deployment.unpublish_alternatives_change_access',
link: 'app_deployment.unpublish_alternatives_change_access_link',
Copy link
Member

@nkylstad nkylstad Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a function in shared/src/ext-urls calles altinnDocsUrl that takes in a language and relative URL, and returns the fully qualified url to the docs. Perhaps that could be used here rather than putting a static link in the text resources?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/app-deploy Area: Related to deploying apps from Altinn Studio to Altinn Apps. frontend solution/studio/designer Issues related to the Altinn Studio Designer solution.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Frontend: Implement design to trigger un-deploy
2 participants