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

[web] Fix display of Wizards' StepList with hidden items #49734

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ export function StepItem<T>(props: {
return (
<StepsContainer active={isDone || isActive}>
<StepTitle>
<Bullet isDone={isDone} isActive={isActive} stepNumber={index + 1} />
<Bullet
isDone={isDone}
isActive={isActive}
stepNumber={props.view.displayIndex ?? index + 1}
/>
{props.view.title}
</StepTitle>
</StepsContainer>
Expand Down
8 changes: 6 additions & 2 deletions web/packages/teleport/src/components/Wizard/flow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ test('computeViewChildrenSize', async () => {
},
{
title: 'Banana',
hide: true,
},
];
expect(computeViewChildrenSize(nestedViews)).toBe(3);
expect(computeViewChildrenSize({ views: nestedViews })).toBe(3);
expect(
computeViewChildrenSize({ views: nestedViews, constrainToVisible: true })
).toBe(2);

const notNestedViews = [
{
Expand All @@ -54,7 +58,7 @@ test('computeViewChildrenSize', async () => {
title: 'Banana',
},
];
expect(computeViewChildrenSize(notNestedViews)).toBe(2);
expect(computeViewChildrenSize({ views: notNestedViews })).toBe(2);
});

test('addIndexToViews and rendering correct steps', async () => {
Expand Down
64 changes: 55 additions & 9 deletions web/packages/teleport/src/components/Wizard/flow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,61 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* BaseView is a recursive type representing a view in a Wizard flow.
*
* @template T - Any view-specific properties.
*/
export type BaseView<T> = T & {
/**
* Whether to hide the view from the list of views.
*/
hide?: boolean;
/**
* Current step index in the wizard.
*/
index?: number;
/**
* Current visible step index in the wizard (ignoring any hidden steps).
*/
displayIndex?: number;
kiosion marked this conversation as resolved.
Show resolved Hide resolved
/**
* Optional list of sub-views.
*/
views?: BaseView<T>[];
/**
* Title of this view in the wizard flow.
*/
title: string;
};

/**
* computeViewChildrenSize calculates how many children a view has, without counting the first
* child. This is because the first child shares the same index with its parent, so we don't
* need to count it as it's not taking up a new index
* need to count it as it's not taking up a new index.
*
* If `constrainToVisible` is true, then we only count the visible views.
*/
export function computeViewChildrenSize<T>(views: BaseView<T>[]) {
export function computeViewChildrenSize<T>({
views,
constrainToVisible = false,
}: {
views: BaseView<T>[];
constrainToVisible?: boolean;
}) {
let size = 0;
for (const view of views) {
if (constrainToVisible && view.hide) {
continue;
}

if (view.views) {
size += computeViewChildrenSize(view.views);
size += computeViewChildrenSize({
views: view.views,
constrainToVisible,
});
} else {
size += 1;
size++;
}
}

Expand All @@ -48,7 +84,8 @@ export function computeViewChildrenSize<T>(views: BaseView<T>[]) {
*/
export function addIndexToViews<T>(
views: BaseView<T>[],
index = 0
index = 0,
displayIndex = 1
): BaseView<T>[] {
const result: BaseView<T>[] = [];

Expand All @@ -60,11 +97,20 @@ export function addIndexToViews<T>(
};

if (view.views) {
copy.views = addIndexToViews(view.views, index);

index += computeViewChildrenSize(view.views);
copy.views = addIndexToViews(view.views, index, displayIndex);
index += computeViewChildrenSize({ views: view.views });
} else {
index += 1;
index++;
}

if (!view.hide) {
copy.displayIndex = displayIndex;
displayIndex += view.views
? computeViewChildrenSize({
views: view.views,
constrainToVisible: true,
})
: 1;
}

result.push(copy);
Expand Down
Loading