diff --git a/components/cascader/nz-cascader.component.html b/components/cascader/nz-cascader.component.html index 0d6bb8ce9c3..34e224e2b55 100644 --- a/components/cascader/nz-cascader.component.html +++ b/components/cascader/nz-cascader.component.html @@ -76,7 +76,7 @@ (click)="onOptionClick(option, i, $event)">
  • - {{ nzNotFoundContent || ('Select.notFoundContent' | nzI18n) }} +
  • diff --git a/components/cascader/nz-cascader.module.ts b/components/cascader/nz-cascader.module.ts index d6035d1bcaf..63b0432d49a 100644 --- a/components/cascader/nz-cascader.module.ts +++ b/components/cascader/nz-cascader.module.ts @@ -3,14 +3,14 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { NzI18nModule } from '../i18n/nz-i18n.module'; +import { NzEmptyModule } from '../empty/nz-empty.module'; import { NzIconModule } from '../icon/nz-icon.module'; import { NzInputModule } from '../input/nz-input.module'; import { NzCascaderOptionComponent } from './nz-cascader-li.component'; import { NzCascaderComponent } from './nz-cascader.component'; @NgModule({ - imports : [ CommonModule, FormsModule, OverlayModule, NzInputModule, NzIconModule, NzI18nModule ], + imports : [ CommonModule, FormsModule, OverlayModule, NzInputModule, NzIconModule, NzEmptyModule ], declarations: [ NzCascaderComponent, NzCascaderOptionComponent diff --git a/components/components.less b/components/components.less index 3cfb0b6caf9..55090ec4788 100644 --- a/components/components.less +++ b/components/components.less @@ -15,6 +15,7 @@ @import "./divider/style/index.less"; @import "./drawer/style/index"; @import "./dropdown/style/index.less"; +@import "./empty/style/index.less"; @import "./form/style/index.less"; @import "./grid/style/index.less"; @import "./input/style/index.less"; @@ -50,4 +51,4 @@ @import "./cascader/style/index.less"; @import "./tree/style/index.less"; @import "./tree-select/style/index.less"; -@import "./calendar/style/index.less"; \ No newline at end of file +@import "./calendar/style/index.less"; diff --git a/components/empty/demo/basic.md b/components/empty/demo/basic.md new file mode 100644 index 00000000000..60dcec80351 --- /dev/null +++ b/components/empty/demo/basic.md @@ -0,0 +1,16 @@ +--- +order: 0 +title: + zh-CN: 基本 + en-US: Basic +--- + +## zh-CN + +简单的展示。 + +## en-US + +Simplest usage. + + diff --git a/components/empty/demo/basic.ts b/components/empty/demo/basic.ts new file mode 100644 index 00000000000..a7b33ec84d7 --- /dev/null +++ b/components/empty/demo/basic.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-empty-basic', + template: ` + `, + styles : [] +}) +export class NzDemoEmptyBasicComponent { +} diff --git a/components/empty/demo/config.md b/components/empty/demo/config.md new file mode 100644 index 00000000000..15f2aa5aaee --- /dev/null +++ b/components/empty/demo/config.md @@ -0,0 +1,16 @@ +--- +order: 2 +title: + zh-CN: 全局化配置 + en-US: Default Config +--- + +## zh-CN + +自定义全局组件的 Empty 样式。 + +## en-US + +Use `NzEmptyService` set global Empty style. + + diff --git a/components/empty/demo/config.ts b/components/empty/demo/config.ts new file mode 100644 index 00000000000..bef481528d6 --- /dev/null +++ b/components/empty/demo/config.ts @@ -0,0 +1,100 @@ +import { ChangeDetectorRef, Component, TemplateRef, ViewChild } from '@angular/core'; +import { NzEmptyService } from 'ng-zorro-antd'; + +@Component({ + selector: 'nz-demo-empty-config', + template: ` + + + + + +

    Select

    + + +

    TreeSelect

    + + +

    Cascader

    + + +

    Transfer

    + + +

    Table

    + + + + Title + Age + + + + +

    List

    + + + +
    + +

    Data Not Found in {{ name }}

    +
    +
    + `, + styles : [ `h3 { + font-size: inherit; + margin: 16px 0 8px 0; + }` + ] +}) +export class NzDemoEmptyConfigComponent { + @ViewChild('customTpl') customTpl: TemplateRef; // tslint:disable-line:no-any + + customize = false; + options = [ + { + value : 'zhejiang', + label : 'Zhejiang', + children: [ { + value : 'hangzhou', + label : 'Hangzhou', + children: [ { + value : 'xihu', + label : 'West Lake', + isLeaf: true + } ] + }, { + value : 'ningbo', + label : 'Ningbo', + isLeaf: true + } ] + }, { + value : 'jiangsu', + label : 'Jiangsu', + children: [ { + value : 'nanjing', + label : 'Nanjing', + children: [ { + value : 'zhonghuamen', + label : 'Zhong Hua Men', + isLeaf: true + } ] + } ] + } + ]; + + constructor(private nzEmptyService: NzEmptyService) { + } + + onConfigChange(): void { + if (this.customize) { + this.nzEmptyService.setDefaultContent(this.customTpl); // tslint:disable-line:no-any + } else { + this.nzEmptyService.resetDefault(); + } + } +} diff --git a/components/empty/demo/customize.md b/components/empty/demo/customize.md new file mode 100644 index 00000000000..1c62515a3e8 --- /dev/null +++ b/components/empty/demo/customize.md @@ -0,0 +1,16 @@ +--- +order: 1 +title: + zh-CN: 自定义 + en-US: Customize +--- + +## zh-CN + +自定义图片、描述、附属内容。 + +## en-US + +Customize image, description and extra content. + + diff --git a/components/empty/demo/customize.ts b/components/empty/demo/customize.ts new file mode 100644 index 00000000000..e1036650b19 --- /dev/null +++ b/components/empty/demo/customize.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-empty-customize', + template: ` + + + + Customize Description + + + + + + `, + styles : [] +}) +export class NzDemoEmptyCustomizeComponent { + onClick(): void { + console.log('clicked'); + } +} diff --git a/components/empty/doc/index.en-US.md b/components/empty/doc/index.en-US.md new file mode 100644 index 00000000000..4bc3febadd6 --- /dev/null +++ b/components/empty/doc/index.en-US.md @@ -0,0 +1,41 @@ +--- +category: Components +type: Data Display +title: Empty +cols: 1 +--- + +Empty state placeholder. + +## When To Use + +When there is no data provided, display for friendly tips. + +## API + +### nz-empty + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| `[nzNotFoundImage]` | Customize image. Will tread as image url when string provided | `string` | `TemplateRef` | - | +| `[nzNotFoundContent]` | Custom description | `string` | `TemplateRef` | - | +| `[nzNotFoundFooter]` | Custom Footer | `string` | `TemplateRef` | - | + +### NzEmptyService + +| Methods/Properties | Description | Parameters | +| -------- | ----------- | ---- | +| `setDefaultContent` | To set the default empty content. The parent component name would be passed to the template. | `TemplateRef` | `string` | +| `resetDefault` | Reset default empty content | - | + +### InjectionToken + +| Token | Description | Parameters | +| ----- | --- | ---- | +| `NZ_DEFAULT_EMPTY_CONTENT` | To provide a user default empty component | `Component` | `string` | +| `NZ_EMPTY_COMPONENT_NAME` | Would be injected to `NZ_DEFAULT_EMPTY_CONTENT`, telling that component its parent component's name | `string` | + +### Global Customizable Empty Content + +You may notice or used some inputs like `nzNotFoundContent` in some components. Now they would use `Empty` component. And you can even render a user default empty component, either by providing a `NZ_DEFAULT_EMPTY_CONTENT` in your root module or invoke `setDefaultEmptyContent`. + diff --git a/components/empty/doc/index.zh-CN.md b/components/empty/doc/index.zh-CN.md new file mode 100644 index 00000000000..6e3085f3c76 --- /dev/null +++ b/components/empty/doc/index.zh-CN.md @@ -0,0 +1,42 @@ +--- +category: Components +type: Data Display +subtitle: 空状态 +title: Empty +cols: 1 +--- + +空状态时的展示占位图。 + +## 何时使用 + +当目前没有数据时,用于显式的用户提示。 + +## API + +### nz-empty + +| 参数 | 说明 | 类型 | 默认值 | +| -------- | ----------- | ---- | ------- | +| `[nzNotFoundImage]` | 设置显示图片,为 `string` 时表示自定义图片地址 | `string` | `TemplateRef` | - | +| `[nzNotFoundContent]` | 自定义描述内容 | `string` | `TemplateRef` | - | +| `[nzNotFoundFooter]` | 设置自定义 footer | `string` | `TemplateRef` | - | + +### NzEmptyService + +| 属性/方法 | 说明 | 参数 | +| -------- | ----------- | ---- | +| `setDefaultEmptyContent` | 设置全局空内容,空组件的父组件名称将会被传递给模板 | `TemplateRef` | `string` | +| `resetDefault` | 重置默认空内容 | - | + +### InjectionToken + +| Token | 说明 | 参数 | +| ----- | --- | ---- | +| `NZ_DEFAULT_EMPTY_CONTENT` | 提供一个用户自定义的空组件 | `Component` | `string` | +| `NZ_EMPTY_COMPONENT_NAME` | 将会被注入到 `NZ_DEFAULT_EMPTY_CONTENT` 中,告诉该组件其父组件的名称 | `string` | + +### 全局自定义空组件 + +你或许知道或者用过一些类似 `nzNotFoundContent` 的属性来自定义组件数据为空时的内容,现在它们都会使用 `Empty` 组件。你甚至可以通过提供在根模块中提供 `NZ_DEFAULT_EMPTY_CONTENT`,或者是调用 `setDefaultEmptyContent` 方法来定义一个自定义的全局空组件。 + diff --git a/components/empty/index.ts b/components/empty/index.ts new file mode 100644 index 00000000000..7e1a213e3ea --- /dev/null +++ b/components/empty/index.ts @@ -0,0 +1 @@ +export * from './public-api'; diff --git a/components/empty/nz-embed-empty.component.html b/components/empty/nz-embed-empty.component.html new file mode 100644 index 00000000000..1304c4514d7 --- /dev/null +++ b/components/empty/nz-embed-empty.component.html @@ -0,0 +1,11 @@ + + + + + + + + + {{ content }} + + diff --git a/components/empty/nz-embed-empty.component.ts b/components/empty/nz-embed-empty.component.ts new file mode 100644 index 00000000000..2fd593f7187 --- /dev/null +++ b/components/empty/nz-embed-empty.component.ts @@ -0,0 +1,110 @@ +import { ComponentPortal, PortalInjector, TemplatePortal } from '@angular/cdk/portal'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + Injector, + Input, + OnChanges, + OnDestroy, + OnInit, + SimpleChanges, + TemplateRef, Type, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { Subscription } from 'rxjs'; + +import { simpleEmptyImage, NzEmptyCustomContent, NzEmptySize, NZ_EMPTY_COMPONENT_NAME } from './nz-empty.config'; +import { NzEmptyContentTypeError } from './nz-empty.error'; +import { NzEmptyService } from './nz-empty.service'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation : ViewEncapsulation.None, + selector : 'nz-embed-empty', + templateUrl : './nz-embed-empty.component.html' +}) +export class NzEmbedEmptyComponent implements OnChanges, OnInit, OnDestroy { + @Input() nzComponentName: string; + @Input() specificContent: NzEmptyCustomContent; + + content; + contentType: 'component' | 'template' | 'string' = 'string'; + contentPortal; + defaultSvg = this.sanitizer.bypassSecurityTrustResourceUrl(simpleEmptyImage); + size: NzEmptySize = ''; + subs_ = new Subscription(); + + constructor( + public emptyService: NzEmptyService, + private sanitizer: DomSanitizer, + private viewContainerRef: ViewContainerRef, + private cdr: ChangeDetectorRef, + private injector: Injector + ) { + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.nzComponentName) { + this.size = this.getEmptySize(changes.nzComponentName.currentValue); + } + + if (changes.specificContent && !changes.specificContent.isFirstChange()) { + this.content = changes.specificContent.currentValue; + this.renderEmpty(); + } + } + + ngOnInit(): void { + const userContent_ = this.emptyService.userDefaultContent$.subscribe(content => { + this.content = this.specificContent || content; + this.renderEmpty(); + }); + + this.subs_.add(userContent_); + } + + ngOnDestroy(): void { + this.subs_.unsubscribe(); + } + + private getEmptySize(componentName: string): NzEmptySize { + switch (componentName) { + case 'table': + case 'list': + return 'normal'; + case 'select': + case 'tree-select': + case 'cascader': + case 'transfer': + return 'small'; + default: + return ''; + } + } + + private renderEmpty(): void { + const content = this.content; + + if (content === undefined || content === null) { + // Do nothing. + } else if (typeof content === 'string') { + this.contentType = 'string'; + } else if (content instanceof TemplateRef) { + const context = { $implicit: this.nzComponentName } as any; // tslint:disable-line:no-any + this.contentType = 'template'; + this.contentPortal = new TemplatePortal(content, this.viewContainerRef, context); + } else if (content instanceof Type) { + const context = new WeakMap([ [ NZ_EMPTY_COMPONENT_NAME, this.nzComponentName ] ]); + const injector = new PortalInjector(this.injector, context); + this.contentType = 'component'; + this.contentPortal = new ComponentPortal(content, this.viewContainerRef, injector); + } else { + throw NzEmptyContentTypeError(content); + } + + this.cdr.markForCheck(); + } +} diff --git a/components/empty/nz-empty.component.html b/components/empty/nz-empty.component.html new file mode 100644 index 00000000000..3936ab2bc24 --- /dev/null +++ b/components/empty/nz-empty.component.html @@ -0,0 +1,15 @@ +
    + + + +
    +

    + + {{ nzNotFoundContent || ('Empty.description' | nzI18n) }} + +

    + diff --git a/components/empty/nz-empty.component.ts b/components/empty/nz-empty.component.ts new file mode 100644 index 00000000000..24df0312e4c --- /dev/null +++ b/components/empty/nz-empty.component.ts @@ -0,0 +1,45 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + OnChanges, + SimpleChanges, + TemplateRef, + ViewEncapsulation +} from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +import { emptyImage } from './nz-empty.config'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation : ViewEncapsulation.None, + selector : 'nz-empty', + templateUrl : './nz-empty.component.html', + styles : [ 'nz-empty { display: block; }' ], + host : { + 'class': 'ant-empty' + } +}) +export class NzEmptyComponent implements OnChanges { + @Input() nzNotFoundImage: string | TemplateRef; + @Input() nzNotFoundContent: string | TemplateRef; + @Input() nzNotFoundFooter: string | TemplateRef; + + // NOTE: It would be very hack to use `ContentChild`, because Angular could tell if user actually pass something to + // . See: https://github.com/angular/angular/issues/12530. + // I can use a directive but this would expose the name `footer`. + // @ContentChild(TemplateRef) nzNotFoundFooter: TemplateRef; + + defaultSvg = this.sanitizer.bypassSecurityTrustResourceUrl(emptyImage); + isContentString = false; + + constructor(private sanitizer: DomSanitizer) { + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.nzNotFoundContent) { + this.isContentString = typeof changes.nzNotFoundContent.currentValue === 'string'; + } + } +} diff --git a/components/empty/nz-empty.config.ts b/components/empty/nz-empty.config.ts new file mode 100644 index 00000000000..e4a89468a93 --- /dev/null +++ b/components/empty/nz-empty.config.ts @@ -0,0 +1,15 @@ +import { InjectionToken, TemplateRef, Type } from '@angular/core'; + +export type NzEmptySize = 'normal' | 'small' | ''; + +// tslint:disable-next-line:no-any +export type NzEmptyCustomContent = Type | TemplateRef | string; + +// tslint:disable-next-line:no-any +export const NZ_DEFAULT_EMPTY_CONTENT = new InjectionToken>('nz-empty-content'); + +export const NZ_EMPTY_COMPONENT_NAME = new InjectionToken('nz-empty-component-name'); + +export const emptyImage = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg0IiBoZWlnaHQ9IjE1MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0IDMxLjY3KSI+PGVsbGlwc2UgZmlsbC1vcGFjaXR5PSIuOCIgZmlsbD0iI0Y1RjVGNyIgY3g9IjY3Ljc5NyIgY3k9IjEwNi44OSIgcng9IjY3Ljc5NyIgcnk9IjEyLjY2OCIvPjxwYXRoIGQ9Ik0xMjIuMDM0IDY5LjY3NEw5OC4xMDkgNDAuMjI5Yy0xLjE0OC0xLjM4Ni0yLjgyNi0yLjIyNS00LjU5My0yLjIyNWgtNTEuNDRjLTEuNzY2IDAtMy40NDQuODM5LTQuNTkyIDIuMjI1TDEzLjU2IDY5LjY3NHYxNS4zODNoMTA4LjQ3NVY2OS42NzR6IiBmaWxsPSIjQUVCOEMyIi8+PHBhdGggZD0iTTEwMS41MzcgODYuMjE0TDgwLjYzIDYxLjEwMmMtMS4wMDEtMS4yMDctMi41MDctMS44NjctNC4wNDgtMS44NjdIMzEuNzI0Yy0xLjU0IDAtMy4wNDcuNjYtNC4wNDggMS44NjdMNi43NjkgODYuMjE0djEzLjc5Mmg5NC43NjhWODYuMjE0eiIgZmlsbD0idXJsKCNsaW5lYXJHcmFkaWVudC0xKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMuNTYpIi8+PHBhdGggZD0iTTMzLjgzIDBoNjcuOTMzYTQgNCAwIDAgMSA0IDR2OTMuMzQ0YTQgNCAwIDAgMS00IDRIMzMuODNhNCA0IDAgMCAxLTQtNFY0YTQgNCAwIDAgMSA0LTR6IiBmaWxsPSIjRjVGNUY3Ii8+PHBhdGggZD0iTTQyLjY3OCA5Ljk1M2g1MC4yMzdhMiAyIDAgMCAxIDIgMlYzNi45MWEyIDIgMCAwIDEtMiAySDQyLjY3OGEyIDIgMCAwIDEtMi0yVjExLjk1M2EyIDIgMCAwIDEgMi0yek00Mi45NCA0OS43NjdoNDkuNzEzYTIuMjYyIDIuMjYyIDAgMSAxIDAgNC41MjRINDIuOTRhMi4yNjIgMi4yNjIgMCAwIDEgMC00LjUyNHpNNDIuOTQgNjEuNTNoNDkuNzEzYTIuMjYyIDIuMjYyIDAgMSAxIDAgNC41MjVINDIuOTRhMi4yNjIgMi4yNjIgMCAwIDEgMC00LjUyNXpNMTIxLjgxMyAxMDUuMDMyYy0uNzc1IDMuMDcxLTMuNDk3IDUuMzYtNi43MzUgNS4zNkgyMC41MTVjLTMuMjM4IDAtNS45Ni0yLjI5LTYuNzM0LTUuMzZhNy4zMDkgNy4zMDkgMCAwIDEtLjIyMi0xLjc5VjY5LjY3NWgyNi4zMThjMi45MDcgMCA1LjI1IDIuNDQ4IDUuMjUgNS40MnYuMDRjMCAyLjk3MSAyLjM3IDUuMzcgNS4yNzcgNS4zN2gzNC43ODVjMi45MDcgMCA1LjI3Ny0yLjQyMSA1LjI3Ny01LjM5M1Y3NS4xYzAtMi45NzIgMi4zNDMtNS40MjYgNS4yNS01LjQyNmgyNi4zMTh2MzMuNTY5YzAgLjYxNy0uMDc3IDEuMjE2LS4yMjEgMS43ODl6IiBmaWxsPSIjRENFMEU2Ii8+PC9nPjxwYXRoIGQ9Ik0xNDkuMTIxIDMzLjI5MmwtNi44MyAyLjY1YTEgMSAwIDAgMS0xLjMxNy0xLjIzbDEuOTM3LTYuMjA3Yy0yLjU4OS0yLjk0NC00LjEwOS02LjUzNC00LjEwOS0xMC40MDhDMTM4LjgwMiA4LjEwMiAxNDguOTIgMCAxNjEuNDAyIDAgMTczLjg4MSAwIDE4NCA4LjEwMiAxODQgMTguMDk3YzAgOS45OTUtMTAuMTE4IDE4LjA5Ny0yMi41OTkgMTguMDk3LTQuNTI4IDAtOC43NDQtMS4wNjYtMTIuMjgtMi45MDJ6IiBmaWxsPSIjRENFMEU2Ii8+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ5LjY1IDE1LjM4MykiIGZpbGw9IiNGRkYiPjxlbGxpcHNlIGN4PSIyMC42NTQiIGN5PSIzLjE2NyIgcng9IjIuODQ5IiByeT0iMi44MTUiLz48cGF0aCBkPSJNNS42OTggNS42M0gwTDIuODk4LjcwNHpNOS4yNTkuNzA0aDQuOTg1VjUuNjNIOS4yNTl6Ii8+PC9nPjwvZz48L3N2Zz4='; + +export const simpleEmptyImage = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNjRweCIgaGVpZ2h0PSI0MXB4IiB2aWV3Qm94PSIwIDAgNjQgNDEiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjUgKDY3NDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDxnIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00NzIuMDAwMDAwLCAtMTMzNS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY0LjAwMDAwMCwgMTExNC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnICB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MC4wMDAwMDAsIDc4LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgICAgIDxnICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjguMDAwMDAwLCAxNDQuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxlbGxpcHNlICBmaWxsPSIjRjVGNUY1IiBjeD0iMzIiIGN5PSIzMyIgcng9IjMyIiByeT0iNyI+PC9lbGxpcHNlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGcgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSg5LjAwMDAwMCwgMC4wMDAwMDApIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0iI0Q5RDlEOSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQ2LDEyLjc2MDU2MDQgTDM1Ljg1NDMwNDcsMS4yNTczOTYzMyBDMzUuMzY3NDQxNCwwLjQ3MzgyNjYwNSAzNC42NTU4Nzg5LDAgMzMuOTA2NzYxNywwIEwxMi4wOTMyMzgzLDAgQzExLjM0NDEyMTEsMCAxMC42MzI1NTg2LDAuNDczOTUwMjU1IDEwLjE0NTY5NTMsMS4yNTczOTYzMyBMMi42MTQ3OTcyN2UtMTIsMTIuNzYwNTYwNCBMMCwyMiBMNDYsMjIgTDQ2LDEyLjc2MDU2MDQgWiIgID48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTMyLjYxMzI4MTMsMTUuOTMxNSBDMzIuNjEzMjgxMywxNC4zMjU4NTExIDMzLjYwNjk1MzEsMTMuMDAwMjM0IDM0LjgzOTY5OTIsMTMgTDQ2LDEzIEw0NiwzMS4xMzcxMjc3IEM0NiwzMy4yNTg5NTc0IDQ0LjY3OTM4NjcsMzUgNDMuMDUwNDI5NywzNSBMMi45NDk1NzAzMSwzNSBDMS4zMjA1MjM0NCwzNSAwLDMzLjI1ODg0MDQgMCwzMS4xMzcxMjc3IEwwLDEzIEwxMS4xNjAzMDA4LDEzIEMxMi4zOTMwNDY5LDEzIDEzLjM4NjcxODgsMTQuMzIyODA4NSAxMy4zODY3MTg4LDE1LjkyODQ1NzQgTDEzLjM4NjcxODgsMTUuOTQ5NjM4MyBDMTMuMzg2NzE4OCwxNy41NTUyODcyIDE0LjM5MTcxMDksMTguODUxMTgwOSAxNS42MjQ0NTcsMTguODUxMTgwOSBMMzAuMzc1NTQzLDE4Ljg1MTE4MDkgQzMxLjYwODI4OTEsMTguODUxMTgwOSAzMi42MTMyODEzLDE3LjU0MzM1MTEgMzIuNjEzMjgxMywxNS45Mzc3MDIxIEwzMi42MTMyODEzLDE1LjkzMTUgWiIgIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'; diff --git a/components/empty/nz-empty.error.ts b/components/empty/nz-empty.error.ts new file mode 100644 index 00000000000..04be36dbbcf --- /dev/null +++ b/components/empty/nz-empty.error.ts @@ -0,0 +1,3 @@ +export function NzEmptyContentTypeError(content: any): Error { // tslint:disable-line:no-any + return TypeError(`[NG-ZORRO]: useDefaultContent expect 'string', 'templateRef' or 'component' but get ${content}`); +} diff --git a/components/empty/nz-empty.module.ts b/components/empty/nz-empty.module.ts new file mode 100644 index 00000000000..023e33f7b0a --- /dev/null +++ b/components/empty/nz-empty.module.ts @@ -0,0 +1,15 @@ +import { PortalModule } from '@angular/cdk/portal'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { NzAddOnModule } from '../core/addon/addon.module'; +import { NzI18nModule } from '../i18n/nz-i18n.module'; +import { NzEmbedEmptyComponent } from './nz-embed-empty.component'; +import { NzEmptyComponent } from './nz-empty.component'; + +@NgModule({ + imports : [ CommonModule, PortalModule, NzAddOnModule, NzI18nModule ], + declarations: [ NzEmptyComponent, NzEmbedEmptyComponent ], + exports : [ NzEmptyComponent, NzEmbedEmptyComponent ] +}) +export class NzEmptyModule { +} diff --git a/components/empty/nz-empty.service.ts b/components/empty/nz-empty.service.ts new file mode 100644 index 00000000000..3c87356eb2b --- /dev/null +++ b/components/empty/nz-empty.service.ts @@ -0,0 +1,24 @@ +import { Inject, Injectable, Optional, Type } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { NzEmptyCustomContent, NZ_DEFAULT_EMPTY_CONTENT } from './nz-empty.config'; + +@Injectable({ + providedIn: 'root' +}) +export class NzEmptyService { // tslint:disable-line:no-any + userDefaultContent$ = new BehaviorSubject(undefined); + + constructor(@Inject(NZ_DEFAULT_EMPTY_CONTENT) @Optional() private defaultEmptyContent: Type) { + if (this.defaultEmptyContent) { + this.userDefaultContent$.next(this.defaultEmptyContent); + } + } + + setDefaultContent(content?: NzEmptyCustomContent): void { + this.userDefaultContent$.next(content); + } + + resetDefault(): void { + this.userDefaultContent$.next(undefined); + } +} diff --git a/components/empty/nz-empty.spec.ts b/components/empty/nz-empty.spec.ts new file mode 100644 index 00000000000..cc3298dcf1a --- /dev/null +++ b/components/empty/nz-empty.spec.ts @@ -0,0 +1,337 @@ +import { CommonModule } from '@angular/common'; +import { Component, Inject, NgModule, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { fakeAsync, tick, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NzListModule } from '../list'; +import { NzEmbedEmptyComponent } from './nz-embed-empty.component'; +import { NzEmptyComponent } from './nz-empty.component'; +import { NZ_DEFAULT_EMPTY_CONTENT, NZ_EMPTY_COMPONENT_NAME } from './nz-empty.config'; +import { NzEmptyModule } from './nz-empty.module'; +import { NzEmptyService } from './nz-empty.service'; + +describe('nz-empty', () => { + let fixture; + let testComponent; + let emptyComponent; + let embedComponent; + + /** + * Basic usage. + */ + describe('basic', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports : [ CommonModule, NzEmptyModule ], + declarations: [ NzEmptyTestBasicComponent ] + }).compileComponents(); + + fixture = TestBed.createComponent(NzEmptyTestBasicComponent); + testComponent = fixture.debugElement.componentInstance; + emptyComponent = fixture.debugElement.query(By.directive(NzEmptyComponent)); + fixture.detectChanges(); + }); + + it('should render image, description on default situation', () => { + expect(emptyComponent.nativeElement.classList.contains('ant-empty')).toBe(true); + + const imageEl = emptyComponent.nativeElement.firstChild; + expect(imageEl.tagName).toBe('DIV'); + expect(imageEl.classList.contains('ant-empty-image')).toBe(true); + expect(imageEl.firstElementChild.tagName).toBe('IMG'); + expect(imageEl.firstElementChild.getAttribute('alt')).toBe('empty'); + expect(imageEl.firstElementChild.src).toContain('data:image'); + + const contentEl = emptyComponent.nativeElement.lastElementChild; + expect(contentEl.tagName).toBe('P'); + expect(contentEl.innerText.trim()).toBe('暂无数据'); + }); + + it('should render image, content and footer as template', () => { + testComponent.image = testComponent.imageTpl; + testComponent.content = testComponent.contentTpl; + testComponent.footer = testComponent.footerTpl; + + fixture.detectChanges(); + + expect(emptyComponent.nativeElement.classList.contains('ant-empty')).toBe(true); + + const imageEl = emptyComponent.nativeElement.firstChild; + expect(imageEl.tagName).toBe('DIV'); + expect(imageEl.classList.contains('ant-empty-image')).toBe(true); + expect(imageEl.innerText).toBe('Image'); + + const contentEl = emptyComponent.nativeElement.querySelector('.ant-empty-description'); + expect(contentEl).not.toBeFalsy(); + expect(contentEl.tagName).toBe('P'); + expect(contentEl.innerText).toBe('Content'); + + const footerEl = emptyComponent.nativeElement.lastElementChild; + expect(footerEl.tagName).toBe('DIV'); + expect(footerEl.classList.contains('ant-empty-footer')).toBe(true); + expect(footerEl.innerText).toBe('Footer'); + }); + + it('should render image, content and footer as string and change `alt`', () => { + testComponent.image = 'https://ng.ant.design/assets/img/logo.svg'; + testComponent.content = 'zorro icon'; + testComponent.footer = 'Footer'; + + fixture.detectChanges(); + + expect(emptyComponent.nativeElement.classList.contains('ant-empty')).toBe(true); + + const imageEl = emptyComponent.nativeElement.firstChild; + expect(imageEl.tagName).toBe('DIV'); + expect(imageEl.classList.contains('ant-empty-image')).toBe(true); + expect(imageEl.firstElementChild.tagName).toBe('IMG'); + expect(imageEl.firstElementChild.getAttribute('alt')).toBe('zorro icon'); + expect(imageEl.firstElementChild.src).toContain('ng.ant.design'); + + const contentEl = emptyComponent.nativeElement.querySelector('.ant-empty-description'); + expect(contentEl).not.toBeFalsy(); + expect(contentEl.tagName).toBe('P'); + expect(contentEl.innerText).toBe('zorro icon'); + + const footerEl = emptyComponent.nativeElement.lastElementChild; + expect(footerEl.tagName).toBe('DIV'); + expect(footerEl.classList.contains('ant-empty-footer')).toBe(true); + expect(footerEl.innerText).toBe('Footer'); + }); + + // TODO: need to add i18n test later. + }); + + /** + * Config default empty content via `NzEmptyService`'s `setDefaultEmptyContent` method. + */ + describe('embed', () => { + describe('service method', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ NzEmptyTestServiceModule ] + }).compileComponents(); + + fixture = TestBed.createComponent(NzEmptyTestServiceComponent); + testComponent = fixture.debugElement.componentInstance; + }); + + it('should components\' prop has priority', fakeAsync(() => { + const refresh = () => { + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + + embedComponent = fixture.debugElement.query(By.directive(NzEmbedEmptyComponent)); + emptyComponent = fixture.debugElement.query(By.directive(NzEmptyComponent)); + }; + + refresh(); + + // Default. + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeTruthy(); + expect(emptyComponent.nativeElement.classList.contains('ant-empty')).toBe(true); + expect(emptyComponent.nativeElement.classList.contains('ant-empty-normal')).toBe(true); + const imageEl = emptyComponent.nativeElement.firstChild; + expect(imageEl.tagName).toBe('DIV'); + expect(imageEl.classList.contains('ant-empty-image')).toBe(true); + expect(imageEl.firstElementChild.tagName).toBe('IMG'); + expect(imageEl.firstElementChild.getAttribute('alt')).toBe('empty'); + expect(imageEl.firstElementChild.src).toContain('data:image/svg+xml'); + + // Prop. + testComponent.noResult = 'list'; + refresh(); + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeFalsy(); + expect(embedComponent.nativeElement.innerText).toBe('list'); + })); + + it('should support string, template and component', fakeAsync(() => { + const refresh = () => { + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + + embedComponent = fixture.debugElement.query(By.directive(NzEmbedEmptyComponent)); + emptyComponent = fixture.debugElement.query(By.directive(NzEmptyComponent)); + }; + + // String. + testComponent.changeToString(); + refresh(); + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeFalsy(); + expect(embedComponent.nativeElement.innerText).toBe('empty'); + + // Template. + testComponent.changeToTemplate(); + refresh(); + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeFalsy(); + const divEl = embedComponent.nativeElement.firstElementChild; + expect(divEl).toBeTruthy(); + expect(divEl.tagName).toBe('DIV'); + expect(divEl.innerText).toBe('I am in template list'); + + // FIXME: This is not supported yet, see https://github.com/angular/angular/issues/15634. + // Component. + // testComponent.changeToComponent(); + // refresh(); + // expect(embedComponent).toBeTruthy(); + // expect(emptyComponent).toBeFalsy(); + // const componentEl = embedComponent.nativeElement.nextSibling; + // expect(componentEl).toBeTruthy(); + // expect(componentEl.tagName).toBe('NZ-EMPTY-TEST-CUSTOM'); + // expect(componentEl.innerText).toBe(`I'm in component list`); + + // Reset. + testComponent.reset(); + refresh(); + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeTruthy(); + expect(emptyComponent.nativeElement.classList.contains('ant-empty')).toBe(true); + expect(emptyComponent.nativeElement.classList.contains('ant-empty-normal')).toBe(true); + const imageEl = emptyComponent.nativeElement.firstChild; + expect(imageEl.tagName).toBe('DIV'); + expect(imageEl.classList.contains('ant-empty-image')).toBe(true); + expect(imageEl.firstElementChild.tagName).toBe('IMG'); + expect(imageEl.firstElementChild.getAttribute('alt')).toBe('empty'); + expect(imageEl.firstElementChild.src).toContain('data:image/svg+xml'); + })); + + it('should raise error when set a invalid default value', () => { + expect(() => { + testComponent.changeToInvalid(); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + }).toThrowError(); + }); + }); + + /** + * Config default empty content via injection. + */ + describe('service injection', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ NzEmptyTestInjectionModule ] + }).compileComponents(); + + fixture = TestBed.createComponent(NzEmptyTestServiceComponent); + testComponent = fixture.debugElement.componentInstance; + }); + + it('should support injection', fakeAsync(() => { + const refresh = () => { + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + + embedComponent = fixture.debugElement.query(By.directive(NzEmbedEmptyComponent)); + emptyComponent = fixture.debugElement.query(By.directive(NzEmptyComponent)); + }; + + refresh(); + + // Component. + expect(embedComponent).toBeTruthy(); + expect(emptyComponent).toBeFalsy(); + const componentEl = embedComponent.nativeElement.nextSibling; + expect(componentEl).toBeTruthy(); + expect(componentEl.tagName).toBe('NZ-EMPTY-TEST-CUSTOM'); + expect(componentEl.innerText).toBe(`I'm in component list`); + })); + }); + }); +}); + +@Component({ + selector: 'nz-empty-test-basic', + template: ` + + Image + Content + Footer + + ` +}) +export class NzEmptyTestBasicComponent { + @ViewChild('imageTpl') imageTpl: TemplateRef; + @ViewChild('contentTpl') contentTpl: TemplateRef; + @ViewChild('footerTpl') footerTpl: TemplateRef; + + image = undefined; + content = undefined; + footer = undefined; +} + +@Component({ + selector: 'nz-empty-test-service', + template: ` + + +
    I am in template {{ component }}
    +
    + ` +}) +export class NzEmptyTestServiceComponent { + @ViewChild('tpl') template: TemplateRef; + + noResult = null; + + constructor(private emptyService: NzEmptyService) { + } + + reset(): void { + this.emptyService.resetDefault(); + } + + changeToString(): void { + this.emptyService.setDefaultContent('empty'); + } + + changeToTemplate(): void { + this.emptyService.setDefaultContent(this.template); + } + + changeToInvalid(): void { + this.emptyService.setDefaultContent(false as any); // tslint:disable-line:no-any + } +} + +@Component({ + selector: 'nz-empty-test-custom', + template: ` +
    I'm in component {{ name }}
    + ` +}) +export class NzEmptyTestCustomComponent { + constructor(@Inject(NZ_EMPTY_COMPONENT_NAME) public name: string) { + } +} + +@NgModule({ + imports : [ CommonModule, NzEmptyModule, NzListModule ], + declarations : [ NzEmptyTestServiceComponent, NzEmptyTestCustomComponent ], + entryComponents: [ NzEmptyTestCustomComponent ], + exports : [ NzEmptyTestServiceComponent, NzEmptyTestCustomComponent ] +}) +export class NzEmptyTestServiceModule { +} + +@NgModule({ + imports : [ CommonModule, NzEmptyModule, NzListModule ], + declarations : [ NzEmptyTestServiceComponent, NzEmptyTestCustomComponent ], + entryComponents: [ NzEmptyTestCustomComponent ], + exports : [ NzEmptyTestServiceComponent, NzEmptyTestCustomComponent ], + providers : [ + { + provide : NZ_DEFAULT_EMPTY_CONTENT, + useValue: NzEmptyTestCustomComponent + } + ] +}) +export class NzEmptyTestInjectionModule { +} diff --git a/components/empty/public-api.ts b/components/empty/public-api.ts new file mode 100644 index 00000000000..edd144618d4 --- /dev/null +++ b/components/empty/public-api.ts @@ -0,0 +1,5 @@ +export * from './nz-embed-empty.component'; +export * from './nz-empty.component'; +export * from './nz-empty.module'; +export * from './nz-empty.service'; +export * from './nz-empty.config'; diff --git a/components/empty/style/index.less b/components/empty/style/index.less new file mode 100644 index 00000000000..780aed730e9 --- /dev/null +++ b/components/empty/style/index.less @@ -0,0 +1,45 @@ +@import '../../style/themes/default'; +@import '../../style/mixins/index'; + +@empty-prefix-cls: ~'@{ant-prefix}-empty'; + +.@{empty-prefix-cls} { + text-align: center; + font-size: @empty-font-size; + line-height: 22px; + margin: 0 8px; + + &-image { + margin-bottom: 8px; + height: 100px; + + img { + height: 100%; + } + } + + &-description { + margin: 0; + } + + &-footer { + margin-top: 16px; + } + + // antd internal empty style + &-small { + margin: 8px 0; + + .@{empty-prefix-cls}-image { + height: 35px; + } + } + + &-normal { + margin: 32px 0; + + .@{empty-prefix-cls}-image { + height: 40px; + } + } +} diff --git a/components/i18n/languages/ar_EG.ts b/components/i18n/languages/ar_EG.ts index 8610c4f4563..4901e900c13 100644 --- a/components/i18n/languages/ar_EG.ts +++ b/components/i18n/languages/ar_EG.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'الفلاتر', filterConfirm: 'تأكيد', filterReset: 'إعادة ضبط', - emptyText: 'لا توجد بيانات', selectAll: 'اختيار الكل', selectInvert: 'إلغاء الاختيار', }, @@ -27,18 +26,17 @@ export default { cancelText: 'إلغاء', }, Transfer: { - notFoundContent: 'لا يوجد محتوى', searchPlaceholder: 'ابحث هنا', itemUnit: 'عنصر', itemsUnit: 'عناصر', }, - Select: { - notFoundContent: 'لايوجد محتوى', - }, Upload: { uploading: 'جاري الرفع...', removeFile: 'احذف الملف', uploadError: 'مشكلة فى الرفع', previewFile: 'استعرض الملف', }, + Empty: { + description: 'لا توجد بيانات', + }, }; diff --git a/components/i18n/languages/bg_BG.ts b/components/i18n/languages/bg_BG.ts index bd5d371670a..9d2b9e9938c 100644 --- a/components/i18n/languages/bg_BG.ts +++ b/components/i18n/languages/bg_BG.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Филтриране', filterConfirm: 'Добре', filterReset: 'Нулриане', - emptyText: 'Няма данни', selectAll: 'Избор на текуща страница', selectInvert: 'Обръщане', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Отказ', }, Transfer: { - notFoundContent: 'Няма намерени', searchPlaceholder: 'Търсене', itemUnit: 'избор', itemsUnit: 'избори', }, - Select: { - notFoundContent: 'Няма намерени', - }, Upload: { uploading: 'Качване...', removeFile: 'Премахване', uploadError: 'Грешка при качването', previewFile: 'Преглед', }, + Empty: { + description: 'Няма данни', + }, }; diff --git a/components/i18n/languages/ca_ES.ts b/components/i18n/languages/ca_ES.ts index 63323197dc2..034e832201d 100644 --- a/components/i18n/languages/ca_ES.ts +++ b/components/i18n/languages/ca_ES.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtrar Menu', filterConfirm: 'OK', filterReset: 'Restablir', - emptyText: 'Sense dades', }, Modal: { okText: 'OK', @@ -25,12 +24,11 @@ export default { cancelText: 'Cancel·lar', }, Transfer: { - notFoundContent: 'No trobat', searchPlaceholder: 'Cercar aquí', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'No trobat', + Empty: { + description: 'Sense dades', }, }; diff --git a/components/i18n/languages/cs_CZ.ts b/components/i18n/languages/cs_CZ.ts index 9d21f606cbb..eb6916fad0b 100644 --- a/components/i18n/languages/cs_CZ.ts +++ b/components/i18n/languages/cs_CZ.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtr', filterConfirm: 'Potvrdit', filterReset: 'Obnovit', - emptyText: 'Žádná data', }, Modal: { okText: 'Ok', @@ -25,18 +24,17 @@ export default { cancelText: 'Storno', }, Transfer: { - notFoundContent: 'Nenalezeno', searchPlaceholder: 'Vyhledávání', itemUnit: 'položka', itemsUnit: 'položek', }, - Select: { - notFoundContent: 'Nenalezeno', - }, Upload: { uploading: 'Nahrávání...', removeFile: 'Odstranit soubor', uploadError: 'Chyba při nahrávání', previewFile: 'Zobrazit soubor', }, + Empty: { + description: 'Žádná data', + }, }; diff --git a/components/i18n/languages/da_DK.ts b/components/i18n/languages/da_DK.ts index 25387489ab7..d90d1849fbd 100644 --- a/components/i18n/languages/da_DK.ts +++ b/components/i18n/languages/da_DK.ts @@ -13,32 +13,30 @@ export default { filterTitle: 'Filtermenu', filterConfirm: 'OK', filterReset: 'Nulstil', - emptyText: 'Ingen data', selectAll: 'Vælg alle', selectInvert: 'Inverter valg', }, Modal: { okText: 'OK', - cancelText: 'Annuller', + cancelText: 'Afbryd', justOkText: 'OK', }, Popconfirm: { okText: 'OK', - cancelText: 'Annuller', + cancelText: 'Afbryd', }, Transfer: { - notFoundContent: 'Intet match', searchPlaceholder: 'Søg her', itemUnit: 'element', itemsUnit: 'elementer', }, - Select: { - notFoundContent: 'Intet match', - }, Upload: { uploading: 'Uploader...', removeFile: 'Fjern fil', uploadError: 'Fejl ved upload', previewFile: 'Forhåndsvisning', }, + Empty: { + description: 'Ingen data', + }, }; diff --git a/components/i18n/languages/de_DE.ts b/components/i18n/languages/de_DE.ts index bb132f3c57c..a4700dfb518 100644 --- a/components/i18n/languages/de_DE.ts +++ b/components/i18n/languages/de_DE.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filter-Menü', filterConfirm: 'OK', filterReset: 'Zurücksetzen', - emptyText: 'Keine Daten', selectAll: 'Selektiere Alle', selectInvert: 'Selektion Invertieren', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Abbrechen', }, Transfer: { - notFoundContent: 'Nicht gefunden', searchPlaceholder: 'Suchen', itemUnit: 'Eintrag', itemsUnit: 'Einträge', }, - Select: { - notFoundContent: 'Nicht gefunden', - }, Upload: { uploading: 'Hochladen...', removeFile: 'Datei entfernen', uploadError: 'Fehler beim Hochladen', previewFile: 'Dateivorschau', }, + Empty: { + description: 'Keine Daten', + }, }; diff --git a/components/i18n/languages/el_GR.ts b/components/i18n/languages/el_GR.ts index 132b625536e..9f87a291454 100644 --- a/components/i18n/languages/el_GR.ts +++ b/components/i18n/languages/el_GR.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Μενού φίλτρων', filterConfirm: 'ΟΚ', filterReset: 'Επαναφορά', - emptyText: 'Δεν υπάρχουν δεδομένα', selectAll: 'Επιλογή τρέχουσας σελίδας', selectInvert: 'Αντιστροφή τρέχουσας σελίδας', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Άκυρο', }, Transfer: { - notFoundContent: 'Δεν βρέθηκε', searchPlaceholder: 'Αναζήτηση', itemUnit: 'αντικείμενο', itemsUnit: 'αντικείμενα', }, - Select: { - notFoundContent: 'Δεν βρέθηκε', - }, Upload: { uploading: 'Μεταφόρτωση...', removeFile: 'Αφαίρεση αρχείου', uploadError: 'Σφάλμα μεταφόρτωσης', previewFile: 'Προεπισκόπηση αρχείου', }, + Empty: { + description: 'Δεν υπάρχουν δεδομένα', + }, }; diff --git a/components/i18n/languages/en_GB.ts b/components/i18n/languages/en_GB.ts index 3252c6c8e9b..7f9748f9679 100644 --- a/components/i18n/languages/en_GB.ts +++ b/components/i18n/languages/en_GB.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filter menu', filterConfirm: 'OK', filterReset: 'Reset', - emptyText: 'No data', selectAll: 'Select current page', selectInvert: 'Invert current page', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Cancel', }, Transfer: { - notFoundContent: 'Not Found', searchPlaceholder: 'Search here', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Not Found', - }, Upload: { uploading: 'Uploading...', removeFile: 'Remove file', uploadError: 'Upload error', previewFile: 'Preview file', }, + Empty: { + description: 'No data', + }, }; diff --git a/components/i18n/languages/en_US.ts b/components/i18n/languages/en_US.ts index 502f92d2d48..6008b03509f 100644 --- a/components/i18n/languages/en_US.ts +++ b/components/i18n/languages/en_US.ts @@ -9,13 +9,16 @@ export default { DatePicker, TimePicker, Calendar, + global: { + placeholder: 'Please select', + }, Table: { filterTitle: 'Filter menu', filterConfirm: 'OK', filterReset: 'Reset', - emptyText: 'No data', selectAll: 'Select current page', selectInvert: 'Invert current page', + sortTitle: 'Sort', }, Modal: { okText: 'OK', @@ -28,18 +31,17 @@ export default { }, Transfer: { titles: ['', ''], - notFoundContent: 'Not Found', searchPlaceholder: 'Search here', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Not Found', - }, Upload: { uploading: 'Uploading...', removeFile: 'Remove file', uploadError: 'Upload error', previewFile: 'Preview file', }, + Empty: { + description: 'No Data', + }, }; diff --git a/components/i18n/languages/es_ES.ts b/components/i18n/languages/es_ES.ts index 59440feb8ae..934f54cd997 100644 --- a/components/i18n/languages/es_ES.ts +++ b/components/i18n/languages/es_ES.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtrar menú', filterConfirm: 'Aceptar', filterReset: 'Reiniciar', - emptyText: 'No hay datos', selectAll: 'Seleccionar todo', selectInvert: 'Invertir selección', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Cancelar', }, Transfer: { - notFoundContent: 'No encontrado', searchPlaceholder: 'Buscar aquí', itemUnit: 'elemento', itemsUnit: 'elementos', }, - Select: { - notFoundContent: 'No encontrado', - }, Upload: { uploading: 'Subiendo...', removeFile: 'Eliminar archivo', uploadError: 'Error al subir el archivo', previewFile: 'Vista previa', }, + Empty: { + description: 'No hay datos', + }, }; diff --git a/components/i18n/languages/et_EE.ts b/components/i18n/languages/et_EE.ts index 7cf25547b49..710aaac0292 100644 --- a/components/i18n/languages/et_EE.ts +++ b/components/i18n/languages/et_EE.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtri menüü', filterConfirm: 'OK', filterReset: 'Nulli', - emptyText: 'Andmed puuduvad', selectAll: 'Vali kõik', selectInvert: 'Inverteeri valik', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Tühista', }, Transfer: { - notFoundContent: 'Ei leitud', searchPlaceholder: 'Otsi siit', itemUnit: 'kogus', itemsUnit: 'kogus', }, - Select: { - notFoundContent: 'Ei leitud', - }, Upload: { uploading: 'Üleslaadimine...', removeFile: 'Eemalda fail', uploadError: 'Üleslaadimise tõrge', previewFile: 'Faili eelvaade', }, + Empty: { + description: 'Andmed puuduvad', + }, }; diff --git a/components/i18n/languages/fa_IR.ts b/components/i18n/languages/fa_IR.ts index f2335b3bbb6..413ba1fd9ba 100644 --- a/components/i18n/languages/fa_IR.ts +++ b/components/i18n/languages/fa_IR.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'منوی فیلتر', filterConfirm: 'تایید', filterReset: 'پاک کردن', - emptyText: 'داده‌ای موجود نیست', selectAll: 'انتخاب صفحه‌ی کنونی', selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', }, @@ -27,18 +26,17 @@ export default { cancelText: 'لغو', }, Transfer: { - notFoundContent: 'داده‌ای موجود نیست', searchPlaceholder: 'جستجو', itemUnit: '', itemsUnit: '', }, - Select: { - notFoundContent: 'داده‌ای موجود نیست', - }, Upload: { uploading: 'در حال آپلود...', removeFile: 'حذف فایل', uploadError: 'خطا در آپلود', previewFile: 'مشاهده‌ی فایل', }, + Empty: { + description: 'داده‌ای موجود نیست', + }, }; diff --git a/components/i18n/languages/fi_FI.ts b/components/i18n/languages/fi_FI.ts index 3d3b1f99625..368478b07a0 100644 --- a/components/i18n/languages/fi_FI.ts +++ b/components/i18n/languages/fi_FI.ts @@ -13,9 +13,9 @@ export default { filterTitle: 'Suodatus valikko', filterConfirm: 'OK', filterReset: 'Tyhjennä', - emptyText: 'Ei kohteita', selectAll: 'Valitse kaikki', selectInvert: 'Valitse päinvastoin', + sortTitle: 'Lajittele', }, Modal: { okText: 'OK', @@ -27,18 +27,17 @@ export default { cancelText: 'Peruuta', }, Transfer: { - notFoundContent: 'Ei löytynyt', searchPlaceholder: 'Etsi täältä', itemUnit: 'kohde', itemsUnit: 'kohdetta', }, - Select: { - notFoundContent: 'Ei löytynyt', - }, Upload: { uploading: 'Lähetetään...', removeFile: 'Poista tiedosto', uploadError: 'Virhe lähetyksessä', previewFile: 'Esikatsele tiedostoa', }, + Empty: { + description: 'Ei kohteita', + }, }; diff --git a/components/i18n/languages/fr_BE.ts b/components/i18n/languages/fr_BE.ts index edc8b974e9e..0fcf56a57a2 100644 --- a/components/i18n/languages/fr_BE.ts +++ b/components/i18n/languages/fr_BE.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtrer', filterConfirm: 'OK', filterReset: 'Réinitialiser', - emptyText: 'Aucune donnée', }, Modal: { okText: 'OK', @@ -25,12 +24,11 @@ export default { cancelText: 'Annuler', }, Transfer: { - notFoundContent: 'Pas de résultat', searchPlaceholder: 'Recherche', itemUnit: 'élément', itemsUnit: 'éléments', }, - Select: { - notFoundContent: 'Pas de résultat', + Empty: { + description: 'Aucune donnée', }, }; diff --git a/components/i18n/languages/fr_FR.ts b/components/i18n/languages/fr_FR.ts index ec958407ff3..3c36f928208 100644 --- a/components/i18n/languages/fr_FR.ts +++ b/components/i18n/languages/fr_FR.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtrer', filterConfirm: 'OK', filterReset: 'Réinitialiser', - emptyText: 'Aucune donnée', selectAll: 'Tout sélectionner', selectInvert: 'Inverser la sélection', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Annuler', }, Transfer: { - notFoundContent: 'Pas de résultat', searchPlaceholder: 'Recherche', itemUnit: 'élément', itemsUnit: 'éléments', }, - Select: { - notFoundContent: 'Pas de résultat', - }, Upload: { uploading: 'Téléversement en cours...', removeFile: 'Supprimer', uploadError: 'Erreur de téléversement', previewFile: 'Afficher l\'aperçu du fichier', }, + Empty: { + description: 'Aucune donnée', + }, }; diff --git a/components/i18n/languages/is_IS.ts b/components/i18n/languages/is_IS.ts index 543c891459b..016949e6d73 100644 --- a/components/i18n/languages/is_IS.ts +++ b/components/i18n/languages/is_IS.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Afmarkanir', filterConfirm: 'Staðfesta', filterReset: 'Núllstilla', - emptyText: 'Engin gögn', selectAll: 'Velja allt', selectInvert: 'Viðsnúa vali', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Hætta við', }, Transfer: { - notFoundContent: 'Engar færslur', searchPlaceholder: 'Leita hér', itemUnit: 'færsla', itemsUnit: 'færslur', }, - Select: { - notFoundContent: 'Ekkert finnst', - }, Upload: { uploading: 'Hleð upp...', removeFile: 'Fjarlægja skrá', uploadError: 'Villa við að hlaða upp', previewFile: 'Forskoða skrá', }, + Empty: { + description: 'Engin gögn', + }, }; diff --git a/components/i18n/languages/it_IT.ts b/components/i18n/languages/it_IT.ts index 6fcee7209be..9ceba10218b 100644 --- a/components/i18n/languages/it_IT.ts +++ b/components/i18n/languages/it_IT.ts @@ -10,12 +10,12 @@ export default { TimePicker, Calendar, Table: { - filterTitle: 'Menu Filtro', + filterTitle: 'Menù Filtro', filterConfirm: 'OK', filterReset: 'Reset', - emptyText: 'Nessun dato', selectAll: 'Seleziona pagina corrente', - selectInvert: 'Selezionare Inverti', + selectInvert: 'Inverti selezione nella pagina corrente', + sortTitle: 'Ordina', }, Modal: { okText: 'OK', @@ -27,18 +27,17 @@ export default { cancelText: 'Annulla', }, Transfer: { - notFoundContent: 'Non trovato', searchPlaceholder: 'Cerca qui', itemUnit: 'articolo', itemsUnit: 'elementi', }, - Select: { - notFoundContent: 'Non trovato', - }, Upload: { uploading: 'Caricamento...', removeFile: 'Rimuovi il file', uploadError: 'Errore di caricamento', previewFile: 'Anteprima file', }, + Empty: { + description: 'Nessun dato', + }, }; diff --git a/components/i18n/languages/ja_JP.ts b/components/i18n/languages/ja_JP.ts index 889fd8b5087..8a01130029a 100644 --- a/components/i18n/languages/ja_JP.ts +++ b/components/i18n/languages/ja_JP.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'メニューをフィルター', filterConfirm: 'OK', filterReset: 'リセット', - emptyText: 'データがありません', selectAll: 'すべてを選択', selectInvert: '選択を反転', }, @@ -27,18 +26,17 @@ export default { cancelText: 'キャンセル', }, Transfer: { - notFoundContent: '結果はありません', searchPlaceholder: 'ここを検索', itemUnit: 'アイテム', itemsUnit: 'アイテム', }, - Select: { - notFoundContent: '結果はありません', - }, Upload: { uploading: 'アップロード中...', removeFile: 'ファイルを削除', uploadError: 'アップロードエラー', previewFile: 'ファイルをプレビュー', }, + Empty: { + description: 'データがありません', + }, }; diff --git a/components/i18n/languages/ko_KR.ts b/components/i18n/languages/ko_KR.ts index e14a192fd69..b341f40475a 100644 --- a/components/i18n/languages/ko_KR.ts +++ b/components/i18n/languages/ko_KR.ts @@ -13,9 +13,8 @@ export default { filterTitle: '필터 메뉴', filterConfirm: '확인', filterReset: '초기화', - emptyText: '데이터 없음', - selectAll: '전체 선택', - selectInvert: '선택 토글', + selectAll: '모두 선택', + selectInvert: '선택 반전', }, Modal: { okText: '확인', @@ -27,18 +26,17 @@ export default { cancelText: '취소', }, Transfer: { - notFoundContent: '데이터 없음', searchPlaceholder: '여기에 검색하세요', itemUnit: '개', itemsUnit: '개', }, - Select: { - notFoundContent: '데이터 없음', - }, Upload: { uploading: '업로드 중...', removeFile: '파일 삭제', uploadError: '업로드 실패', previewFile: '파일 미리보기', }, + Empty: { + description: '데이터 없음', + }, }; diff --git a/components/i18n/languages/nb_NO.ts b/components/i18n/languages/nb_NO.ts index 1e558475873..1d1607582df 100644 --- a/components/i18n/languages/nb_NO.ts +++ b/components/i18n/languages/nb_NO.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtermeny', filterConfirm: 'OK', filterReset: 'Nullstill', - emptyText: 'Ingen data', selectAll: 'Velg alle', selectInvert: 'Inverter valg', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Avbryt', }, Transfer: { - notFoundContent: 'Ingen treff', searchPlaceholder: 'Søk her', itemUnit: 'element', itemsUnit: 'elementer', }, - Select: { - notFoundContent: 'Ingen treff', - }, Upload: { uploading: 'Laster opp...', removeFile: 'Fjern fil', uploadError: 'Feil ved opplastning', previewFile: 'Forhåndsvisning', }, + Empty: { + description: 'Ingen data', + }, }; diff --git a/components/i18n/languages/nl_BE.ts b/components/i18n/languages/nl_BE.ts index 8c2596f1d72..8ef32ed2ea0 100644 --- a/components/i18n/languages/nl_BE.ts +++ b/components/i18n/languages/nl_BE.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'FilterMenu', filterConfirm: 'OK', filterReset: 'Reset', - emptyText: 'Geen gegevens', selectAll: 'Selecteer huidige pagina', selectInvert: 'Selecteer huidige pagina', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Annuleer', }, Transfer: { - notFoundContent: 'Niet gevonden', searchPlaceholder: 'Zoek hier', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Niet gevonden', - }, Upload: { uploading: 'Uploaden...', removeFile: 'Bestand verwijderen', uploadError: 'Upload fout', previewFile: 'Preview bestand', }, + Empty: { + description: 'Geen gegevens', + }, }; diff --git a/components/i18n/languages/nl_NL.ts b/components/i18n/languages/nl_NL.ts index 0e789b5c72d..ee1f48d3a2a 100644 --- a/components/i18n/languages/nl_NL.ts +++ b/components/i18n/languages/nl_NL.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filteren', filterConfirm: 'OK', filterReset: 'Reset', - emptyText: 'Geen gegevens', selectAll: 'Selecteer huidige pagina', selectInvert: 'Deselecteer huidige pagina', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Annuleren', }, Transfer: { - notFoundContent: 'Niet gevonden', searchPlaceholder: 'Zoeken', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Niet gevonden', - }, Upload: { uploading: 'Uploaden...', removeFile: 'Verwijder bestand', uploadError: 'Fout tijdens uploaden', previewFile: 'Bekijk bestand', }, + Empty: { + description: 'Geen gegevens', + }, }; diff --git a/components/i18n/languages/pl_PL.ts b/components/i18n/languages/pl_PL.ts index a44657f2918..06b7963a0fc 100644 --- a/components/i18n/languages/pl_PL.ts +++ b/components/i18n/languages/pl_PL.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Menu filtra', filterConfirm: 'OK', filterReset: 'Wyczyść', - emptyText: 'Brak danych', selectAll: 'Zaznacz bieżącą stronę', selectInvert: 'Odwróć zaznaczenie', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Anuluj', }, Transfer: { - notFoundContent: 'Nie znaleziono', searchPlaceholder: 'Szukaj', itemUnit: 'obiekt', itemsUnit: 'obiekty', }, - Select: { - notFoundContent: 'Nie znaleziono', - }, Upload: { uploading: 'Wysyłanie...', removeFile: 'Usuń plik', uploadError: 'Błąd wysyłania', previewFile: 'Podejrzyj plik', }, + Empty: { + description: 'Brak danych', + }, }; diff --git a/components/i18n/languages/pt_BR.ts b/components/i18n/languages/pt_BR.ts index fca27e57966..b931d188834 100644 --- a/components/i18n/languages/pt_BR.ts +++ b/components/i18n/languages/pt_BR.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtro', filterConfirm: 'OK', filterReset: 'Resetar', - emptyText: 'Não há dados', selectAll: 'Selecionar página atual', selectInvert: 'Inverter seleção', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Cancelar', }, Transfer: { - notFoundContent: 'Não encontrado', searchPlaceholder: 'Procurar', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Não encontrado', - }, Upload: { uploading: 'Enviando...', removeFile: 'Remover arquivo', uploadError: 'Erro no envio', previewFile: 'Visualizar arquivo', }, + Empty: { + description: 'Não há dados', + }, }; diff --git a/components/i18n/languages/pt_PT.ts b/components/i18n/languages/pt_PT.ts index 2e2296ef5b9..a2ad4cd166c 100644 --- a/components/i18n/languages/pt_PT.ts +++ b/components/i18n/languages/pt_PT.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtro', filterConfirm: 'Aplicar', filterReset: 'Reiniciar', - emptyText: 'Sem resultados', selectAll: 'Selecionar página atual', selectInvert: 'Inverter seleção', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Cancelar', }, Transfer: { - notFoundContent: 'Sem resultados', searchPlaceholder: 'Procurar...', itemUnit: 'item', itemsUnit: 'itens', }, - Select: { - notFoundContent: 'Sem resultados', - }, Upload: { uploading: 'A carregar...', removeFile: 'Remover', uploadError: 'Erro ao carregar', previewFile: 'Pré-visualizar', }, + Empty: { + description: 'Sem resultados', + }, }; diff --git a/components/i18n/languages/ru_RU.ts b/components/i18n/languages/ru_RU.ts index bcc1895ff3b..cae74539733 100644 --- a/components/i18n/languages/ru_RU.ts +++ b/components/i18n/languages/ru_RU.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Фильтр', filterConfirm: 'OK', filterReset: 'Сбросить', - emptyText: 'Нет данных', selectAll: 'Выбрать всё', selectInvert: 'Инвертировать выбор', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Отмена', }, Transfer: { - notFoundContent: 'Ничего не найдено', - searchPlaceholder: 'Введите название для поиска', - itemUnit: 'item', - itemsUnit: 'items', - }, - Select: { - notFoundContent: 'Ничего не найдено', + searchPlaceholder: 'Поиск', + itemUnit: 'элем.', + itemsUnit: 'элем.', }, Upload: { - uploading: 'Закачиваю...', + uploading: 'Загрузка...', removeFile: 'Удалить файл', - uploadError: 'Ошибка при закачке', + uploadError: 'При загрузке произошла ошибка', previewFile: 'Предпросмотр файла', }, + Empty: { + description: 'Нет данных', + }, }; diff --git a/components/i18n/languages/sk_SK.ts b/components/i18n/languages/sk_SK.ts index e64a45c6600..811574e230e 100644 --- a/components/i18n/languages/sk_SK.ts +++ b/components/i18n/languages/sk_SK.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filter', filterConfirm: 'OK', filterReset: 'Obnoviť', - emptyText: 'Žiadne dáta', selectAll: 'Vybrať všetko', selectInvert: 'Vybrať opačné', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Zrušiť', }, Transfer: { - notFoundContent: 'Nenájdené', searchPlaceholder: 'Vyhľadávanie', itemUnit: 'položka', itemsUnit: 'položiek', }, - Select: { - notFoundContent: 'Nenájdené', - }, Upload: { uploading: 'Nahrávanie...', removeFile: 'Odstrániť súbor', uploadError: 'Chyba pri nahrávaní', previewFile: 'Zobraziť súbor', }, + Empty: { + description: 'Žiadne dáta', + }, }; diff --git a/components/i18n/languages/sl_SI.ts b/components/i18n/languages/sl_SI.ts index 779c1d43075..3e2e3120462 100644 --- a/components/i18n/languages/sl_SI.ts +++ b/components/i18n/languages/sl_SI.ts @@ -11,11 +11,10 @@ export default { Calendar, Table: { filterTitle: 'Filter', - filterConfirm: 'Potrdi', - filterReset: 'Ponastavi', - emptyText: 'Ni podataka', - selectAll: 'Izberi trenutno stran', - selectInvert: 'Obrni vrstni red izbora', + filterConfirm: 'Filtriraj', + filterReset: 'Pobriši filter', + selectAll: 'Izberi vse na trenutni strani', + selectInvert: 'Obrni izbor na trenutni strani', }, Modal: { okText: 'V redu', @@ -23,17 +22,13 @@ export default { justOkText: 'V redu', }, Popconfirm: { - okText: 'V redu', + okText: 'v redu', cancelText: 'Prekliči', }, Transfer: { - notFoundContent: 'Ni zadetkov', searchPlaceholder: 'Išči tukaj', - itemUnit: 'vnos', - itemsUnit: 'vnosi', - }, - Select: { - notFoundContent: 'Ni zadetkov', + itemUnit: 'Objekt', + itemsUnit: 'Objektov', }, Upload: { uploading: 'Nalaganje...', @@ -41,4 +36,7 @@ export default { uploadError: 'Napaka pri nalaganju', previewFile: 'Predogled datoteke', }, + Empty: { + description: 'Ni podatkov', + }, }; diff --git a/components/i18n/languages/sr_RS.ts b/components/i18n/languages/sr_RS.ts index 8cc3dd78da0..5eb78230591 100644 --- a/components/i18n/languages/sr_RS.ts +++ b/components/i18n/languages/sr_RS.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filter', filterConfirm: 'Primeni filter', filterReset: 'Resetuj filter', - emptyText: 'Nema podataka', selectAll: 'Obeleži sve na trenutnoj strani', selectInvert: 'Obrni selekciju na trenutnoj stranici', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Otkaži', }, Transfer: { - notFoundContent: 'Nisu pronađeni rezultati pretrage', searchPlaceholder: 'Pretražite ovde', itemUnit: 'stavka', itemsUnit: 'stavki', }, - Select: { - notFoundContent: 'Nije pronađeno', - }, Upload: { uploading: 'Slanje...', removeFile: 'Ukloni fajl', uploadError: 'Greška prilikom slanja', previewFile: 'Pogledaj fajl', }, + Empty: { + description: 'Nema podataka', + }, }; diff --git a/components/i18n/languages/sv_SE.ts b/components/i18n/languages/sv_SE.ts index acac36098a4..f37f0a5ee83 100644 --- a/components/i18n/languages/sv_SE.ts +++ b/components/i18n/languages/sv_SE.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Filtermeny', filterConfirm: 'OK', filterReset: 'Rensa', - emptyText: 'Ingen information', }, Modal: { okText: 'OK', @@ -25,12 +24,11 @@ export default { cancelText: 'Avbryt', }, Transfer: { - notFoundContent: 'Info saknas', searchPlaceholder: 'Sök', itemUnit: 'element', itemsUnit: 'element', }, - Select: { - notFoundContent: 'Info saknas', + Empty: { + description: 'Ingen information', }, }; diff --git a/components/i18n/languages/th_TH.ts b/components/i18n/languages/th_TH.ts index e72f5855442..4c7e6a469b6 100644 --- a/components/i18n/languages/th_TH.ts +++ b/components/i18n/languages/th_TH.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'ตัวกรอง', filterConfirm: 'ยืนยัน', filterReset: 'รีเซ็ต', - emptyText: 'ไม่มีข้อมูล', selectAll: 'เลือกทั้งหมดในหน้านี้', selectInvert: 'เลือกสถานะตรงกันข้าม', }, @@ -27,18 +26,17 @@ export default { cancelText: 'ยกเลิก', }, Transfer: { - notFoundContent: 'ไม่พบข้อมูล', searchPlaceholder: 'ค้นหา', itemUnit: 'ชิ้น', itemsUnit: 'ชิ้น', }, - Select: { - notFoundContent: 'ไม่พบข้อมูล', - }, Upload: { uploading: 'กำลังอัปโหลด...', removeFile: 'ลบไฟล์', uploadError: 'เกิดข้อผิดพลาดในการอัปโหลด', previewFile: 'ดูตัวอย่างไฟล์', }, + Empty: { + description: 'ไม่มีข้อมูล', + }, }; diff --git a/components/i18n/languages/tr_TR.ts b/components/i18n/languages/tr_TR.ts index b5d28aa930f..dc81e24e8f7 100644 --- a/components/i18n/languages/tr_TR.ts +++ b/components/i18n/languages/tr_TR.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Menü Filtrele', filterConfirm: 'Tamam', filterReset: 'Sıfırla', - emptyText: 'Veri Yok', selectAll: 'Hepsini Seç', selectInvert: 'Tersini Seç', }, @@ -27,18 +26,17 @@ export default { cancelText: 'İptal', }, Transfer: { - notFoundContent: 'Bulunamadı', searchPlaceholder: 'Arama', itemUnit: 'Öğe', itemsUnit: 'Öğeler', }, - Select: { - notFoundContent: 'Bulunamadı', - }, Upload: { uploading: 'Yükleniyor...', removeFile: `Dosyayı kaldır`, uploadError: 'Yükleme Hatası', previewFile: `Dosyayı Önizle`, }, + Empty: { + description: 'Veri Yok', + }, }; diff --git a/components/i18n/languages/uk_UA.ts b/components/i18n/languages/uk_UA.ts index ae0c7768540..43b18aafb3a 100644 --- a/components/i18n/languages/uk_UA.ts +++ b/components/i18n/languages/uk_UA.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Фільтрувати', filterConfirm: 'OK', filterReset: 'Скинути', - emptyText: 'Даних немає', selectAll: 'Обрати всі', selectInvert: 'Інвертувати вибір', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Скасувати', }, Transfer: { - notFoundContent: 'Нічого не знайдено', searchPlaceholder: 'Введіть текст для пошуку', itemUnit: 'item', itemsUnit: 'items', }, - Select: { - notFoundContent: 'Нічого не знайдено', - }, Upload: { uploading: 'Завантаження ...', removeFile: 'Видалити файл', uploadError: 'Помилка завантаження', previewFile: 'Попередній перегляд файлу', }, + Empty: { + description: 'Даних немає', + }, }; diff --git a/components/i18n/languages/vi_VN.ts b/components/i18n/languages/vi_VN.ts index a8017c4b9fd..7e57e2bc6ee 100644 --- a/components/i18n/languages/vi_VN.ts +++ b/components/i18n/languages/vi_VN.ts @@ -13,7 +13,6 @@ export default { filterTitle: 'Bộ ', filterConfirm: 'OK', filterReset: 'Tạo Lại', - emptyText: 'Trống', selectAll: 'Chọn Tất Cả', selectInvert: 'Chọn Ngược Lại', }, @@ -27,18 +26,17 @@ export default { cancelText: 'Huỷ', }, Transfer: { - notFoundContent: 'Không Tìm Thấy', searchPlaceholder: 'Tìm ở đây', itemUnit: 'mục', itemsUnit: 'mục', }, - Select: { - notFoundContent: 'Không Tìm Thấy', - }, Upload: { uploading: 'Đang tải lên...', removeFile: 'Gỡ bỏ tập tin', uploadError: 'Lỗi tải lên', previewFile: 'Xem thử tập tin', }, + Empty: { + description: 'Trống', + }, }; diff --git a/components/i18n/languages/zh_CN.ts b/components/i18n/languages/zh_CN.ts index 218c3d2aeb6..156419ce278 100644 --- a/components/i18n/languages/zh_CN.ts +++ b/components/i18n/languages/zh_CN.ts @@ -9,13 +9,17 @@ export default { DatePicker, TimePicker, Calendar, + // locales for all comoponents + global: { + placeholder: '请选择', + }, Table: { filterTitle: '筛选', filterConfirm: '确定', filterReset: '重置', - emptyText: '暂无数据', selectAll: '全选当页', selectInvert: '反选当页', + sortTitle: '排序', }, Modal: { okText: '确定', @@ -27,18 +31,17 @@ export default { okText: '确定', }, Transfer: { - notFoundContent: '无匹配结果', searchPlaceholder: '请输入搜索内容', itemUnit: '项', itemsUnit: '项', }, - Select: { - notFoundContent: '无匹配结果', - }, Upload: { uploading: '文件上传中', removeFile: '删除文件', uploadError: '上传错误', previewFile: '预览文件', }, + Empty: { + description: '暂无数据', + }, }; diff --git a/components/i18n/languages/zh_TW.ts b/components/i18n/languages/zh_TW.ts index 7381666c6cd..87eeb9c8a6a 100644 --- a/components/i18n/languages/zh_TW.ts +++ b/components/i18n/languages/zh_TW.ts @@ -13,7 +13,6 @@ export default { filterTitle: '篩選器', filterConfirm: '確 定', filterReset: '重 置', - emptyText: '目前尚無資料', selectAll: '全部選取', selectInvert: '反向選取', }, @@ -27,18 +26,17 @@ export default { cancelText: '取 消', }, Transfer: { - notFoundContent: '查無此資料', searchPlaceholder: '搜尋資料', itemUnit: '項目', itemsUnit: '項目', }, - Select: { - notFoundContent: '查無此資料', - }, Upload: { uploading: '正在上傳...', removeFile: '刪除檔案', uploadError: '上傳失敗', previewFile: '檔案預覽', }, + Empty: { + description: '無此資料', + }, }; diff --git a/components/i18n/nz-i18n.interface.ts b/components/i18n/nz-i18n.interface.ts index fed5f5bbab7..806b247a041 100644 --- a/components/i18n/nz-i18n.interface.ts +++ b/components/i18n/nz-i18n.interface.ts @@ -66,7 +66,6 @@ export interface NzI18nInterface { filterTitle: string; filterConfirm: string; filterReset: string; - emptyText: string; selectAll: string; selectInvert: string; }; @@ -81,18 +80,17 @@ export interface NzI18nInterface { }; Transfer: { titles?: string[]; - notFoundContent: string; searchPlaceholder: string; itemUnit: string; itemsUnit: string; }; - Select: { - notFoundContent: string; - }; Upload: { uploading: string; removeFile: string; uploadError: string; previewFile: string; }; + Empty: { + description: string; + }; } diff --git a/components/list/doc/index.en-US.md b/components/list/doc/index.en-US.md index 98891b91d8b..d412218593b 100644 --- a/components/list/doc/index.en-US.md +++ b/components/list/doc/index.en-US.md @@ -26,6 +26,7 @@ A list can be used to display content related to a single subject. The content c | `[nzItemLayout]` | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - | | `[nzLoading]` | Shows a loading indicator while the contents of the list are being fetched | boolean | false | | `[nzLoadMore]` | Shows a load more content | `TemplateRef` | - | +| `[nzNoResult]` | Specify content to show when list is empty | `string` | `TemplateRef` | - | | `[nzPagination]` | Shows a pagination content | `TemplateRef` | - | | `[nzSize]` | Size of list | `default,small,large` | `default` | | `[nzSplit]` | Toggles rendering of the split under the list item | boolean | true | diff --git a/components/list/doc/index.zh-CN.md b/components/list/doc/index.zh-CN.md index 7f539678059..4bc46250a80 100644 --- a/components/list/doc/index.zh-CN.md +++ b/components/list/doc/index.zh-CN.md @@ -27,6 +27,7 @@ cols: 1 | `[nzItemLayout]` | 设置 `nz-list-item` 布局, 设置成 `vertical` 则竖直样式显示, 默认横排 | string | - | | `[nzLoading]` | 当卡片内容还在加载中时,可以用 `loading` 展示一个占位 | boolean | false | | `[nzLoadMore]` | 加载更多 | `TemplateRef` | - | +| `[nzNoResult]` | 当列表为空时加载的内容 | `string` | `TemplateRef` | - | | `[nzPagination]` | 对应的 `pagination` 配置 | `TemplateRef` | - | | `[nzSize]` | list 的尺寸 | `default,small,large` | `default` | | `[nzSplit]` | 是否展示分割线 | boolean | true | diff --git a/components/list/list.spec.ts b/components/list/list.spec.ts index 6a066f49a75..c7df7592629 100644 --- a/components/list/list.spec.ts +++ b/components/list/list.spec.ts @@ -22,12 +22,6 @@ describe('list', () => { fixture.detectChanges(); }); - afterEach(() => { - if (context.comp != null) { - context.comp.ngOnDestroy(); - } - }); - describe('[fields]', () => { describe('#nzItemLayout', () => { diff --git a/components/list/nz-list.component.html b/components/list/nz-list.component.html index 0d3aa679f98..05b6447967b 100644 --- a/components/list/nz-list.component.html +++ b/components/list/nz-list.component.html @@ -16,7 +16,7 @@
    - {{locale.emptyText}} +
    diff --git a/components/list/nz-list.component.ts b/components/list/nz-list.component.ts index 0226a209842..b1b98777cfb 100644 --- a/components/list/nz-list.component.ts +++ b/components/list/nz-list.component.ts @@ -5,17 +5,14 @@ import { ElementRef, Input, OnChanges, - OnDestroy, OnInit, TemplateRef, ViewEncapsulation } from '@angular/core'; -import { Subscription } from 'rxjs'; import { NzUpdateHostClassService } from '../core/services/update-host-class.service'; import { NzSizeLDSType } from '../core/types/size'; import { InputBoolean } from '../core/util/convert'; -import { NzI18nService } from '../i18n/nz-i18n.service'; import { NzListGrid } from './interface'; @@ -32,10 +29,7 @@ import { NzListGrid } from './interface'; } ` ] }) -export class NzListComponent implements OnInit, OnChanges, OnDestroy { - /* tslint:disable-next-line:no-any */ - locale: any = {}; - private i18n$: Subscription; +export class NzListComponent implements OnInit, OnChanges { // #region fields // tslint:disable-next-line:no-any @@ -63,6 +57,8 @@ export class NzListComponent implements OnInit, OnChanges, OnDestroy { @Input() @InputBoolean() nzSplit = true; + @Input() nzNoResult: string | TemplateRef; + // #endregion // #region styles @@ -86,22 +82,14 @@ export class NzListComponent implements OnInit, OnChanges, OnDestroy { // #endregion - constructor(private el: ElementRef, private cd: ChangeDetectorRef, private updateHostClassService: NzUpdateHostClassService, private i18n: NzI18nService) { + constructor(private el: ElementRef, private cd: ChangeDetectorRef, private updateHostClassService: NzUpdateHostClassService) { } ngOnInit(): void { - this.i18n$ = this.i18n.localeChange.subscribe(() => { - this.locale = this.i18n.getLocaleData('Table'); - this.cd.detectChanges(); - }); this._setClassMap(); } ngOnChanges(): void { this._setClassMap(); } - - ngOnDestroy(): void { - this.i18n$.unsubscribe(); - } } diff --git a/components/list/nz-list.module.ts b/components/list/nz-list.module.ts index 0148a13c8d3..59e43a14c87 100644 --- a/components/list/nz-list.module.ts +++ b/components/list/nz-list.module.ts @@ -3,8 +3,8 @@ import { NgModule } from '@angular/core'; import { NzAvatarModule } from '../avatar/nz-avatar.module'; import { NzAddOnModule } from '../core/addon/addon.module'; +import { NzEmptyModule } from '../empty/nz-empty.module'; import { NzGridModule } from '../grid/nz-grid.module'; -import { NzI18nModule } from '../i18n/nz-i18n.module'; import { NzSpinModule } from '../spin/nz-spin.module'; import { NzListItemMetaComponent } from './nz-list-item-meta.component'; @@ -12,9 +12,24 @@ import { NzListItemComponent } from './nz-list-item.component'; import { NzListComponent } from './nz-list.component'; @NgModule({ - imports: [ CommonModule, NzSpinModule, NzGridModule, NzAvatarModule, NzI18nModule, NzAddOnModule ], - declarations: [ NzListComponent, NzListItemComponent, NzListItemMetaComponent ], - exports: [ NzListComponent, NzListItemComponent, NzListItemMetaComponent ] + imports : [ + CommonModule, + NzSpinModule, + NzGridModule, + NzAvatarModule, + NzAddOnModule, + NzEmptyModule + ], + declarations: [ + NzListComponent, + NzListItemComponent, + NzListItemMetaComponent + ], + exports : [ + NzListComponent, + NzListItemComponent, + NzListItemMetaComponent + ] }) export class NzListModule { } diff --git a/components/ng-zorro-antd.module.ts b/components/ng-zorro-antd.module.ts index 2d680788d2a..4425b4dbf03 100644 --- a/components/ng-zorro-antd.module.ts +++ b/components/ng-zorro-antd.module.ts @@ -20,6 +20,7 @@ import { NzDatePickerModule } from './date-picker/date-picker.module'; import { NzDividerModule } from './divider/nz-divider.module'; import { NzDrawerModule } from './drawer/nz-drawer.module'; import { NzDropDownModule } from './dropdown/nz-dropdown.module'; +import { NzEmptyModule } from './empty/nz-empty.module'; import { NzFormModule } from './form/nz-form.module'; import { NzGridModule } from './grid/nz-grid.module'; import { NzI18nModule } from './i18n/nz-i18n.module'; @@ -74,6 +75,7 @@ export * from './divider'; export * from './drawer'; export * from './dropdown'; export * from './drawer'; +export * from './empty'; export * from './form'; export * from './grid'; export * from './i18n'; @@ -172,7 +174,8 @@ export * from './core/util'; NzTreeSelectModule, NzTimePickerModule, NzWaveModule, - NzSkeletonModule + NzSkeletonModule, + NzEmptyModule ] }) export class NgZorroAntdModule { diff --git a/components/select/nz-option-container.component.html b/components/select/nz-option-container.component.html index 4014aae9e24..792a1752111 100644 --- a/components/select/nz-option-container.component.html +++ b/components/select/nz-option-container.component.html @@ -9,7 +9,7 @@ *ngIf="isNotFoundDisplay" nz-select-unselectable class="ant-select-dropdown-menu-item ant-select-dropdown-menu-item-disabled"> - {{ nzNotFoundContent ? nzNotFoundContent : ('Select.notFoundContent' | nzI18n) }} +
  • - {{ locale.emptyText }} - - {{ nzNoResult }} - - - - +
  • -
    {{ notFoundContent }}
    +
    + +