Skip to content

Commit

Permalink
feat(admin-ui): Enable selection of content language from list views
Browse files Browse the repository at this point in the history
Relates to #883
  • Loading branch information
michaelbromley committed Jun 28, 2021
1 parent 680b8c2 commit eb9cb4f
Show file tree
Hide file tree
Showing 19 changed files with 224 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
<vdr-action-bar>
<vdr-ab-left>
<clr-checkbox-wrapper class="expand-all-toggle ml3">
<input type="checkbox" clrCheckbox [(ngModel)]="expandAll" />
<label>{{ 'catalog.expand-all-collections' | translate }}</label>
</clr-checkbox-wrapper>
<div class="flex center wrap">
<vdr-language-selector
class="mt2"
[availableLanguageCodes]="availableLanguages$ | async"
[currentLanguageCode]="contentLanguage$ | async"
(languageCodeChange)="setLanguage($event)"
></vdr-language-selector>
<clr-checkbox-wrapper
class="expand-all-toggle ml3"
[ngClass]="(availableLanguages$ | async)?.length === 1 ? 'mt3' : 'mt1'"
>
<input type="checkbox" clrCheckbox [(ngModel)]="expandAll" />
<label>{{ 'catalog.expand-all-collections' | translate }}</label>
</clr-checkbox-wrapper>
</div>
</vdr-ab-left>
<vdr-ab-right>
<vdr-action-bar-items locationId="collection-list"></vdr-action-bar-items>
<a class="btn btn-primary" *vdrIfPermissions="['CreateCatalog', 'CreateCollection']" [routerLink]="['./create']">
<a
class="btn btn-primary"
*vdrIfPermissions="['CreateCatalog', 'CreateCollection']"
[routerLink]="['./create']"
>
<clr-icon shape="plus"></clr-icon>
{{ 'catalog.create-new-collection' | translate }}
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

.expand-all-toggle {
display: block;
margin-top: 14px;
}

.collection-wrapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
DataService,
GetCollectionList,
LanguageCode,
ModalService,
NotificationService,
QueryResult,
ServerConfigService,
} from '@vendure/admin-ui/core';
import { combineLatest, EMPTY, Observable } from 'rxjs';
import { distinctUntilChanged, map, shareReplay, switchMap, take } from 'rxjs/operators';
import { distinctUntilChanged, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';

import { RearrangeEvent } from '../collection-tree/collection-tree.component';

Expand All @@ -23,6 +25,8 @@ export class CollectionListComponent implements OnInit, OnDestroy {
activeCollectionId$: Observable<string | null>;
activeCollectionTitle$: Observable<string>;
items$: Observable<GetCollectionList.Items[]>;
availableLanguages$: Observable<LanguageCode[]>;
contentLanguage$: Observable<LanguageCode>;
expandAll = false;
private queryResult: QueryResult<any>;

Expand All @@ -32,6 +36,7 @@ export class CollectionListComponent implements OnInit, OnDestroy {
private modalService: ModalService,
private router: Router,
private route: ActivatedRoute,
private serverConfigService: ServerConfigService,
) {}

ngOnInit() {
Expand All @@ -51,6 +56,11 @@ export class CollectionListComponent implements OnInit, OnDestroy {
return '';
}),
);
this.availableLanguages$ = this.serverConfigService.getAvailableLanguages();
this.contentLanguage$ = this.dataService.client
.uiState()
.mapStream(({ uiState }) => uiState.contentLanguage)
.pipe(tap(() => this.refresh()));
}

ngOnDestroy() {
Expand Down Expand Up @@ -109,6 +119,10 @@ export class CollectionListComponent implements OnInit, OnDestroy {
this.router.navigate(['./', params], { relativeTo: this.route, queryParamsHandling: 'preserve' });
}

setLanguage(code: LanguageCode) {
this.dataService.client.setContentLanguage(code).subscribe();
}

private refresh() {
this.queryResult.ref.refetch();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<vdr-action-bar>
<vdr-ab-left>
<vdr-language-selector
[availableLanguageCodes]="availableLanguages$ | async"
[currentLanguageCode]="contentLanguage$ | async"
(languageCodeChange)="setLanguage($event)"
></vdr-language-selector>
</vdr-ab-left>
<vdr-ab-right>
<vdr-action-bar-items locationId="facet-list"></vdr-action-bar-items>
<a class="btn btn-primary"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BaseListComponent } from '@vendure/admin-ui/core';
import { BaseListComponent, LanguageCode, ServerConfigService } from '@vendure/admin-ui/core';
import { DeletionResult, GetFacetList } from '@vendure/admin-ui/core';
import { NotificationService } from '@vendure/admin-ui/core';
import { DataService } from '@vendure/admin-ui/core';
import { ModalService } from '@vendure/admin-ui/core';
import { EMPTY } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { EMPTY, Observable } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';

@Component({
selector: 'vdr-facet-list',
templateUrl: './facet-list.component.html',
styleUrls: ['./facet-list.component.scss'],
})
export class FacetListComponent extends BaseListComponent<GetFacetList.Query, GetFacetList.Items> {
export class FacetListComponent
extends BaseListComponent<GetFacetList.Query, GetFacetList.Items>
implements OnInit {
availableLanguages$: Observable<LanguageCode[]>;
contentLanguage$: Observable<LanguageCode>;
readonly initialLimit = 3;
displayLimit: { [id: string]: number } = {};
constructor(
private dataService: DataService,
private modalService: ModalService,
private notificationService: NotificationService,
private serverConfigService: ServerConfigService,
router: Router,
route: ActivatedRoute,
) {
Expand All @@ -31,6 +36,15 @@ export class FacetListComponent extends BaseListComponent<GetFacetList.Query, Ge
);
}

ngOnInit() {
super.ngOnInit();
this.availableLanguages$ = this.serverConfigService.getAvailableLanguages();
this.contentLanguage$ = this.dataService.client
.uiState()
.mapStream(({ uiState }) => uiState.contentLanguage)
.pipe(tap(() => this.refresh()));
}

toggleDisplayLimit(facet: GetFacetList.Items) {
if (this.displayLimit[facet.id] === facet.values.length) {
this.displayLimit[facet.id] = this.initialLimit;
Expand Down Expand Up @@ -69,6 +83,10 @@ export class FacetListComponent extends BaseListComponent<GetFacetList.Query, Ge
);
}

setLanguage(code: LanguageCode) {
this.dataService.client.setContentLanguage(code).subscribe();
}

private showModalAndDelete(facetId: string, message?: string) {
return this.modalService
.dialog({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@
</vdr-dropdown-menu>
</vdr-dropdown>
</div>
<clr-checkbox-wrapper>
<input type="checkbox" clrCheckbox [(ngModel)]="groupByProduct" />
<label>{{ 'catalog.group-by-product' | translate }}</label>
</clr-checkbox-wrapper>
<div class="flex wrap">
<clr-checkbox-wrapper class="mt2">
<input type="checkbox" clrCheckbox [(ngModel)]="groupByProduct"/>
<label>{{ 'catalog.group-by-product' | translate }}</label>
</clr-checkbox-wrapper>
<vdr-language-selector
[availableLanguageCodes]="availableLanguages$ | async"
[currentLanguageCode]="contentLanguage$ | async"
(languageCodeChange)="setLanguage($event)"
></vdr-language-selector>
</div>
</vdr-ab-left>
<vdr-ab-right>
<vdr-action-bar-items locationId="product-list"></vdr-action-bar-items>
Expand Down Expand Up @@ -58,7 +65,9 @@
[src]="asset | assetPreview:'tiny'"
/>
<ng-template #imagePlaceholder>
<div class="placeholder"><clr-icon shape="image" size="48"></clr-icon></div>
<div class="placeholder">
<clr-icon shape="image" size="48"></clr-icon>
</div>
</ng-template>
</div>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@ import {
DataService,
JobQueueService,
JobState,
LanguageCode,
LogicalOperator,
ModalService,
NotificationService,
SearchInput,
SearchProducts,
ServerConfigService,
} from '@vendure/admin-ui/core';
import { EMPTY, Observable } from 'rxjs';
import { delay, map, switchMap, take, takeUntil, withLatestFrom } from 'rxjs/operators';
import { EMPTY, Observable, of } from 'rxjs';
import {
delay,
distinctUntilChanged,
map,
shareReplay,
switchMap,
take,
takeUntil,
tap,
withLatestFrom,
} from 'rxjs/operators';

import { ProductSearchInputComponent } from '../product-search-input/product-search-input.component';

Expand All @@ -29,13 +41,16 @@ export class ProductListComponent
facetValueIds: string[] = [];
groupByProduct = true;
facetValues$: Observable<SearchProducts.FacetValues[]>;
availableLanguages$: Observable<LanguageCode[]>;
contentLanguage$: Observable<LanguageCode>;
@ViewChild('productSearchInputComponent', { static: true })
private productSearchInput: ProductSearchInputComponent;
constructor(
private dataService: DataService,
private modalService: ModalService,
private notificationService: NotificationService,
private jobQueueService: JobQueueService,
private serverConfigService: ServerConfigService,
router: Router,
route: ActivatedRoute,
) {
Expand Down Expand Up @@ -80,6 +95,11 @@ export class ProductListComponent
this.facetValues$.pipe(take(1), delay(100), withLatestFrom(fvids$)).subscribe(([__, ids]) => {
this.productSearchInput.setFacetValues(ids);
});
this.availableLanguages$ = this.serverConfigService.getAvailableLanguages();
this.contentLanguage$ = this.dataService.client
.uiState()
.mapStream(({ uiState }) => uiState.contentLanguage)
.pipe(tap(() => this.refresh()));
}

setSearchTerm(term: string) {
Expand Down Expand Up @@ -141,4 +161,8 @@ export class ProductListComponent
},
);
}

setLanguage(code: LanguageCode) {
this.dataService.client.setContentLanguage(code).subscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,21 @@ export abstract class BaseDetailComponent<Entity extends { id: string; updatedAt

init() {
this.entity$ = this.route.data.pipe(
switchMap((data) => (data.entity as Observable<Entity>).pipe(takeUntil(this.destroy$))),
tap((entity) => (this.id = entity.id)),
switchMap(data => (data.entity as Observable<Entity>).pipe(takeUntil(this.destroy$))),
tap(entity => (this.id = entity.id)),
shareReplay(1),
);
this.isNew$ = this.entity$.pipe(
map((entity) => entity.id === ''),
map(entity => entity.id === ''),
shareReplay(1),
);
this.languageCode$ = this.route.paramMap.pipe(
map((paramMap) => paramMap.get('lang')),
switchMap((lang) => {
map(paramMap => paramMap.get('lang')),
switchMap(lang => {
if (lang) {
return of(lang as LanguageCode);
} else {
return this.dataService.settings
.getActiveChannel()
.mapSingle((data) => data.activeChannel.defaultLanguageCode);
return this.dataService.client.uiState().mapSingle(data => data.uiState.contentLanguage);
}
}),
distinctUntilChanged(),
Expand All @@ -69,6 +67,7 @@ export abstract class BaseDetailComponent<Entity extends { id: string; updatedAt

setLanguage(code: LanguageCode) {
this.setQueryParam('lang', code);
this.dataService.client.setContentLanguage(code).subscribe();
}

canDeactivate(): boolean {
Expand Down
23 changes: 21 additions & 2 deletions packages/admin-ui/src/lib/core/src/common/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ export type Mutation = {
setActiveChannel: UserStatus;
setAsLoggedIn: UserStatus;
setAsLoggedOut: UserStatus;
setContentLanguage: LanguageCode;
setOrderCustomFields?: Maybe<Order>;
setUiLanguage: LanguageCode;
setUiTheme: Scalars['String'];
Expand Down Expand Up @@ -906,6 +907,11 @@ export type MutationSetAsLoggedInArgs = {
};


export type MutationSetContentLanguageArgs = {
languageCode: LanguageCode;
};


export type MutationSetOrderCustomFieldsArgs = {
input: UpdateOrderInput;
};
Expand Down Expand Up @@ -5022,6 +5028,7 @@ export type UserStatus = {
export type UiState = {
__typename?: 'UiState';
language: LanguageCode;
contentLanguage: LanguageCode;
theme: Scalars['String'];
};

Expand Down Expand Up @@ -5285,6 +5292,13 @@ export type SetUiLanguageMutationVariables = Exact<{

export type SetUiLanguageMutation = Pick<Mutation, 'setUiLanguage'>;

export type SetContentLanguageMutationVariables = Exact<{
languageCode: LanguageCode;
}>;


export type SetContentLanguageMutation = Pick<Mutation, 'setContentLanguage'>;

export type SetUiThemeMutationVariables = Exact<{
theme: Scalars['String'];
}>;
Expand Down Expand Up @@ -5313,7 +5327,7 @@ export type GetUiStateQueryVariables = Exact<{ [key: string]: never; }>;

export type GetUiStateQuery = { uiState: (
{ __typename?: 'UiState' }
& Pick<UiState, 'language' | 'theme'>
& Pick<UiState, 'language' | 'contentLanguage' | 'theme'>
) };

export type GetClientStateQueryVariables = Exact<{ [key: string]: never; }>;
Expand All @@ -5327,7 +5341,7 @@ export type GetClientStateQuery = { networkStatus: (
& UserStatusFragment
), uiState: (
{ __typename?: 'UiState' }
& Pick<UiState, 'language' | 'theme'>
& Pick<UiState, 'language' | 'contentLanguage' | 'theme'>
) };

export type SetActiveChannelMutationVariables = Exact<{
Expand Down Expand Up @@ -8629,6 +8643,11 @@ export namespace SetUiLanguage {
export type Mutation = SetUiLanguageMutation;
}

export namespace SetContentLanguage {
export type Variables = SetContentLanguageMutationVariables;
export type Mutation = SetContentLanguageMutation;
}

export namespace SetUiTheme {
export type Variables = SetUiThemeMutationVariables;
export type Mutation = SetUiThemeMutation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LocalStorageService } from '../../providers/local-storage/local-storage

export function getClientDefaults(localStorageService: LocalStorageService) {
const currentLanguage = localStorageService.get('uiLanguageCode') || getDefaultUiLanguage();
const currentContentLanguage = localStorageService.get('contentLanguageCode') || getDefaultUiLanguage();
const activeTheme = localStorageService.get('activeTheme') || 'default';
return {
networkStatus: {
Expand All @@ -22,6 +23,7 @@ export function getClientDefaults(localStorageService: LocalStorageService) {
} as GetUserStatus.UserStatus,
uiState: {
language: currentLanguage,
contentLanguage: currentContentLanguage,
theme: activeTheme,
__typename: 'UiState',
} as GetUiState.UiState,
Expand Down
Loading

0 comments on commit eb9cb4f

Please sign in to comment.