diff --git a/components/cron-expression/cron-expression-input.component.ts b/components/cron-expression/cron-expression-input.component.ts new file mode 100644 index 00000000000..0d9c3c9271a --- /dev/null +++ b/components/cron-expression/cron-expression-input.component.ts @@ -0,0 +1,49 @@ +/** + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE + */ + +import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core'; + +import { CronChangeType, TimeType } from './typings'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, + selector: 'nz-cron-expression-input', + exportAs: 'nzCronExpression', + template: ` +
+ +
+ ` +}) +export class NzCronExpressionInputComponent { + @Input() value: string = '0'; + @Input() label: TimeType = 'second'; + @Output() readonly focusEffect = new EventEmitter(); + @Output() readonly blurEffect = new EventEmitter(); + @Output() readonly getValue = new EventEmitter(); + + constructor() {} + + focusInputEffect(event: FocusEvent): void { + this.focusEffect.emit(this.label); + (event.target as HTMLInputElement).select(); + } + + blurInputEffect(): void { + this.blurEffect.emit(); + } + + setValue(): void { + this.getValue.emit({ label: this.label, value: this.value }); + } +} diff --git a/components/cron-expression/cron-expression-label.component.ts b/components/cron-expression/cron-expression-label.component.ts new file mode 100644 index 00000000000..be98dfd1e87 --- /dev/null +++ b/components/cron-expression/cron-expression-label.component.ts @@ -0,0 +1,44 @@ +/** + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE + */ + +import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, OnInit } from '@angular/core'; + +import { NzCronExpressionLabelI18n } from 'ng-zorro-antd/i18n'; + +import { TimeType, TimeTypeError } from './typings'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, + selector: 'nz-cron-expression-label', + exportAs: 'nzCronExpression', + template: ` +
+ +
+ +
+
+ ` +}) +export class NzCronExpressionLabelComponent implements OnInit { + @Input() type: TimeType = 'second'; + @Input() valid: boolean = true; + @Input() locale!: NzCronExpressionLabelI18n; + @Input() labelFocus: string | null = null; + labelError: TimeTypeError = 'secondError'; + + constructor() {} + + ngOnInit(): void { + this.labelError = `${this.type}Error`; + } +} diff --git a/components/cron-expression/cron-expression-specialized.component.ts b/components/cron-expression/cron-expression-specialized.component.ts deleted file mode 100644 index e0e08b95002..00000000000 --- a/components/cron-expression/cron-expression-specialized.component.ts +++ /dev/null @@ -1,379 +0,0 @@ -/** - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE - */ - -import { - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - forwardRef, - Input, - OnDestroy, - OnInit, - ViewEncapsulation -} from '@angular/core'; -import { - ControlValueAccessor, - FormControl, - NG_ASYNC_VALIDATORS, - NG_VALUE_ACCESSOR, - UntypedFormBuilder, - UntypedFormGroup, - ValidationErrors, - Validators -} from '@angular/forms'; -import { Observable, of, Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; - -import { parseExpression } from 'cron-parser'; - -import { NzSafeAny } from 'ng-zorro-antd/core/types'; -import { NzCronExpressionI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n'; - -import { CronType, NzCronExpressionSize } from './typings'; - -@Component({ - changeDetection: ChangeDetectionStrategy.OnPush, - encapsulation: ViewEncapsulation.None, - selector: 'nz-cron-expression-specialized', - exportAs: 'nzCronExpressionSpecialized', - template: ` -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - - -

- {{ dateItem | date: 'YYYY-MM-dd HH:mm:ss' }} -

-
- {{ locale.cronError }} -
-
-
-
- -
-
-
- - - - {{ dateTime | date: 'YYYY-MM-dd HH:mm:ss' }} - - {{ locale.cronError }} - - - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- `, - providers: [ - { - provide: NG_ASYNC_VALIDATORS, - useExisting: forwardRef(() => NzCronExpressionSpecializedComponent), - multi: true - }, - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => NzCronExpressionSpecializedComponent), - multi: true - } - ] -}) -export class NzCronExpressionSpecializedComponent implements OnInit, ControlValueAccessor, OnDestroy { - validateForm!: UntypedFormGroup; - locale!: NzCronExpressionI18nInterface; - focus: boolean = false; - labelFocus: string | null = null; - - @Input() nzSize: NzCronExpressionSize = 'default'; - @Input() nzCronType: 'linux' | 'spring' = 'linux'; - @Input() nzCollapseDisable: boolean = false; - - private destroy$ = new Subject(); - - nextTimeList: Date[] = []; - dateTime: Date = new Date(); - - second = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`${control.value} * * * * *`); - } catch (err: unknown) { - return of({ error: true }); - } - } - return of(null); - }; - - minute = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`* ${control.value} * * * *`); - } catch (err: unknown) { - return of({ error: true }); - } - } - return of(null); - }; - - hour = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`* * ${control.value} * * *`); - } catch (err: unknown) { - return of({ error: true }); - } - } - return of(null); - }; - - day = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`* * * ${control.value} * *`); - } catch (err: unknown) { - return of({ error: true }); - } - } - return of(null); - }; - - month = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`* * * * ${control.value} *`); - } catch (err: unknown) { - return of({ error: true }); - } - } - return of(null); - }; - - week = (control: FormControl): Observable => { - if (control.value) { - try { - parseExpression(`* * * * * ${control.value}`); - } catch (err: unknown) { - return of({ error: true }); - } - return of(null); - } else { - return of({ error: true }); - } - }; - - constructor(private formBuilder: UntypedFormBuilder, private cdr: ChangeDetectorRef, private i18n: NzI18nService) {} - - onChange: NzSafeAny = () => {}; - onTouch: () => void = () => null; - - writeValue(value: CronType): void { - this.validateForm.patchValue(value); - } - - registerOnChange(fn: NzSafeAny): void { - this.onChange = fn; - } - - registerOnTouched(fn: NzSafeAny): void { - this.onTouch = fn; - } - - validate(): Observable<{ error: boolean } | null> { - if (!this.validateForm.valid) { - return of({ error: true }); - } - return of(null); - } - - ngOnInit(): void { - if (this.nzCronType === 'spring') { - this.validateForm = this.formBuilder.group({ - second: ['0', Validators.required, this.second], - minute: ['*', Validators.required, this.minute], - hour: ['*', Validators.required, this.hour], - day: ['*', Validators.required, this.day], - month: ['*', Validators.required, this.month], - week: ['?', Validators.required, this.week] - }); - } else { - this.validateForm = this.formBuilder.group({ - minute: ['*', Validators.required, this.minute], - hour: ['*', Validators.required, this.hour], - day: ['*', Validators.required, this.day], - month: ['*', Validators.required, this.month], - week: ['?', Validators.required, this.week] - }); - } - - this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => { - this.locale = this.i18n.getLocaleData('CronExpression'); - this.cdr.markForCheck(); - }); - this.validateForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(item => { - this.onChange(item); - try { - const interval = parseExpression(Object.values(item).join(' ')); - this.dateTime = new Date(interval.next().toString()); - this.nextTimeList = [ - new Date(interval.next().toString()), - new Date(interval.next().toString()), - new Date(interval.next().toString()), - new Date(interval.next().toString()), - new Date(interval.next().toString()) - ]; - } catch (err: NzSafeAny) { - return; - } - }); - } - - focusColor(value: string): void { - this.focus = true; - this.labelFocus = value; - this.cdr.markForCheck(); - } - - blurColor(): void { - this.focus = false; - this.labelFocus = null; - this.cdr.markForCheck(); - } - - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); - } -} diff --git a/components/cron-expression/cron-expression.component.ts b/components/cron-expression/cron-expression.component.ts index 5f318483ddd..420776b0688 100644 --- a/components/cron-expression/cron-expression.component.ts +++ b/components/cron-expression/cron-expression.component.ts @@ -5,23 +5,36 @@ import { ChangeDetectionStrategy, + ChangeDetectorRef, Component, forwardRef, Input, - OnChanges, OnDestroy, OnInit, - SimpleChanges, + TemplateRef, ViewEncapsulation } from '@angular/core'; -import { NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { + AsyncValidator, + ControlValueAccessor, + FormControl, + NG_ASYNC_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + ValidationErrors, + Validators +} from '@angular/forms'; import { Observable, of, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { CronExpression, parseExpression } from 'cron-parser'; + import { NzSafeAny } from 'ng-zorro-antd/core/types'; -import { NzCronExpressionI18nInterface } from 'ng-zorro-antd/i18n'; +import { InputBoolean } from 'ng-zorro-antd/core/util'; +import { NzCronExpressionI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n'; -import { CronType, NzCronExpressionSize } from './typings'; +import { CronChangeType, CronType, NzCronExpressionSize, TimeType } from './typings'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -29,16 +42,60 @@ import { CronType, NzCronExpressionSize } from './typings'; selector: 'nz-cron-expression', exportAs: 'nzCronExpression', template: ` -
- - - -
+
+
+
+ + + +
+
+ + + +
+ + + +
    +
  • + {{ dateItem | date: 'YYYY-MM-dd HH:mm:ss' }} +
  • +
  • ···
  • +
+
+ {{ locale.cronError }} +
+
+
+
+ +
+ + + {{ dateTime | date: 'YYYY-MM-dd HH:mm:ss' }} + + {{ locale.cronError }} + +
`, providers: [ { @@ -53,12 +110,20 @@ import { CronType, NzCronExpressionSize } from './typings'; } ] }) -export class NzCronExpressionComponent implements OnInit, OnChanges, OnDestroy { - locale!: NzCronExpressionI18nInterface; - @Input() defaults: string | null = null; +export class NzCronExpressionComponent implements OnInit, ControlValueAccessor, AsyncValidator, OnDestroy { @Input() nzSize: NzCronExpressionSize = 'default'; - @Input() nzCronType: 'linux' | 'spring' = 'linux'; - @Input() nzCollapseDisable: boolean = false; + @Input() nzType: 'linux' | 'spring' = 'linux'; + @Input() @InputBoolean() nzCollapseDisable: boolean = false; + @Input() nzExtra?: TemplateRef | null = null; + + locale!: NzCronExpressionI18nInterface; + focus: boolean = false; + labelFocus: TimeType | null = null; + validLabel: string | null = null; + labels: TimeType[] = []; + interval!: CronExpression; + nextTimeList: Date[] = []; + dateTime: Date = new Date(); private destroy$ = new Subject(); validateForm!: UntypedFormGroup; @@ -66,19 +131,18 @@ export class NzCronExpressionComponent implements OnInit, OnChanges, OnDestroy { onChange: NzSafeAny = () => {}; onTouch: () => void = () => null; - convertFormat(value: string): CronType { + convertFormat(value: string): void { const values = value.split(' '); - const keys = Object.keys(this.validateForm.controls.specialized.value); const valueObject: CronType = {}; - keys.map((a, b) => { + this.labels.map((a, b) => { valueObject[a] = values[b]; }); - return valueObject; + this.validateForm.patchValue(valueObject); } writeValue(value: string | null): void { if (value) { - this.validateForm.controls.specialized.patchValue(this.convertFormat(value)); + this.convertFormat(value); } } @@ -90,39 +154,112 @@ export class NzCronExpressionComponent implements OnInit, OnChanges, OnDestroy { this.onTouch = fn; } - validate(): Observable<{ error: boolean } | null> { - if (this.validateForm.controls.specialized.valid) { + validate(): Observable { + if (this.validateForm.valid) { return of(null); } else { return of({ error: true }); } } - constructor(private formBuilder: UntypedFormBuilder) {} + constructor(private formBuilder: UntypedFormBuilder, private cdr: ChangeDetectorRef, private i18n: NzI18nService) {} ngOnInit(): void { - if (this.nzCronType === 'spring') { + if (this.nzType === 'spring') { + this.labels = ['second', 'minute', 'hour', 'day', 'month', 'week']; this.validateForm = this.formBuilder.group({ - specialized: { second: '0', minute: '*', hour: '*', day: '*', month: '*', week: '*' } + second: ['0', Validators.required, this.checkValid], + minute: ['*', Validators.required, this.checkValid], + hour: ['*', Validators.required, this.checkValid], + day: ['*', Validators.required, this.checkValid], + month: ['*', Validators.required, this.checkValid], + week: ['*', Validators.required, this.checkValid] }); } else { + this.labels = ['minute', 'hour', 'day', 'month', 'week']; this.validateForm = this.formBuilder.group({ - specialized: { minute: '*', hour: '*', day: '*', month: '*', week: '*' } + minute: ['*', Validators.required, this.checkValid], + hour: ['*', Validators.required, this.checkValid], + day: ['*', Validators.required, this.checkValid], + month: ['*', Validators.required, this.checkValid], + week: ['*', Validators.required, this.checkValid] }); } + this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => { + this.locale = this.i18n.getLocaleData('CronExpression'); + this.cdr.markForCheck(); + }); + + this.previewDate(this.validateForm.value); - this.validateForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(item => { - this.onChange(Object.values(item.specialized).join(' ')); + this.validateForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => { + this.onChange(Object.values(value).join(' ')); + this.previewDate(value); + this.cdr.markForCheck(); }); } - ngOnChanges(changes: SimpleChanges): void { - const { defaults } = changes; - if (defaults && this.defaults) { - this.validateForm.controls.specialized.patchValue(this.convertFormat(this.defaults)); + previewDate(value: CronType): void { + try { + this.interval = parseExpression(Object.values(value).join(' ')); + this.dateTime = this.interval.next().toDate(); + this.nextTimeList = [ + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate() + ]; + } catch (err: NzSafeAny) { + return; } } + loadMorePreview(): void { + this.nextTimeList = [ + ...this.nextTimeList, + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate(), + this.interval.next().toDate() + ]; + this.cdr.markForCheck(); + } + + focusEffect(value: TimeType): void { + this.focus = true; + this.labelFocus = value; + this.cdr.markForCheck(); + } + + blurEffect(): void { + this.focus = false; + this.labelFocus = null; + this.cdr.markForCheck(); + } + + getValue(item: CronChangeType): void { + this.validLabel = item.label; + this.validateForm.controls[item.label].patchValue(item.value); + this.cdr.markForCheck(); + } + + checkValid = (control: FormControl): Observable => { + if (control.value) { + try { + const cron: string[] = []; + this.labels.forEach(label => { + label === this.validLabel ? cron.push(control.value) : cron.push('*'); + }); + parseExpression(cron.join(' ')); + } catch (err: unknown) { + return of({ error: true }); + } + } + return of(null); + }; + ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); diff --git a/components/cron-expression/cron-expression.module.ts b/components/cron-expression/cron-expression.module.ts index 593dde70909..99a837ef0dc 100644 --- a/components/cron-expression/cron-expression.module.ts +++ b/components/cron-expression/cron-expression.module.ts @@ -3,9 +3,10 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ +import { ScrollingModule } from '@angular/cdk/scrolling'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { NzCollapseModule } from 'ng-zorro-antd/collapse'; import { NzFormModule } from 'ng-zorro-antd/form'; @@ -13,11 +14,12 @@ import { NzIconModule } from 'ng-zorro-antd/icon'; import { NzInputModule } from 'ng-zorro-antd/input'; import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; -import { NzCronExpressionSpecializedComponent } from './cron-expression-specialized.component'; +import { NzCronExpressionInputComponent } from './cron-expression-input.component'; +import { NzCronExpressionLabelComponent } from './cron-expression-label.component'; import { NzCronExpressionComponent } from './cron-expression.component'; @NgModule({ - declarations: [NzCronExpressionComponent, NzCronExpressionSpecializedComponent], + declarations: [NzCronExpressionComponent, NzCronExpressionLabelComponent, NzCronExpressionInputComponent], imports: [ CommonModule, ReactiveFormsModule, @@ -25,7 +27,9 @@ import { NzCronExpressionComponent } from './cron-expression.component'; NzCollapseModule, NzFormModule, NzInputModule, - NzIconModule + NzIconModule, + FormsModule, + ScrollingModule ], exports: [NzCronExpressionComponent] }) diff --git a/components/cron-expression/demo/collapse.md b/components/cron-expression/demo/collapse.md index 4225fa00651..49a251e74b1 100644 --- a/components/cron-expression/demo/collapse.md +++ b/components/cron-expression/demo/collapse.md @@ -4,3 +4,11 @@ title: zh-CN: 隐藏折叠面板 en-US: Hide Collapse --- + +## zh-CN + +`[nzCollapseDisable]="true"` + +## en-US + +`[nzCollapseDisable]="true"` \ No newline at end of file diff --git a/components/cron-expression/demo/shortcuts.md b/components/cron-expression/demo/shortcuts.md index 6354addfdc8..414a555261a 100644 --- a/components/cron-expression/demo/shortcuts.md +++ b/components/cron-expression/demo/shortcuts.md @@ -1,6 +1,14 @@ --- order: 4 title: - zh-CN: 设置快捷操作 - en-US: Shortcuts ---- \ No newline at end of file + zh-CN: 额外节点 + en-US: Extra Node +--- + +## zh-CN + +你可以通过 nzExtra 来指定右侧的内容。 + +## en-US + +You can use nzExtra to specify the content on the right. \ No newline at end of file diff --git a/components/cron-expression/demo/shortcuts.ts b/components/cron-expression/demo/shortcuts.ts index a7fe2ab30cb..c61cbd51bb2 100644 --- a/components/cron-expression/demo/shortcuts.ts +++ b/components/cron-expression/demo/shortcuts.ts @@ -3,23 +3,30 @@ import { Component } from '@angular/core'; @Component({ selector: 'nz-demo-cron-expression-shortcuts', template: ` - -
    -
  • {{ +
  • {{ item.label }}
-
+ +

cron: {{ cron }}

` }) export class NzDemoCronExpressionShortcutsComponent { - defaults: string | null = null; + value: string = '1 1 * * *'; + cron: string = ''; options = [ { label: 'Every hour', @@ -35,7 +42,11 @@ export class NzDemoCronExpressionShortcutsComponent { } ]; - Shortcuts(value: string): void { - this.defaults = value; + setValue(value: string): void { + this.value = value; + } + + getValue(value: string): void { + this.cron = value; } } diff --git a/components/cron-expression/demo/type.md b/components/cron-expression/demo/type.md index c34d649b75f..e642cf8b8b6 100644 --- a/components/cron-expression/demo/type.md +++ b/components/cron-expression/demo/type.md @@ -7,8 +7,8 @@ title: ## zh-CN -我们为 `nz-cron-expression` 输入框定义了两种规则类型(五段式, 六段式),分别为: `nzCronType="linux"`、`nzCronType="spring"`。 +我们为 `nz-cron-expression` 输入框定义了两种规则类型(五段式, 六段式),分别为: `nzType="linux"`、`nzType="spring"`。 ## en-US -There are two rule types of an CronExpression box: `nzCronType="linux"` (five-segment) and`nzCronType="spring"` (six-segment). +There are two rule types of an CronExpression box: `nzType="linux"` (five-segment) and`nzType="spring"` (six-segment). diff --git a/components/cron-expression/demo/type.ts b/components/cron-expression/demo/type.ts index f90d9c617fa..40c5b858bcb 100644 --- a/components/cron-expression/demo/type.ts +++ b/components/cron-expression/demo/type.ts @@ -4,8 +4,8 @@ import { Component } from '@angular/core'; selector: 'nz-demo-cron-expression-type', template: `
- - + +
`, styles: [ diff --git a/components/cron-expression/doc/index.en-US.md b/components/cron-expression/doc/index.en-US.md index b8c3996cc90..c756a098cc8 100644 --- a/components/cron-expression/doc/index.en-US.md +++ b/components/cron-expression/doc/index.en-US.md @@ -32,10 +32,9 @@ npm install cron-parser ### nz-cron-expression -| Parameter | Description | Type | Default | -|-------------|---------------|-------------|---------| -| `[nzSize]` | The size of the input box. | `'large'|'small'|'default'` | `default` | -| `[nzCronType]` | Set cron rule type, optional value is `linux` and `spring` or not set | `'linux'|'spring'` | `linux` | -| `[nzVisible]` | Hide quick settings | `boolean` | `false` | -| `[nzType]` | can be set to `primary` `dashed` `text` `link` or omitted, Takes effect when `[nzVisible]=false` | `'primary'|'dashed'|'link'|'text'` | - | -| `[nzOptions]` | Options for Modifying Quick Settings, Takes effect when `[nzVisible]=false` | `NzCronOptions` | - | +| Parameter | Description | Type | Default | +|-------------|--------------------------------------------------|-------------|---------| +| `[nzType]` | Cron rule type | `'linux'|'spring'` | `linux` | +| `[nzSize]` | The size of the input box. | `'large'|'small'|'default'` | `default` | +| `[nzCollapseDisable]` | Hide collapse | `boolean` | `false` | +| `[nzExtra]` | Render the content on the right | `TemplateRef` | - | \ No newline at end of file diff --git a/components/cron-expression/doc/index.zh-CN.md b/components/cron-expression/doc/index.zh-CN.md index 7994091a154..b17ea22a71c 100644 --- a/components/cron-expression/doc/index.zh-CN.md +++ b/components/cron-expression/doc/index.zh-CN.md @@ -32,10 +32,9 @@ npm install cron-parser ### nz-cron-expression -| 参数 | 说明 | 类型 | 默认值 | -|----------------|-----|-------------|----------| -| `[nzSize]` | 设置文本框、按钮大小,可选值为 `small` `large` 或者不设 | `'large'|'small'|'default'` | `default` | -| `[nzCronType]` | 设置cron规则类型,可选值为 `spring` 或者不设 | `'linux'|'spring'` | `linux` | -| `[nzVisible]` | 隐藏快捷设置 | `boolean` | `false` | -| `[nzType]` | 设置快捷设置类型,可选值为 `primary` `dashed` `text` `link` 或者不设, `[nzVisible]=false` 时生效 | `'primary'|'dashed'|'link'|'text'` | - | -| `[nzOptions]` | 修改快捷设置的选项, `[nzVisible]=false` 时生效 | `NzCronOptions` | - | +| 参数 | 说明 | 类型 | 默认值 | +|----------------|----------------|-----------------------------|----------| +| `[nzType]` | cron 规则类型 | `'linux'|'spring'` | `linux` | +| `[nzSize]` | 设置输入框大小 | `'large'|'small'|'default'` | `default` | +| `[nzCollapseDisable]` | 隐藏折叠面板 | `boolean` | `false` | +| `[nzExtra]` | 自定义渲染右侧的内容 | `TemplateRef` | - | \ No newline at end of file diff --git a/components/cron-expression/style/index.less b/components/cron-expression/style/index.less index ea15f8b8353..8dbb94f6ce7 100644 --- a/components/cron-expression/style/index.less +++ b/components/cron-expression/style/index.less @@ -4,84 +4,115 @@ @cron-expression-prefix-cls: ~'@{ant-prefix}-cron-expression'; .@{cron-expression-prefix-cls} { - display: block; -} - -.@{cron-expression-prefix-cls}-box { display: flex; flex-wrap: nowrap; -} -.@{cron-expression-prefix-cls}-input-group { - display: flex; - flex-wrap: nowrap; - align-items: center; - border: @border-width-base solid @border-color-base; - padding: @padding-xss @padding-sm; - border-radius: @border-radius-base; + &-content{ + width: 100%; - &:hover { - border-color: @primary-color; + .@{cron-expression-prefix-cls}-input-group-error { + border-color: @error-color; + box-shadow: none; + + &:hover { + border-color: @error-color; + box-shadow: none; + } + } + + .@{cron-expression-prefix-cls}-input-group-error-focus { + box-shadow: 0 0 0 2px @error-color-outline; + &:hover { + box-shadow: 0 0 0 2px @error-color-outline; + } + } } - input { - border: none !important; - box-shadow: none !important; - width: 100%; - outline: none; - padding: 0; + nz-cron-expression-input{ + width: 20%; } -} -.@{cron-expression-prefix-cls}-input-group-lg { - padding: 6.5px @padding-sm; - font-size: @font-size-lg; -} -.@{cron-expression-prefix-cls}-input-group-sm { - padding: 0 @padding-sm; -} + &-input-group { + display: flex; + flex-wrap: nowrap; + align-items: center; + border: @border-width-base solid @border-color-base; + padding: @padding-xss @padding-sm; + border-radius: @border-radius-base; -.@{cron-expression-prefix-cls}-input-group-focus { - border-color: @primary-color; - box-shadow: 0 0 0 2px @primary-color-outline; - border-right-width: @border-width-base; - outline: 0; -} + &:hover { + border-color: @primary-color; + } -.@{cron-expression-prefix-cls}-label-group { - display: flex; - width: 100%; - flex-wrap: nowrap; - justify-content: space-around; - padding: 0 @padding-sm; + input { + border: none !important; + box-shadow: none !important; + width: 100%; + outline: none; + padding: 0; + } + } + + &-input-group-lg { + padding: 6.5px @padding-sm; + font-size: @font-size-lg; + } - &>div { + &-input-group-sm { + padding: 0 @padding-sm; + } + + &-input-group-focus { + border-color: @primary-color; + box-shadow: 0 0 0 2px @primary-color-outline; + border-right-width: @border-width-base; + outline: 0; + } + + nz-cron-expression-label { width: 20%; } -} -.@{cron-expression-prefix-cls}-label-foucs { - color: @primary-color; -} + &-label-group { + display: flex; + width: 100%; + flex-wrap: nowrap; + justify-content: space-around; + padding: 0 @padding-sm; + } -.@{cron-expression-prefix-cls}-map { - margin-left: @margin-sm; -} + &-label-foucs { + color: @primary-color; + } -nz-collapse { - width: 100%; -} + &-map { + margin-left: @margin-sm; + } -.@{cron-expression-prefix-cls}-error { - color: @error-color; -} + &-preview-date { + overflow-y: scroll; + height: 132px; + } -.@{cron-expression-prefix-cls}-hint { - p { - display: flex; + &-error { + color: @error-color; } - span { - display: inline-block; - min-width: 40px; + + &-hint { + p { + display: flex; + } + span { + display: inline-block; + min-width: 40px; + } } } + +.ant-collapse > .ant-collapse-item > .ant-collapse-header { + padding: @padding-sm; +} + +.ant-collapse-content > .ant-collapse-content-box { + padding: @padding-md @padding-lg+@padding-sm; +} \ No newline at end of file diff --git a/components/cron-expression/typings.ts b/components/cron-expression/typings.ts index 17d66481d80..2a3e906781b 100644 --- a/components/cron-expression/typings.ts +++ b/components/cron-expression/typings.ts @@ -3,8 +3,22 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ +export type TimeType = 'second' | 'minute' | 'hour' | 'day' | 'month' | 'week'; + +export type TimeTypeError = 'secondError' | 'minuteError' | 'hourError' | 'dayError' | 'monthError' | 'weekError'; + export interface CronType { - [p: string]: string; + second?: string; + minute?: string; + hour?: string; + day?: string; + month?: string; + week?: string; +} + +export interface CronChangeType { + label: string; + value: string; } export type NzCronExpressionSize = 'large' | 'default' | 'small'; diff --git a/components/i18n/languages/en_US.ts b/components/i18n/languages/en_US.ts index 281f8a879b7..fc23dcc0973 100644 --- a/components/i18n/languages/en_US.ts +++ b/components/i18n/languages/en_US.ts @@ -197,6 +197,6 @@ export default { monthError: '

*Any value

,Separator between multiple values

-Connector for interval values

/Equally distributed

1-12Allowable range

', weekError: - '

*Any value

,Separator between multiple values

-Connector for interval values

/Equally distributed

0-7Allowable range (0 represents Sunday, 1-7 are Monday to Sunday)

' + '

*Any value

,Separator between multiple values

-Connector for interval values

/Equally distributed

? Not specify

0-7Allowable range (0 represents Sunday, 1-7 are Monday to Sunday)

' } }; diff --git a/components/i18n/languages/zh_CN.ts b/components/i18n/languages/zh_CN.ts index e4ffa9f31cf..45fa17658d7 100755 --- a/components/i18n/languages/zh_CN.ts +++ b/components/i18n/languages/zh_CN.ts @@ -193,6 +193,6 @@ export default { monthError: '

* 任意值

, 多个值之间的分隔符

- 区间值的连接符

/ 平均分配

1-12 允许范围

', weekError: - '

* 任意值

, 多个值之间的分隔符

- 区间值的连接符

/ 平均分配

0-7 允许范围(0代表周日,1-7依次为周一到周日)

' + '

* 任意值

, 多个值之间的分隔符

- 区间值的连接符

/ 平均分配

? 不指定

0-7 允许范围(0代表周日,1-7依次为周一到周日)

' } }; diff --git a/components/i18n/nz-i18n.interface.ts b/components/i18n/nz-i18n.interface.ts index a417e547674..a4e000a9a8a 100644 --- a/components/i18n/nz-i18n.interface.ts +++ b/components/i18n/nz-i18n.interface.ts @@ -131,23 +131,28 @@ export interface NzTextI18nInterface { expand: string; } -export interface NzCronExpressionI18nInterface { - cronError: string; - second: string; - minute: string; - hour: string; - day: string; - month: string; - week: string; +export interface NzCronExpressionLabelI18n { + second?: string; + minute?: string; + hour?: string; + day?: string; + month?: string; + week?: string; // innerHTML - secondError: string; - minuteError: string; - hourError: string; - dayError: string; - monthError: string; - weekError: string; + secondError?: string; + minuteError?: string; + hourError?: string; + dayError?: string; + monthError?: string; + weekError?: string; +} + +export interface NzCronExpressionCronErrorI18n { + cronError?: string; } +export type NzCronExpressionI18nInterface = NzCronExpressionCronErrorI18n & NzCronExpressionLabelI18n; + export interface NzI18nInterface { locale: string; Pagination: NzPaginationI18nInterface;