Skip to content

Commit

Permalink
refactor: renamed value to itemValue in dbxValueListItem
Browse files Browse the repository at this point in the history
BREAKING CHANGE: renamed value to itemValue to better avoid issues when using DbxValueAsListItem values

- Added DbxValueAsListItem type for those use cases
  • Loading branch information
dereekb committed Apr 22, 2022
1 parent afcc824 commit 3441129
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class DocCustomItemListViewComponent extends AbstractDbxListViewDirective

readonly config: DbxValueListViewConfig<DocValueWithSelection> = {
componentClass: DocCustomItemListViewItemComponent,
mapValuesToItemValues: (x) => of(x.map((y) => ({ ...y, icon: y.icon, value: y })))
mapValuesToItemValues: (x) => of(x.map((y) => ({ ...y, icon: y.icon, itemValue: y })))
};

}
Expand All @@ -43,7 +43,7 @@ export class DocCustomItemListViewComponent extends AbstractDbxListViewDirective
template: `
<div class="pad-3">
<h4 class="no-margin">{{ anchorType }}</h4>
<p>{{ value.name }}</p>
<p>{{ name }}</p>
</div>
`
})
Expand All @@ -55,4 +55,8 @@ export class DocCustomItemListViewItemComponent extends AbstractDbxValueListView
return AnchorType[anchorTypeForAnchor(this.item.anchor)];
}

get name() {
return this.itemValue.name;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ export class DocSelectionItemListViewComponent extends AbstractDbxSelectionListV

readonly config: DbxSelectionValueListViewConfig<DocValueWithSelection> = {
componentClass: DocSelectionItemListViewItemComponent,
mapValuesToItemValues: (x) => of(x.map((y) => ({ ...y, icon: y.icon, value: y })))
mapValuesToItemValues: (x) => of(x.map((y) => ({ ...y, icon: y.icon, itemValue: y })))
};

}

@Component({
template: `
<div class="pad-3">
<h5 class="no-margin pad-0">{{ value.name }}</h5>
<h5 class="no-margin pad-0">{{ name }}</h5>
<div>{{ lorem }}</div>
</div>
`
Expand All @@ -47,4 +47,8 @@ export class DocSelectionItemListViewItemComponent extends AbstractDbxValueListV

readonly lorem = LOREM;

get name() {
return this.itemValue.name;
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DbxValueListItem } from "@dereekb/dbx-web";
import { DbxValueAsListItem } from "@dereekb/dbx-web";

export interface DocValue {
name: string;
icon: string;
}

export type DocValueWithSelection = DocValue & Omit<DbxValueListItem<DocValue>, 'value'>;
export type DocValueWithSelection = DbxValueAsListItem<DocValue>;
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export class DocLayoutListComponent implements OnInit, OnDestroy {

readonly stateWithSelection$: Observable<ListLoadingState<DocValueWithSelection>> = this.state$.pipe(
map((x) => mapLoadingStateResults<DocValue[], DocValueWithSelection[]>(x, {
mapValue: ((values) => values.map((x) => ({ ...x, selected: Math.random() > 0.5, disabled: Math.random() > 0.8 })))
mapValue: ((values) => values.map((x: DocValue) => {
const item: DocValueWithSelection = ({ ...x, selected: Math.random() > 0.5, disabled: Math.random() > 0.8 });
return item;
}))
}))
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<mat-chip-list [required]="required" [selectable]="!isReadonlyOrDisabled" #chipList>
<mat-chip *ngFor="let item of items$ | async" (click)="itemClicked(item)" [selected]="item.selected"
[disabled]="isReadonlyOrDisabled || item.disabled">
<span class="dbx-chip-label">{{ item.value.label }}</span>
<span class="dbx-chip-sublabel" *ngIf="item.value.sublabel">{{ item.value.sublabel }}</span>
<span class="dbx-chip-label">{{ item.itemValue.label }}</span>
<span class="dbx-chip-sublabel" *ngIf="item.itemValue.sublabel">{{ item.itemValue.sublabel }}</span>
</mat-chip>
</mat-chip-list>
<dbx-injection [config]="footerConfig"></dbx-injection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export class DbxPickableChipListFieldComponent<T> extends AbstractDbxPickableIte
itemClicked(item: PickableItemFieldItem<T>): void {
if (!item.disabled && !this.isReadonlyOrDisabled) {
if (item.selected) {
this.removeValue(item.value.value);
this.removeValue(item.itemValue.value);
} else {
this.addValue(item.value.value);
this.addValue(item.itemValue.value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export class AbstractDbxPickableItemFieldDirective<T> extends FieldType<Pickable
readonly items$: Observable<PickableItemFieldItem<T>[]> = combineLatest([this.filteredSearchResults$, this.values$]).pipe(
map(([displayValues, values]) => {
const selectedHashValuesSet = new Set(values.map(x => this.hashForValue(x)));
let items: PickableItemFieldItem<T>[] = displayValues.map((x) => ({ value: x, selected: selectedHashValuesSet.has(x._hash) }));
let items: PickableItemFieldItem<T>[] = displayValues.map((x) => ({ itemValue: x, selected: selectedHashValuesSet.has(x._hash) }));

if (this.sortItems) {
items = this.sortItems(items);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function filterPickableItemFieldValuesByLabel<T>(filterText: Maybe<string
}

export function sortPickableItemsByLabel<T>(chips: PickableItemFieldItem<T>[]): PickableItemFieldItem<T>[] {
return chips.sort((a, b) => a.value.label.localeCompare(b.value.label));
return chips.sort((a, b) => a.itemValue.label.localeCompare(b.itemValue.label));
}

export interface PickableItemFieldConfig<T = any> extends LabeledFieldConfig, PickableValueFieldsFieldConfig<T> { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class DbxPickableListFieldComponent<T> extends AbstractDbxPickableItemFie

onSelectionChange(event: unknown) {
const items = (event as ListSelectionState<PickableValueFieldDisplayValue<T>>).items;
const values = items.map(x => x.value.value);
const values = items.map(x => x.itemValue.value);
this.setValues(values);
}

Expand Down Expand Up @@ -84,7 +84,7 @@ export class DbxPickableListFieldItemListViewComponent<T> extends AbstractDbxSel
export class DbxPickableListFieldItemListViewItemComponent<T> extends AbstractDbxValueListViewItemComponent<PickableValueFieldDisplayValue<T>> {

get label(): string {
return this.value.label;
return this.itemValue.label;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export abstract class AbstractDbxSelectionListViewDirective<T> extends AbstractD
matSelectionChanged(selection: MatSelectionListChange): void {
const options = selection.source.selectedOptions.selected;
const items: ListSelectionStateItem<T>[] = options.map(x => {
const { value, selected, disabled } = x;
return ({ value, selected, disabled });
const { value: itemValue, selected, disabled } = x;
return ({ itemValue, selected, disabled });
});

this.selectionChanged({ items });
Expand Down
2 changes: 1 addition & 1 deletion packages/dbx-web/src/lib/layout/list/list.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type DbxListSelectionMode = 'select' | 'view';
export interface ListSelectionStateItem<T> {
disabled?: boolean;
selected?: boolean;
value: T;
itemValue: T;
}

export interface ListSelectionState<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class DbxValueListItemViewComponent<T> {

if (this.emitAllClicks || !item.anchor || anchorTypeForAnchor(item.anchor) === AnchorType.PLAIN) {
// only emit clicks for items with no anchor, or plain anchors.
this.onClickValue(item.value);
this.onClickValue(item.itemValue);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { DbxValueListItem, DBX_VALUE_LIST_VIEW_ITEM } from "./list.view.value";
@Directive()
export abstract class AbstractDbxValueListViewItemComponent<T, I extends DbxValueListItem<T> = DbxValueListItem<T>> {

get value() {
return this.item.value;
get itemValue() {
return this.item.itemValue;
}

constructor(@Inject(DBX_VALUE_LIST_VIEW_ITEM) readonly item: I) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class DbxSelectionValueListViewComponent<T, I extends DbxValueListItem<T>
</ng-container>
<ng-container *ngSwitchDefault>
<mat-selection-list [disabled]="disabled$ | async" [multiple]="multiple" (selectionChange)="matSelectionChanged($event)">
<mat-list-option class="dbx-list-view-item" *ngFor="let item of items" [selected]="item.selected" [disabled]="item.disabled" [value]="item.value" (click)="onClickValue(item.value)">
<mat-list-option class="dbx-list-view-item" *ngFor="let item of items" [selected]="item.selected" [disabled]="item.disabled" [value]="item.itemValue" (click)="onClickValue(item.itemValue)">
<mat-icon matListIcon *ngIf="item.icon">{{ item.icon }}</mat-icon>
<div dbx-injection [config]="item.config"></div>
</mat-list-option>
Expand Down Expand Up @@ -71,8 +71,8 @@ export class DbxSelectionValueListItemViewComponent<T> extends DbxValueListItemV
matSelectionChanged(selection: MatSelectionListChange): void {
const options = selection.source.selectedOptions.selected;
const items: ListSelectionStateItem<T>[] = options.map(x => {
const { value, selected, disabled } = x;
return ({ value, selected, disabled });
const { value: itemValue, selected, disabled } = x;
return ({ itemValue, selected, disabled });
});

this.dbxListView.selectionChange!.next({
Expand Down
38 changes: 21 additions & 17 deletions packages/dbx-web/src/lib/layout/list/list.view.value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,54 @@ import { map, Observable, of } from "rxjs";
export const DBX_VALUE_LIST_VIEW_ITEM = new InjectionToken<any>('DbxValueListViewItem');

export interface DbxValueListItem<T> {
value: T; // todo: rename to data
itemValue: T; // todo: rename to itemValue
icon?: string;
disabled?: boolean;
selected?: boolean;
anchor?: ClickableAnchor;
}

/**
* Special type used with values that contain all the items of DbxValueListItem internally.
*/
export type DbxValueAsListItem<T> = T & Omit<DbxValueListItem<DbxValueListItem<T>>, 'itemValue'>;

export interface AbstractDbxValueListViewConfig<T, I extends DbxValueListItem<T> = DbxValueListItem<T>, V = any> extends DbxInjectionComponentConfig<V> {
mapValuesToItemValues?(values: T[]): Observable<I[]>;
}

export const DEFAULT_DBX_VALUE_LIST_CONFIG_MAP_VALUES = <T, I extends DbxValueListItem<T>>(values: T[]) => of(values.map(value => ({ value })) as I[]);
export const DEFAULT_DBX_VALUE_LIST_CONFIG_MAP_VALUES = <T, I extends DbxValueListItem<T>>(itemValues: T[]) => of(itemValues.map(itemValue => ({ itemValue })) as I[]);

export interface DbxValueListItemConfig<T> extends DbxValueListItem<T> {
config: DbxInjectionComponentConfig;
}

export function mapValuesToValuesListItemConfigObs<T>(listViewConfig: AbstractDbxValueListViewConfig<T>, values: T[]): Observable<DbxValueListItemConfig<T>[]> {
return (listViewConfig.mapValuesToItemValues ?? DEFAULT_DBX_VALUE_LIST_CONFIG_MAP_VALUES)(values).pipe(
map((itemValues) => {
const items: DbxValueListItemConfig<T>[] = mapItemValuesToValueListItemConfig(listViewConfig, itemValues);
return items;
export function mapValuesToValuesListItemConfigObs<T>(listViewConfig: AbstractDbxValueListViewConfig<T>, itemValues: T[]): Observable<DbxValueListItemConfig<T>[]> {
return (listViewConfig.mapValuesToItemValues ?? DEFAULT_DBX_VALUE_LIST_CONFIG_MAP_VALUES)(itemValues).pipe(
map((listItems) => {
const listItemConfigs: DbxValueListItemConfig<T>[] = mapItemValuesToValueListItemConfig(listViewConfig, listItems);
return listItemConfigs;
})
);
}

export function mapItemValuesToValueListItemConfig<T>(listViewConfig: AbstractDbxValueListViewConfig<T>, itemValues: DbxValueListItem<T>[]): DbxValueListItemConfig<T>[] {
return itemValues.map((itemValue) => {
const anchor = itemValue.anchor;
const disabled = itemValue.disabled || anchor?.disabled;
export function mapItemValuesToValueListItemConfig<T>(listViewConfig: AbstractDbxValueListViewConfig<T>, listItmes: DbxValueListItem<T>[]): DbxValueListItemConfig<T>[] {
return listItmes.map((listItem) => {
const anchor = listItem.anchor;
const disabled = listItem.disabled || anchor?.disabled;

return {
value: itemValue.value,
icon: itemValue.icon,
selected: itemValue.selected,
itemValue: listItem.itemValue,
icon: listItem.icon,
selected: listItem.selected,
disabled,
anchor: itemValue.anchor,
anchor: listItem.anchor,
config: Object.assign({
providers: [{
provide: DBX_VALUE_LIST_VIEW_ITEM,
useValue: itemValue
useValue: listItem
}] as StaticProvider[]
}, listViewConfig)
}
});
}

0 comments on commit 3441129

Please sign in to comment.