Skip to content

Conversation

dchyun
Copy link
Contributor

@dchyun dchyun commented Jul 29, 2025

📌 Summary

If merged, this PR would convert the pages in the showcase for the Table component to TS.

Showcase page

Note: Percy diff is expected as the medium density is now being displayed.

🔗 External links

Jira ticket: HDS-5076


👀 Component checklist

  • Percy was checked for any visual regression

💬 Please consider using conventional comments when reviewing this PR.

📋 PCI review checklist
  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • If applicable, I've worked with GRC to document the impact of any changes to security controls.
    Examples of changes to controls include access controls, encryption, logging, etc.
  • If applicable, I've worked with GRC to ensure compliance due to a significant change to the in-scope PCI environment.
    Examples include changes to operating systems, ports, protocols, services, cryptography-related components, PII processing code, etc.

Copy link

vercel bot commented Jul 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
hds-showcase ✅ Ready (Inspect) Visit Preview Aug 7, 2025 6:36pm
hds-website ✅ Ready (Inspect) Visit Preview Aug 7, 2025 6:36pm

selectionKey,
selectionCheckboxElement,
}: HdsTableOnSelectionChangeSignature) {
if (selectionKey) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] selectionKey and selectionCheckboxElement are optional, so checks have been added to handle that use case. This applies to all similar selection change functions below.

@tracked multiSelectToggleScope__demo1 = false;
@tracked multiSelectToggleDebug__demo1 = false;
@deepTracked multiSelectSelectableData__demo1 = [
// @ts-expect-error - we need to reevaluate how we get the data for the table demos when we break up the template files into sub components
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] Without this, an error is flagged that the controller is using this.model before it is defined. Similar expect errors are added for other data variables.

@@ -56,6 +56,7 @@
"@glint/template": "^1.5.2",
"@hashicorp/design-system-components": "workspace:*",
"@hashicorp/design-system-tokens": "workspace:*",
"@nullvoxpopuli/ember-composable-helpers": "^5.2.11",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] In the Table template the helper call is used, but its package, ember-composable-helpers, isn't included in the showcase devDependencies.

console.log('Selected Row Keys:', selectedRowsKeys);
console.groupEnd();
this.multiSelectUserData__demo4.forEach((user) => {
user.isSelected = selectedRowsKeys.includes(user.id);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] There are type errors thrown here as user.id is a number, but selectionRowKeys expects a string. selectionRowKeys has been updated to support number in #3066 .

<B.Tr
@selectionKey={{B.data.id}}
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
@selectionKey="{{B.data.id}}"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] @selectionKey is typed as a string, but the data id is a number, so converting it to a string here, and in following similar instances.

@@ -3,6 +3,7 @@
SPDX-License-Identifier: MPL-2.0
}}

{{! @glint-expect-error - file will be broken up in https://hashicorp.atlassian.net/browse/HDS-5077}}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] There is an error thrown about how lengthy this page is, this should be able to be removed once the page is broken up into sub templates.

@dchyun dchyun marked this pull request as ready for review July 30, 2025 18:09
@dchyun dchyun requested a review from a team as a code owner July 30, 2025 18:09
Copy link
Contributor

@shleewhite shleewhite left a comment

Choose a reason for hiding this comment

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

Just a couple small comments!

Copy link
Contributor

@didoo didoo left a comment

Choose a reason for hiding this comment

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

Left a few high-level comments

@onClickSort={{fn H.setSortBy "peer-name"}}
@sortOrder={{if (eq "peer-name" H.sortBy) H.sortOrder}}
>Peer name</H.ThSort>
{{#if H.setSortBy}}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] @didoo @shleewhite this is where the check for H.setSortBy is needed. In @onClickSort, setSortBy is called directly and because it is conditionally yielded it's possible it could be undefined.

@dchyun dchyun requested review from didoo and shleewhite August 6, 2025 13:05
shleewhite
shleewhite previously approved these changes Aug 6, 2025
Copy link
Contributor

@didoo didoo left a comment

Choose a reason for hiding this comment

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

Left a few comments.

Can you open the equivalent files from the AdvancedTable side by side, and compare the implementation there and here, to make sure they're as similar as possible? It's not nitpicking: this consistency will facilitate future code refactoring, debugging, reviews, etc.

Comment on lines +134 to +142
s1 instanceof Object &&
s2 instanceof Object &&
'status' in s1 &&
'status' in s2 &&
typeof s1['status'] === 'string' &&
typeof s2['status'] === 'string'
Copy link
Contributor

Choose a reason for hiding this comment

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

Ooof!

Copy link
Contributor

Choose a reason for hiding this comment

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

[question] at line 153 there is similar code (clonedModelClusters.sort) but it's not so "strictly typed" as here. Why in that case is not necessary, but here it is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The difference between this sorting function and others (like line 184 get sortedModelClusters__demo3()) is that this function is used in the sortingFunction column hash.

In the function I can type the parameters as MockDataCluster so s1['status'] is defined, but the problem is the parameters of the sortingFunction are typed as unknown so there is a type mismatch.

This implementation matches the example from the adv table so thinking to leave it as is for now.

Screenshot 2025-08-07 at 9 30 01 AM

@dchyun
Copy link
Contributor Author

dchyun commented Aug 7, 2025

Can you open the equivalent files from the AdvancedTable side by side, and compare the implementation there and here

@didoo Compared the adv table and table files and aligned in a few places to the adv table. Nothing major, but should be aligned for all similar functions now.

@dchyun dchyun requested review from didoo and shleewhite August 7, 2025 13:57
@didoo
Copy link
Contributor

didoo commented Aug 7, 2025

@dchyun since #3074 is practically ready to be merged (only a couple of tiny things left to fix) do you think it would make sense to rebase you branch on that PR's branch, and use the data sources (and data types) from that PR? I think it could simplify this PR and improve even more the consistency between Table and AdvancedTable migrated code

@dchyun
Copy link
Contributor Author

dchyun commented Aug 7, 2025

@dchyun since #3074 is practically ready to be merged (only a couple of tiny things left to fix) do you think it would make sense to rebase you branch on that PR's branch, and use the data sources (and data types) from that PR? I think it could simplify this PR and improve even more the consistency between Table and AdvancedTable migrated code

@didoo Yes that was my intention to wait for the data reorg to go in before rebasing and merging this. I agree it should simplify things a lot.

selectAllState: boolean,
) => {
modelData.forEach((modelRow) => {
if (modelRow instanceof Object && 'isSelected' in modelRow) {
if (modelRow instanceof Object) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] The userData data doesn't have isSelected set, so this check was breaking the "delete row" example's "expand scope" toggle, which used the userData and this function. The type has been updated to be more specific to ensure modelRow.isSelected is available.

@@ -42,7 +41,6 @@ export default class PageComponentsAdvancedTableRoute extends Route {
userDataDemo4: clone(
users.slice(0, 4).map((user) => ({ ...user, isAnimated: false })),
),
manyColumns: userWithMoreColumns,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[Note] This data didn't appear to be being used anywhere in the adv table so I've removed it from the model

Copy link
Contributor

@shleewhite shleewhite left a comment

Choose a reason for hiding this comment

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

This is looking great!

@@ -10,6 +10,8 @@ import { deepTracked } from 'ember-deep-tracked';
import { later } from '@ember/runloop';

import type { PageComponentsAdvancedTableModel } from 'showcase/routes/page-components/advanced-table';
import type { SelectableItem } from 'showcase/mocks/selectable-item-data';
Copy link
Contributor

Choose a reason for hiding this comment

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

😎 nice

@@ -42,7 +41,6 @@ export default class PageComponentsAdvancedTableRoute extends Route {
userDataDemo4: clone(
users.slice(0, 4).map((user) => ({ ...user, isAnimated: false })),
),
manyColumns: userWithMoreColumns,
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for catching this! Didn't realize its not used in the template.

@dchyun dchyun merged commit 6cbe1b9 into main Aug 7, 2025
16 checks passed
@dchyun dchyun deleted the dchyun/table-showcase-ts-conversion branch August 7, 2025 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants