Skip to content

Commit

Permalink
feat: Improve display of group hierarchies on configurator overview (#…
Browse files Browse the repository at this point in the history
…12521)

Multi-level group hierarchies are now rendered in a way that visualizes parent-child relation between groups

Closes #12358
  • Loading branch information
Changsuwan authored Jun 11, 2021
1 parent bab6215 commit 6c3d3a4
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 75 deletions.
85 changes: 55 additions & 30 deletions docs/migration/css-changes-in-version-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,88 +4,113 @@ title: Changes to Styles in 4.0

## Changes in Checkout Components

* `cx-product-variants` selector has been moved to corresponding feature-lib `@spartacus/product`.
- `cx-product-variants` selector has been moved to corresponding feature-lib `@spartacus/product`.

## Change in Configurator Attribute Type Components

* `cx-quantity` selector has been added to achieve a consistent styling.
- `cx-quantity` selector has been added to achieve a consistent styling.

## Changes in Configurator Product Title Component

* `width` set to 80% on `%cx-configurator-product-title` to use only 80% of the configuration product title width.
- `width` set to 80% on `%cx-configurator-product-title` to use only 80% of the configuration product title width.

* `button` instead of the anchor link on `%cx-configurator-product-title`.
- `button` instead of the anchor link on `%cx-configurator-product-title`.

* `padding` set to 16px/ 32px on `%cx-configurator-product-title` for `cx-details` selector to align spacing depending on the screen size.
- `padding` set to 16px/ 32px on `%cx-configurator-product-title` for `cx-details` selector to align spacing depending on the screen size.

* `cx-configurator-image` mixin has been defined on `%cx-configurator-product-title` for `cx-details-image` selector to achieve a consistent styling.
- `cx-configurator-image` mixin has been defined on `%cx-configurator-product-title` for `cx-details-image` selector to achieve a consistent styling.

* `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-product-title` for `cx-detail-title`, `cx-code` and `cx-description` selectors to enable the truncation for the small widgets.
- `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-product-title` for `cx-detail-title`, `cx-code` and `cx-description` selectors to enable the truncation for the small widgets.

## Changes in Configurator Group Menu Component

* `cx-group-menu` class replace `ul` element on `%cx-configurator-group-menu`.

* `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-group-menu` for `span` selector to enable the configuration group title truncation for the small widgets.
- `cx-group-menu` class replaces `ul` element on `%cx-configurator-group-menu`.
- `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-group-menu` for `span` selector to enable the configuration group title truncation for the small widgets.

## Changes in Configurator Form Component

* `width` set to 100% on `%cx-configurator-form` to use the whole width of the configuration form.
- `width` set to 100% on `%cx-configurator-form` to use the whole width of the configuration form.

* `padding` set to 16px on `%cx-configurator-form` for `cx-group-attribute` to align the spacing between the configuration group attributes.
- `padding` set to 16px on `%cx-configurator-form` for `cx-group-attribute` to align the spacing between the configuration group attributes.

## Changes in Configurator Attribute Header Component

* `margin` set to 17px on `%cx-configurator-attribute-header` to align the spacing to the attribute header to the attribute type.
- `margin` set to 17px on `%cx-configurator-attribute-header` to align the spacing to the attribute header to the attribute type.

* `padding` set to 0px and `margin` to 17px on `%cx-configurator-attribute-type` to align the spacing between the configuration attribute types.
- `padding` set to 0px and `margin` to 17px on `%cx-configurator-attribute-type` to align the spacing between the configuration attribute types.

## Change in Configurator Attribute Drop-Down Component

* `padding` set to 1rem on `%cx-configurator-attribute-drop-down` for `cx-configurator-attribute-quantity` selector to define the spacing between the drop-down attribute type and the quantity counter.
- `padding` set to 1rem on `%cx-configurator-attribute-drop-down` for `cx-configurator-attribute-quantity` selector to define the spacing between the drop-down attribute type and the quantity counter.

## Change in Configurator Attribute Checkbox List Component

* `padding` set to 1rem on `%cx-configurator-attribute-checkbox-list` to define the spacing between the checkbox-list attribute type and the quantity counter.
- `padding` set to 1rem on `%cx-configurator-attribute-checkbox-list` to define the spacing between the checkbox-list attribute type and the quantity counter.

## Change in Configurator Attribute Radio Button Component

* `padding` set to 1rem on `%cx-configurator-attribute-radio-button` to define the spacing between the radio-button attribute type and the quantity counter.
- `padding` set to 1rem on `%cx-configurator-attribute-radio-button` to define the spacing between the radio-button attribute type and the quantity counter.

## Change in Configurator Previous Next Button Component

* `padding` set to 16px on `%cx-configurator-previous-next-buttons` to align the spacing between the configuration form and the bottom of the configuration.
- `padding` set to 16px on `%cx-configurator-previous-next-buttons` to align the spacing between the configuration form and the bottom of the configuration.

## Change in Configurator Price Summary Component

* `padding` set to 16px on `%cx-configurator-price-summary` for cx-total-summary selector to align the spacing.
- `padding` set to 16px on `%cx-configurator-price-summary` for cx-total-summary selector to align the spacing.

## Change in Configurator Footer Container Mixin

* `padding` set to 16px on `%cx-configurator-footer-container` mixin to align the spacing between the price summary and add-to-cart button.
- `padding` set to 16px on `%cx-configurator-footer-container` mixin to align the spacing between the price summary and add-to-cart button.

## Change in Configurator Required Error Message Mixin

* `padding` set to 5px on `%cx-configurator-required-error-msg` mixin to add the spacing at the end of the cx-icon selector.
- `padding` set to 5px on `%cx-configurator-required-error-msg` mixin to add the spacing at the end of the cx-icon selector.

## Changes in Configurator Overview Form Component

* `padding` set to 0px on `%cx-configurator-overview-form` to fix inconsistent spacings in the configuration overview form.
- `padding` set to 0px on `%cx-configurator-overview-form` to fix inconsistent spacings in the configuration overview form.

* `padding` set to 20px and `margin` to 0px on `%cx-configurator-overview-form` for `cx-group` selector to align spacing between the configuration overview groups.
- `padding` set to 20px and `margin` to 0px on `%cx-configurator-overview-form` for `cx-group` selector to align spacing between the configuration overview groups.

* `padding` set to 32px/16px on `%cx-configurator-overview-form` for `h2` selector to align spacing around the configuration overview group titles.
- `padding` set to 32px/16px on `%cx-configurator-overview-form` for `h2` selector to align spacing around the configuration overview group titles.

* `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-overview-form` for `span` selector to enable the overview group title truncation for the small widgets.
- `cx-configurator-truncate-content` mixin has been added on `%cx-configurator-overview-form` for `span` selector to enable the overview group title truncation for the small widgets.

* `padding` set to 32px on `%cx-configurator-overview-form` for `cx-attribute-value-pair` selector to align spacing between the configuration overview attribute value pairs.
- `padding` set to 32px on `%cx-configurator-overview-form` for `cx-attribute-value-pair` selector to align spacing between the configuration overview attribute value pairs.

* `display` set to `none / inline` and `visibility` to `hidden` on `%cx-configurator-overview-form` for `cx-attribute-value-pair` selector to define the visibility for the configuration overview attribute value label.
- `display` set to `none / inline` and `visibility` to `hidden` on `%cx-configurator-overview-form` for `cx-attribute-value-pair` selector to define the visibility for the configuration overview attribute value label.

* `padding` set to 20px on `%cx-configurator-overview-form` for `cx-no-attribute-value-pairs` selector to align spacing between the configuration overview form and the container which is shown when there are no results including a link for removing filter(s).
- `padding` set to 20px on `%cx-configurator-overview-form` for `cx-no-attribute-value-pairs` selector to align spacing between the configuration overview form and the container which is shown when there are no results including a link for removing filter(s).

- `font-size` set to 1.25rem on `%cx-configurator-overview-form` for `topLevel` selector to adjust the attribute header according to the new styling requirement

- `font-weight` set to 700 on `%cx-configurator-overview-form` for `topLevel` selector to adjust the attribute header according to the new styling requirement

- `border-bottom` set to solid 1px var(--cx-color-light) on `%cx-configurator-overview-form` for `topLevel` selector to create the bottom border of the attribute header

- `border-top` set to solid 1px var(--cx-color-light) on `%cx-configurator-overview-form` for `topLevel` selector to create the top border of the attribute header

- `border-left-style` set to none on `%cx-configurator-overview-form` for `topLevel` selector to achieve top-bottom border

- `border-right-style` set to none on `%cx-configurator-overview-form` for `topLevel` selector to achieve top-bottom border

- `background` set to none on `%cx-configurator-overview-form` for `topLevel` to make the header background transparent

- `text-transform` set to none on `%cx-configurator-overview-form` for `topLevel` to prevent the header form transforming to uppercase

- `margin-bottom` set to -60px on `%cx-configurator-overview-form` for `subgroupTopLevel` to eliminate the space between the top-level attribute header and its subgroups

- `background-color` set to var(--cx-color-background) on `%cx-configurator-overview-form` for `cx-group h2` to set the background color of the subgroup headers

- `font-size` set to 1rem on `%cx-configurator-overview-form` for `cx-group h2` to specify the font size of the subgroup headers

- `text-transform` set to uppercase on `%cx-configurator-overview-form` for `cx-group h2` to transform the subgroup header into uppercase

## Changes in Configurator Overview Attribute Component

* `width` set to 40% on `%cx-configurator-overview-attribute` for `cx-attribute-value` selector to use only 40% of the width for the small widgets.
- `width` set to 40% on `%cx-configurator-overview-attribute` for `cx-attribute-value` selector to use only 40% of the width for the small widgets.

- `width` set to 60% on `%cx-configurator-overview-attribute` for `cx-attribute-label` selector to use only 60% of the width for the small widgets.

* `width` set to 60% on `%cx-configurator-overview-attribute` for `cx-attribute-label` selector to use only 60% of the width for the small widgets.
- `font-weight` set to 600 on `%cx-configurator-overview-attribute` for `cx-attribute-value` to make the attribute values bold
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
<ng-container *ngIf="configuration$ | async as configuration">
<ng-container *ngIf="hasAttributes(configuration); else noAttributes">
<ng-container *ngFor="let group of configuration.overview.groups">
<div class="cx-group">
<h2>
<span>{{ group.groupDescription }}</span>
</h2>
<div
*ngFor="let attributeOverview of group.attributes; let i = index"
class="cx-attribute-value-pair"
[ngClass]="getStyleClasses(group.attributes, i)"
>
<ng-container [ngSwitch]="attributeOverview?.type">
<ng-container *ngSwitchCase="attributeOverviewType.GENERAL">
<cx-configurator-overview-attribute
[attributeOverview]="attributeOverview"
></cx-configurator-overview-attribute>
</ng-container>

<ng-container *ngSwitchCase="attributeOverviewType.BUNDLE">
<cx-configurator-cpq-overview-attribute
[attributeOverview]="attributeOverview"
></cx-configurator-cpq-overview-attribute>
</ng-container>

<ng-container *ngSwitchDefault>
<cx-configurator-overview-attribute
[attributeOverview]="attributeOverview"
></cx-configurator-overview-attribute>
</ng-container>
</ng-container>
</div>
</div>
</ng-container>
<ng-container
*ngTemplateOutlet="
groups;
context: {
overviewGroups: configuration.overview.groups,
level: 1
}
"
></ng-container>
</ng-container>
</ng-container>

Expand All @@ -42,3 +19,54 @@ <h2>{{ 'configurator.overviewForm.noAttributeHeader' | cxTranslate }}</h2>
<p>{{ 'configurator.overviewForm.noAttributeText' | cxTranslate }}</p>
</div>
</ng-template>

<ng-template #groups let-overviewGroups="overviewGroups" let-level="level">
<ng-container *ngFor="let group of overviewGroups">
<div
class="cx-group"
[class.topLevel]="level === 1"
[class.subgroupTopLevel]="level === 1 && group.subGroups?.length > 0"
>
<h2>
<span>{{ group.groupDescription }}</span>
</h2>

<div
*ngFor="let attributeOverview of group.attributes; let i = index"
class="cx-attribute-value-pair"
[ngClass]="getStyleClasses(group.attributes, i)"
>
<ng-container [ngSwitch]="attributeOverview?.type">
<ng-container *ngSwitchCase="attributeOverviewType.GENERAL">
<cx-configurator-overview-attribute
[attributeOverview]="attributeOverview"
>
</cx-configurator-overview-attribute>
</ng-container>

<ng-container *ngSwitchCase="attributeOverviewType.BUNDLE">
<cx-configurator-cpq-overview-attribute
[attributeOverview]="attributeOverview"
>
</cx-configurator-cpq-overview-attribute>
</ng-container>

<ng-container *ngSwitchDefault>
<cx-configurator-overview-attribute
[attributeOverview]="attributeOverview"
>
</cx-configurator-overview-attribute>
</ng-container>
</ng-container>
</div>
</div>
<ng-container *ngIf="group.subGroups?.length > 0">
<ng-container
*ngTemplateOutlet="
groups;
context: { overviewGroups: group.subGroups, level: level + 1 }
"
></ng-container>
</ng-container>
</ng-container>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export namespace Configurator {
id: string;
groupDescription?: string;
attributes?: AttributeOverview[];
subGroups?: GroupOverview[];
}

export interface AttributeOverview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ const convertedOverview: Configurator.Overview = {
value: 'V1',
},
],
},
{
id: '11',
groupDescription: undefined,
attributes: [],
subGroups: [
{
id: '11',
groupDescription: undefined,
attributes: [],
},
],
},
{
id: '2',
Expand Down Expand Up @@ -74,16 +76,17 @@ Object.freeze(group3);
const subGroups: OccConfigurator.GroupOverview[] = [group3];
Object.freeze(subGroups);

const subgroup: OccConfigurator.GroupOverview = { id: '11' };
const group1: OccConfigurator.GroupOverview = {
id: '1',
groupDescription: groupDescription,
subGroups: [{ id: '11' }],
characteristicValues: [
{
characteristic: 'C1',
value: 'V1',
},
],
subGroups: [subgroup],
};
Object.freeze(group1);

Expand Down Expand Up @@ -158,7 +161,7 @@ describe('OccConfiguratorVariantNormalizer', () => {

it('should cover sub groups', () => {
const result = occConfiguratorVariantOverviewNormalizer.convert(overview);
expect(result.groups.length).toBe(3);
expect(result.groups?.length).toBe(2);
});

it('should be able to handle groups without attributes', () => {
Expand All @@ -181,7 +184,31 @@ describe('OccConfiguratorVariantNormalizer', () => {
const result = occConfiguratorVariantOverviewNormalizer.convertGroup(
groupWithSubgroups
);
expect(result.length).toBe(5);
expect(result.length).toBe(1);
});

it('should fill subgroups in the target model accross 3 levels', () => {
const thirdLevelGroup: OccConfigurator.GroupOverview = {};
const secondLevelGroup: OccConfigurator.GroupOverview = {
subGroups: [thirdLevelGroup],
};
const groupWithSubgroups: OccConfigurator.GroupOverview = {
subGroups: [group1, group3, secondLevelGroup],
};

const result = occConfiguratorVariantOverviewNormalizer.convertGroup(
groupWithSubgroups
);
const rootGroup = result[0];
expect(rootGroup).toBeDefined();
const subGroups = rootGroup.subGroups;
if (subGroups) {
expect(subGroups.length).toBe(3);
const secondLevelGroupInResult = subGroups[2];
expect(secondLevelGroupInResult.subGroups?.length).toBe(1);
} else {
fail();
}
});
it('should set description for a general group', () => {
const generalTargetGroup: Configurator.GroupOverview = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ export class OccConfiguratorVariantOverviewNormalizer
const characteristicValues: OccConfigurator.CharacteristicOverview[] =
source.characteristicValues;
const subGroups: OccConfigurator.GroupOverview[] = source.subGroups;

result.push({
const group: Configurator.GroupOverview = {
id: source.id,
groupDescription: source.groupDescription,
attributes: characteristicValues
Expand All @@ -55,15 +54,18 @@ export class OccConfiguratorVariantOverviewNormalizer
};
})
: [],
});
this.setGeneralDescription(result[0]);
};

this.setGeneralDescription(group);
if (subGroups) {
group.subGroups = [];
subGroups.forEach((subGroup) =>
this.convertGroup(subGroup).forEach((groupArray) =>
result.push(groupArray)
group.subGroups.push(groupArray)
)
);
}
result.push(group);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

.cx-attribute-value {
width: 100%;
font-weight: 600;

@include media-breakpoint-up(md) {
width: 41.6666666667%;
Expand Down
Loading

0 comments on commit 6c3d3a4

Please sign in to comment.