mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
TD-450: Fix metadata datetime picker (#169)
This commit is contained in:
parent
a7385d712c
commit
032a89d804
@ -11,7 +11,8 @@ function isEmptyObjectOrPrimitive(value: unknown): boolean {
|
||||
return isObject(value) ? isEmpty(value) : isEmptyPrimitive(value);
|
||||
}
|
||||
|
||||
export function clean<T>(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function clean<T extends ReadonlyArray<any> | ArrayLike<any> | Record<any, any>>(
|
||||
value: T,
|
||||
allowRootRemoval = false,
|
||||
isNotDeep = false,
|
||||
|
@ -67,15 +67,4 @@ export class DomainStoreService {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
sequenceCommits(
|
||||
[commit, ...otherCommits]: Commit[],
|
||||
version?: Version | number
|
||||
): Observable<number> {
|
||||
return otherCommits.length
|
||||
? this.commit(commit, version, false).pipe(
|
||||
switchMap((v) => this.sequenceCommits(otherCommits, v))
|
||||
)
|
||||
: this.commit(commit, version);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { LOCALE_ID, NgModule, Injector } from '@angular/core';
|
||||
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
@ -67,6 +68,8 @@ export let AppInjector: Injector;
|
||||
KeycloakTokenInfoModule,
|
||||
PayoutsModule,
|
||||
SectionsModule,
|
||||
// TODO: hack for metadata datetime 😡
|
||||
MatDatepickerModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } },
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
} from '@vality/domain-proto';
|
||||
import { Version } from '@vality/domain-proto/lib/domain_config';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { combineLatest, concat, Observable } from 'rxjs';
|
||||
import { first, map, pluck, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
||||
@ -476,8 +476,8 @@ export class RoutingRulesService {
|
||||
getDelegate(newMainRuleset, delegateIdx).ruleset.id = nextRefID;
|
||||
const newDelegateRuleset = cloneDeep(delegateRuleset);
|
||||
newDelegateRuleset.ref.id = nextRefID;
|
||||
return this.domainStoreService.sequenceCommits([
|
||||
{
|
||||
return concat(
|
||||
this.domainStoreService.commit({
|
||||
ops: [
|
||||
{
|
||||
insert: {
|
||||
@ -485,8 +485,8 @@ export class RoutingRulesService {
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
}),
|
||||
this.domainStoreService.commit({
|
||||
ops: [
|
||||
{
|
||||
update: {
|
||||
@ -495,8 +495,8 @@ export class RoutingRulesService {
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
})
|
||||
);
|
||||
}),
|
||||
pluck('1')
|
||||
);
|
||||
|
@ -7,8 +7,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { FormComponentSuperclass } from '@s-libs/ng-core';
|
||||
import { coerceBoolean } from 'coerce-property';
|
||||
import moment from 'moment';
|
||||
import { Moment } from 'moment/moment';
|
||||
import moment, { Moment } from 'moment';
|
||||
|
||||
import { createControlProviders } from '@cc/utils';
|
||||
|
||||
|
1
src/app/shared/components/datetime/index.ts
Normal file
1
src/app/shared/components/datetime/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './datetime.component';
|
@ -6,4 +6,18 @@
|
||||
label="{{ data.type | fieldLabel: data.field }} (amount)"
|
||||
minor
|
||||
></cc-cash-field>
|
||||
<div *ngSwitchCase="'datetime'" fxLayoutGap="4px">
|
||||
<cc-datetime
|
||||
[formControl]="control"
|
||||
[hint]="aliases"
|
||||
[label]="(extensionResult$ | async)?.label ?? (data.type | fieldLabel: data.field)"
|
||||
fxFlex
|
||||
></cc-datetime>
|
||||
<button *ngIf="!data.isRequired && control.value" mat-icon-button (click)="clear($event)">
|
||||
<mat-icon>clear</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="generate$ | async" mat-icon-button (click)="generate($event)">
|
||||
<mat-icon>loop</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
@ -4,12 +4,13 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { FormComponentSuperclass } from '@s-libs/ng-core';
|
||||
import { ThriftType } from '@vality/thrift-ts';
|
||||
import { defer, switchMap, ReplaySubject, Observable, combineLatest } from 'rxjs';
|
||||
import { shareReplay, first, map } from 'rxjs/operators';
|
||||
import { shareReplay, first, map, pluck } from 'rxjs/operators';
|
||||
|
||||
import { getValueTypeTitle } from '@cc/app/shared/pipes';
|
||||
import { createControlProviders } from '@cc/utils';
|
||||
|
||||
import { ComponentChanges } from '../../../../utils';
|
||||
import { MetadataFormData } from '../../types/metadata-form-data';
|
||||
import { getAliases, MetadataFormData } from '../../types/metadata-form-data';
|
||||
import {
|
||||
Converter,
|
||||
MetadataFormExtension,
|
||||
@ -39,6 +40,15 @@ export class ExtensionFieldComponent<T>
|
||||
switchMap(([data, extensions]) => getFirstDeterminedExtensionsResult(extensions, data)),
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
);
|
||||
generate$ = this.extensionResult$.pipe(pluck('generate'));
|
||||
|
||||
get aliases() {
|
||||
return [...getAliases(this.data), ...(this.data.field ? [this.data] : [])]
|
||||
.filter((d) => d.typeGroup !== 'primitive')
|
||||
.map((d) => getValueTypeTitle(d.type))
|
||||
.filter((t) => t !== this.data.field?.name)
|
||||
.join(', ');
|
||||
}
|
||||
|
||||
private data$ = new ReplaySubject<MetadataFormData>(1);
|
||||
private extensions$ = new ReplaySubject<MetadataFormExtension[]>(1);
|
||||
@ -81,4 +91,19 @@ export class ExtensionFieldComponent<T>
|
||||
}
|
||||
if (changes.extensions) this.extensions$.next(this.extensions);
|
||||
}
|
||||
|
||||
generate(event: MouseEvent) {
|
||||
this.generate$
|
||||
.pipe(
|
||||
switchMap((generate) => generate()),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe((value) => this.control.setValue(value as T));
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
clear(event: MouseEvent) {
|
||||
this.control.reset(null);
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
@ -24,89 +24,63 @@
|
||||
</ng-container>
|
||||
<ng-template #input>
|
||||
<div fxLayoutGap="4px">
|
||||
<ng-container *ngIf="(extensionResult$ | async)?.type === 'datetime'; else input">
|
||||
<cc-datetime
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>
|
||||
<ng-container *ngIf="!(extensionResult$ | async)?.label; else extensionLabel">{{
|
||||
data.type | fieldLabel: data.field
|
||||
}}</ng-container>
|
||||
<ng-template #extensionLabel>{{
|
||||
(extensionResult$ | async).label
|
||||
}}</ng-template>
|
||||
</mat-label>
|
||||
<mat-hint>{{ aliases }}</mat-hint>
|
||||
<input
|
||||
#trigger="matAutocompleteTrigger"
|
||||
[formControl]="control"
|
||||
[hint]="aliases"
|
||||
[label]="
|
||||
(extensionResult$ | async)?.label ?? (data.type | fieldLabel: data.field)
|
||||
"
|
||||
fxFlex
|
||||
></cc-datetime>
|
||||
<button
|
||||
*ngIf="!data.isRequired && control.value"
|
||||
mat-icon-button
|
||||
(click)="clear($event)"
|
||||
>
|
||||
<mat-icon>clear</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="generate$ | async" mat-icon-button (click)="generate($event)">
|
||||
<mat-icon>loop</mat-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-template #input>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>
|
||||
<ng-container
|
||||
*ngIf="!(extensionResult$ | async)?.label; else extensionLabel"
|
||||
>{{ data.type | fieldLabel: data.field }}</ng-container
|
||||
[matAutocomplete]="auto"
|
||||
[ngClass]="{ 'cc-code': (extensionResult$ | async)?.isIdentifier }"
|
||||
[required]="data.isRequired"
|
||||
[type]="inputType"
|
||||
matInput
|
||||
/>
|
||||
<div fxLayoutGap="4px" matSuffix>
|
||||
<button
|
||||
*ngIf="!data.isRequired && control.value"
|
||||
mat-icon-button
|
||||
(click)="clear($event)"
|
||||
>
|
||||
<mat-icon>clear</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="(extensionResult$ | async)?.options?.length"
|
||||
mat-icon-button
|
||||
(click)="
|
||||
auto.isOpen ? trigger.closePanel() : trigger.openPanel();
|
||||
$event.stopPropagation()
|
||||
"
|
||||
>
|
||||
<mat-icon>{{ auto.isOpen ? 'expand_less' : 'expand_more' }}</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<mat-autocomplete #auto="matAutocomplete">
|
||||
<ng-container *ngIf="extensionResult$ | async as extensionResult">
|
||||
<mat-option
|
||||
*ngFor="let option of filteredOptions$ | async"
|
||||
[value]="option.value"
|
||||
>
|
||||
<ng-template #extensionLabel>{{
|
||||
(extensionResult$ | async).label
|
||||
}}</ng-template>
|
||||
</mat-label>
|
||||
<mat-hint>{{ aliases }}</mat-hint>
|
||||
<input
|
||||
#trigger="matAutocompleteTrigger"
|
||||
[formControl]="control"
|
||||
[matAutocomplete]="auto"
|
||||
[ngClass]="{ 'cc-code': (extensionResult$ | async)?.isIdentifier }"
|
||||
[required]="data.isRequired"
|
||||
[type]="inputType"
|
||||
matInput
|
||||
/>
|
||||
<div fxLayoutGap="4px" matSuffix>
|
||||
<button
|
||||
*ngIf="!data.isRequired && control.value"
|
||||
mat-icon-button
|
||||
(click)="clear($event)"
|
||||
>
|
||||
<mat-icon>clear</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="(extensionResult$ | async)?.options?.length"
|
||||
mat-icon-button
|
||||
(click)="
|
||||
auto.isOpen ? trigger.closePanel() : trigger.openPanel();
|
||||
$event.stopPropagation()
|
||||
"
|
||||
>
|
||||
<mat-icon>{{ auto.isOpen ? 'expand_less' : 'expand_more' }}</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<mat-autocomplete #auto="matAutocomplete">
|
||||
<ng-container *ngIf="extensionResult$ | async as extensionResult">
|
||||
<mat-option
|
||||
*ngFor="let option of filteredOptions$ | async"
|
||||
[value]="option.value"
|
||||
>
|
||||
<div fxLayout="row" fxLayoutAlign=" center" fxLayoutGap="8px">
|
||||
<div [ngClass]="{ 'cc-code': extensionResult.isIdentifier }">
|
||||
{{ option.value }}
|
||||
</div>
|
||||
<cc-label
|
||||
[color]="option.color"
|
||||
[label]="option.label"
|
||||
></cc-label>
|
||||
<div fxLayout="row" fxLayoutAlign=" center" fxLayoutGap="8px">
|
||||
<div [ngClass]="{ 'cc-code': extensionResult.isIdentifier }">
|
||||
{{ option.value }}
|
||||
</div>
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<button *ngIf="generate$ | async" mat-icon-button (click)="generate($event)">
|
||||
<mat-icon>loop</mat-icon>
|
||||
</button>
|
||||
</ng-template>
|
||||
<cc-label [color]="option.color" [label]="option.label"></cc-label>
|
||||
</div>
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<button *ngIf="generate$ | async" mat-icon-button (click)="generate($event)">
|
||||
<mat-icon>loop</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-container *ngIf="selected$ | async as selected">
|
||||
|
@ -1,9 +1,6 @@
|
||||
<div *ngIf="data" [ngSwitch]="data?.typeGroup">
|
||||
<cc-extension-field
|
||||
*ngIf="
|
||||
(extensionResult$ | async)?.type && (extensionResult$ | async)?.type !== 'datetime';
|
||||
else defaultFields
|
||||
"
|
||||
*ngIf="(extensionResult$ | async)?.type; else defaultFields"
|
||||
[data]="data"
|
||||
[extensions]="extensions"
|
||||
[formControl]="control"
|
||||
|
@ -17,12 +17,12 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { PipesModule } from '@vality/ng-core';
|
||||
|
||||
import { DatetimeComponent } from '@cc/app/shared/components/datetime/datetime.component';
|
||||
import { JsonViewerModule } from '@cc/app/shared/components/json-viewer';
|
||||
import { ThriftPipesModule } from '@cc/app/shared/pipes/thrift';
|
||||
import { ValueTypeTitleModule } from '@cc/app/shared/pipes/value-type-title';
|
||||
import { CashModule } from '@cc/components/cash-field';
|
||||
|
||||
import { CashModule } from '../../../../components/cash-field';
|
||||
import { DatetimeComponent } from '../datetime';
|
||||
import { ComplexFormComponent } from './components/complex-form/complex-form.component';
|
||||
import { EnumFieldComponent } from './components/enum-field/enum-field.component';
|
||||
import { ExtensionFieldComponent } from './components/extension-field/extension-field.component';
|
||||
|
Loading…
Reference in New Issue
Block a user