Skip to content

[upcoming] UIE-9402: Implement Owned groups tab landing page#13506

Open
fabrice-akamai wants to merge 25 commits intolinode:developfrom
fabrice-akamai:UIE-9402-owned-groups-landing-page
Open

[upcoming] UIE-9402: Implement Owned groups tab landing page#13506
fabrice-akamai wants to merge 25 commits intolinode:developfrom
fabrice-akamai:UIE-9402-owned-groups-landing-page

Conversation

@fabrice-akamai
Copy link
Contributor

@fabrice-akamai fabrice-akamai commented Mar 17, 2026

Description 📝

This PR implements the Owned groups tab landing page content, allowing unrestricted users to view their share groups.

Note: The current implementation does not allow users to sort the table by image count or membership count since this feature is not yet supported by the backend.

Changes 🔄

List any change(s) relevant to the reviewer.

  • Added ShareGroupsView with the search field and share groups table
  • Added the columns and share group tab configs in ShareGroupsTabsConfig.tsx
  • Added ShareGroupTable with ShareGroupRow and ShareGroupActionMenu

Scope 🚢

Upon production release, changes in this PR will be visible to:

  • All customers
  • Some customers (e.g. in Beta or Limited Availability)
  • No customers / Not applicable

Preview 📷

Screen.Recording.2026-03-18.at.4.27.30.PM.mov

How to test 🧪

Prerequisites

(How to setup test environment)

  • Switch to DevCloud in the dev tools in order to test the share groups API
  • Enable the Private Image Sharing feature flag

Verification steps

(How to verify changes)

  • Navigate to the Images page
  • Click on the Share groups tab
  • Test the share groups view component by interacting with the search field, table and action menus
Author Checklists

As an Author, to speed up the review process, I considered 🤔

👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support


  • I have read and considered all applicable items listed above.

As an Author, before moving this PR from Draft to Open, I confirmed ✅

  • All tests and CI checks are passing
  • TypeScript compilation succeeded without errors
  • Code passes all linting rules

@fabrice-akamai fabrice-akamai marked this pull request as ready for review March 18, 2026 20:31
@fabrice-akamai fabrice-akamai requested a review from a team as a code owner March 18, 2026 20:31
@dwiley-akamai dwiley-akamai added the Private Image Sharing Related to Private Image Sharing feature label Mar 19, 2026
Comment on lines +51 to +58
<Hidden mdDown>
<TableCell>
{updated &&
formatDate(updated, {
timezone: profile?.timezone,
})}
</TableCell>
</Hidden>
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should display a when updated is null (can confirm with UX how they want to handle that but we have done it elsewhere in the app)

Image

Comment on lines +11 to +19
import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter';
import { Table } from 'src/components/Table';
import { TableBody } from 'src/components/TableBody';
import { TableCell } from 'src/components/TableCell';
import { TableHead } from 'src/components/TableHead';
import { TableRow } from 'src/components/TableRow';
import { TableRowEmpty } from 'src/components/TableRowEmpty/TableRowEmpty';
import { TableRowError } from 'src/components/TableRowError/TableRowError';
import { TableSortCell } from 'src/components/TableSortCell/TableSortCell';
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's try to use the CDS Web Components where possible when developing this feature. My last PR shows how to bring in the table-related components for example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do. Thanks!

@abailly-akamai
Copy link
Contributor

@fabrice-akamai I am not going to block this (no need to break it down at this point) but I also am not going to review it. The PR is too large and isn't easily ingestible. Even by looking at the amount of commits this is pretty clear.

While the standards are certainly changing, please keep in mind our contributing guidelines for future PRs. It helps your team members review the code, contribute, and actually ship quicker and with more confidence.

@fabrice-akamai
Copy link
Contributor Author

@fabrice-akamai I am not going to block this (no need to break it down at this point) but I also am not going to review it. The PR is too large and isn't easily ingestible. Even by looking at the amount of commits this is pretty clear.

While the standards are certainly changing, please keep in mind our contributing guidelines for future PRs. It helps your team members review the code, contribute, and actually ship quicker and with more confidence.

Hi @abailly-akamai, I agree that this is a pretty large PR and it involves a lot of file changes. This is mainly because the table I implemented required a lot of subcomponents to be added like the row, action menu, and search field. I also had to add new queries to support fetching the paginated data, so it was hard to break them down without leaving out an essential part of the feature. In the future, I'll make sure to break down such features into smaller PRs that are easier to review. Thanks for the feedback!

Copy link
Contributor

@dwiley-akamai dwiley-akamai left a comment

Choose a reason for hiding this comment

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

Code review ✅
Verification steps ✅

My comments about UI styling/formatting can be addressed in a follow-up PR but the Pendo IDs and import consolidation can be done in this one

Copy link
Contributor

Choose a reason for hiding this comment

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

The formatting & mobile support will need to be improved here:

  • Updated cell dash seems right-aligned
  • Updated cell contents get hidden at some point but the column remains (and the Created content gets shifted there)
  • Column names wrap or get obscured
  • Group names get obscured at a point
Screen.Recording.2026-03-23.at.11.29.39.AM.mov

This can be handled in a follow-up PR

@fabrice-akamai
Copy link
Contributor Author

Code review ✅ Verification steps ✅

My comments about UI styling/formatting can be addressed in a follow-up PR but the Pendo IDs and import consolidation can be done in this one

Thanks @dwiley-akamai for the thorough review. Here's a summary of my latest changes:

  • Pendo IDs in Action menu: Updated the name to be more concise, based on the Figma mocks
  • TableRowEmpty state: Removed the TableRowEmpty component that doesn't render properly with the CDS table. Added a simple table row instead.
  • Table responsiveness: Fixed the bug causing the inconsistency at different breakpoints and addressed the edge case with the group names.
  • Empty updated cell: Left-aligned the dash for consistency with the rest of the table.
Screen.Recording.2026-03-23.at.3.46.02.PM.mov

Screenshot 2026-03-23 at 3 45 50 PM

Comment on lines +171 to +180
<TableRow>
<TableCell
style={{
display: 'flex',
justifyContent: 'center',
}}
>
{emptyMessage.main}
</TableCell>
</TableRow>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<TableRow>
<TableCell
style={{
display: 'flex',
justifyContent: 'center',
}}
>
{emptyMessage.main}
</TableCell>
</TableRow>
<TableRow rowborder>
<TableCell>
<Box
sx={(theme) => ({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: theme.spacingFunction(4),
p: `${theme.spacingFunction(24)} ${theme.spacingFunction(32)}`,
width: '100%',
})}
>
<ZeroStateSearchNarrowIcon />
<Typography variant="h3">{emptyMessage.main}</Typography>
{!query && emptyMessage.instruction && (
<Typography variant="body1">
{emptyMessage.instruction}
</Typography>
)}
</Box>
</TableCell>
</TableRow>

If TableRowEmpty isn't working here, I think we should be able to achieve the same using the ADS table components. This change should align with the Figma mockups, and the rowBorder prop will ensure the bottom border/stroke for the last row or empty states, just like we see in the non ads components.

Comment on lines +183 to +186
<TableRowError
colSpan={columns.length + 1}
message={error[0].reason}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

I see there's an alignment issue here - we should also be able to fix this by using the ADS component.

Suggested change
<TableRowError
colSpan={columns.length + 1}
message={error[0].reason}
/>
<TableRow rowborder>
<TableCell>
<ErrorState compact errorText={error[0].reason} />
</TableCell>
</TableRow>
Before After
Image Image

shareGroups: Sharegroup[];
}

export const ShareGroupsTable = (props: ShareGroupsTableProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Unlike other tables (ADS tables like Databases Clusters or non-ADS tables like Owned by me / Recovery Images), why isn't table striping working for this table when My Profile -> Preferences -> Table Striping is turned ON?

When My Profile -> Preferences -> Table Striping -> Turned ON:

Other CM tables ShareGroupsTable
Image Image Image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good observation. I didn't account for that, I'll update the table to use the user preferences.

<SafeTabPanel index={index} key={`images-${tab.type}-content`}>
{tab.type === 'owned-groups' && (
<Notice variant="info">Owned Groups is coming soon...</Notice>
<ShareGroupsView type={'owned-groups'} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<ShareGroupsView type={'owned-groups'} />
<ShareGroupsView type="owned-groups" />

nit: No need for {} here -- using a plain string prop is cleaner

import type { ShareGroupsViewTableColConfig } from './shareGroupsTabsConfig';
import type { APIError, Sharegroup } from '@linode/api-v4';
import type { Order } from 'src/hooks/useOrderV2';
interface HeaderProps {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could we add a line break between the imports and the interface declaration for better readability?

{headerProps.buttonProps && (
<Button
buttonType="primary"
data-pendo-id={`Images Groups Owned-Create Button`}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
data-pendo-id={`Images Groups Owned-Create Button`}
data-pendo-id={headerProps.buttonProps.pendoId}

))}
</TableBody>
</Table>
<PaginationFooter
Copy link
Contributor

Choose a reason for hiding this comment

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

question (non-blocking & optional): Is there any plan to replace this PaginationFooter with the ADS PaginationFooter (if available) across all places in the context of Private Image Sharing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not aware of any plan to replace the PaginationFooter across the app, but I would assume that if we're eventually going to integrate the CDS components in CM then this PaginationFooter will probably be replaced as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should be using the CDS Pagination component -- import { Pagination } from 'akamai-cds-react-components/Pagination'

mb: 2,
},
}}
data-pendo-id="Images Groups Owned-Search"
Copy link
Contributor

Choose a reason for hiding this comment

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

The hardcoded Pendo ID here seems to be an issue❗️ We may need to keep the Pendo IDs in a config for all subsequent table searches and use them here from the config instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I'll move away from hard-coded values here and define them in the config file so they can be passed as props.

@linode-gh-bot
Copy link
Collaborator

Cloud Manager UI test results

🔺 4 failing tests on test run #15 ↗︎

❌ Failing✅ Passing↪️ Skipped🕐 Duration
4 Failing884 Passing11 Skipped50m 5s

Details

Failing Tests
SpecTest
object-storage-objects-multicluster.spec.tsCloud Manager Cypress Tests→Object Storage Multicluster objects » can upload, access, and delete objects
object-storage.e2e.spec.tsCloud Manager Cypress Tests→object storage end-to-end tests » can create and delete object storage buckets
alerts-create.spec.tsCloud Manager Cypress Tests→Create flow when beta alerts enabled by region and feature flag » create flow after switching to beta alerts
alerts-create.spec.tsCloud Manager Cypress Tests→Create flow when beta alerts enabled by region and feature flag » can toggle from legacy to beta alerts and back to legacy

Troubleshooting

Use this command to re-run the failing tests:

pnpm cy:run -s "cypress/e2e/core/objectStorageMulticluster/object-storage-objects-multicluster.spec.ts,cypress/e2e/core/objectStorage/object-storage.e2e.spec.ts,cypress/e2e/core/linodes/alerts-create.spec.ts"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Private Image Sharing Related to Private Image Sharing feature

Projects

Status: Review

Development

Successfully merging this pull request may close these issues.

5 participants