From 75bf0409c47c3c04485c0a9ba4e76394916c4108 Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Tue, 24 Nov 2020 12:06:46 +0100 Subject: [PATCH 1/4] fix: management api remove otp (#1010) * fix: management api remove otp * add postinstall * remove mgmt otp Co-authored-by: Max Peintner --- .../user-mfa/user-mfa.component.html | 10 +++++ .../user-mfa/user-mfa.component.ts | 37 ++++++++++++++++++- console/src/app/services/mgmt.service.ts | 6 +++ internal/api/grpc/management/user.go | 5 +++ .../eventsourcing/eventstore/user.go | 4 ++ internal/management/repository/user.go | 1 + pkg/grpc/management/proto/management.proto | 10 +++++ 7 files changed, 71 insertions(+), 2 deletions(-) diff --git a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.html b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.html index 61c2b662c5..eb234e45d8 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.html +++ b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.html @@ -17,6 +17,16 @@ + + {{ 'USER.MFA.TABLEACTIONS' | translate }} + + + + + diff --git a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts index 00b2e10f76..e91c170d77 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts +++ b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts @@ -1,9 +1,12 @@ import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; import { MatSort } from '@angular/material/sort'; import { MatTable, MatTableDataSource } from '@angular/material/table'; import { BehaviorSubject, Observable } from 'rxjs'; +import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component'; import { MFAState, MfaType, UserMultiFactor, UserView } from 'src/app/proto/generated/management_pb'; import { ManagementService } from 'src/app/services/mgmt.service'; +import { ToastService } from 'src/app/services/toast.service'; export interface MFAItem { @@ -17,7 +20,7 @@ export interface MFAItem { styleUrls: ['./user-mfa.component.scss'], }) export class UserMfaComponent implements OnInit, OnDestroy { - public displayedColumns: string[] = ['type', 'state']; + public displayedColumns: string[] = ['type', 'state', 'actions']; @Input() private user!: UserView.AsObject; public mfaSubject: BehaviorSubject = new BehaviorSubject([]); private loadingSubject: BehaviorSubject = new BehaviorSubject(false); @@ -31,7 +34,7 @@ export class UserMfaComponent implements OnInit, OnDestroy { public MFAState: any = MFAState; public error: string = ''; - constructor(private mgmtUserService: ManagementService) { } + constructor(private mgmtUserService: ManagementService, private dialog: MatDialog, private toast: ToastService) { } public ngOnInit(): void { this.getOTP(); @@ -50,4 +53,34 @@ export class UserMfaComponent implements OnInit, OnDestroy { this.error = error.message; }); } + + public deleteMFA(type: MfaType): void { + const dialogRef = this.dialog.open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.DELETE', + cancelKey: 'ACTIONS.CANCEL', + titleKey: 'USER.MFA.DIALOG.OTP_DELETE_TITLE', + descriptionKey: 'USER.MFA.DIALOG.OTP_DELETE_DESCRIPTION', + }, + width: '400px', + }); + + dialogRef.afterClosed().subscribe(resp => { + if (resp) { + if (type === MfaType.MFATYPE_OTP) { + this.mgmtUserService.removeMfaOTP(this.user.id).then(() => { + this.toast.showInfo('USER.TOAST.OTPREMOVED', true); + + const index = this.dataSource.data.findIndex(mfa => mfa.type === type); + if (index > -1) { + this.dataSource.data.splice(index, 1); + } + this.getOTP(); + }).catch(error => { + this.toast.showError(error); + }); + } + } + }); + } } diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index e3e61180b4..f003e5c456 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -677,6 +677,12 @@ export class ManagementService { return this.grpcService.mgmt.getUserMfas(req); } + public removeMfaOTP(id: string): Promise { + const req = new UserID(); + req.setId(id); + return this.grpcService.mgmt.removeMfaOTP(req); + } + public SaveUserProfile( id: string, firstName?: string, diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index f40f86317c..bf7f0abbd8 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -221,6 +221,11 @@ func (s *Server) GetUserMfas(ctx context.Context, userID *management.UserID) (*m return &management.UserMultiFactors{Mfas: mfasFromModel(mfas)}, nil } +func (s *Server) RemoveMfaOTP(ctx context.Context, userID *management.UserID) (*empty.Empty, error) { + err := s.user.RemoveOTP(ctx, userID.Id) + return &empty.Empty{}, err +} + func (s *Server) SearchUserMemberships(ctx context.Context, in *management.UserMembershipSearchRequest) (*management.UserMembershipSearchResponse, error) { request := userMembershipSearchRequestsToModel(in) request.AppendUserIDQuery(in.UserId) diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index c8579062ff..3ab8118411 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -223,6 +223,10 @@ func (repo *UserRepo) UserMfas(ctx context.Context, userID string) ([]*usr_model return []*usr_model.MultiFactor{{Type: usr_model.MfaTypeOTP, State: user.OTPState}}, nil } +func (repo *UserRepo) RemoveOTP(ctx context.Context, userID string) error { + return repo.UserEvents.RemoveOTP(ctx, userID) +} + func (repo *UserRepo) SetOneTimePassword(ctx context.Context, password *usr_model.Password) (*usr_model.Password, error) { policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if err != nil && caos_errs.IsNotFound(err) { diff --git a/internal/management/repository/user.go b/internal/management/repository/user.go index 58f4bdeda1..ae035368e7 100644 --- a/internal/management/repository/user.go +++ b/internal/management/repository/user.go @@ -31,6 +31,7 @@ type UserRepository interface { ChangeProfile(ctx context.Context, profile *model.Profile) (*model.Profile, error) UserMfas(ctx context.Context, userID string) ([]*model.MultiFactor, error) + RemoveOTP(ctx context.Context, userID string) error SearchExternalIDPs(ctx context.Context, request *model.ExternalIDPSearchRequest) (*model.ExternalIDPSearchResponse, error) RemoveExternalIDP(ctx context.Context, externalIDP *model.ExternalIDP) error diff --git a/pkg/grpc/management/proto/management.proto b/pkg/grpc/management/proto/management.proto index ceeece9f15..52f76c0611 100644 --- a/pkg/grpc/management/proto/management.proto +++ b/pkg/grpc/management/proto/management.proto @@ -388,6 +388,16 @@ rpc GetUserByID(UserID) returns (UserView) { }; } + rpc RemoveMfaOTP(UserID) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/users/{id}/mfas/otp" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "user.write" + }; + } + // Sends an Notification (Email/SMS) with a password reset Link rpc SendSetPasswordNotification(SetPasswordNotificationRequest) returns (google.protobuf.Empty) { option (google.api.http) = { From 78a1b8f0197b10174b6849fd5f7f761ac8cd20c4 Mon Sep 17 00:00:00 2001 From: Silvan Date: Tue, 24 Nov 2020 15:55:38 +0100 Subject: [PATCH 2/4] fix: org member change and remove (#1014) * fix: member * fix: test * fix: test * fix: tests --- internal/org/model/org.go | 8 +++---- .../repository/eventsourcing/eventstore.go | 23 +++++++++++-------- .../repository/eventsourcing/org_member.go | 13 ++++++----- .../eventsourcing/org_member_test.go | 16 +++++++++++-- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/internal/org/model/org.go b/internal/org/model/org.go index c5ec7829a3..3a0bdec40e 100644 --- a/internal/org/model/org.go +++ b/internal/org/model/org.go @@ -85,13 +85,13 @@ func (o *Org) GetPrimaryDomain() *OrgDomain { return nil } -func (o *Org) ContainsMember(userID string) bool { - for _, member := range o.Members { +func (o *Org) MemeberByUserID(userID string) (*OrgMember, int) { + for i, member := range o.Members { if member.UserID == userID { - return true + return member, i } } - return false + return nil, -1 } func (o *Org) nameForDomain(iamDomain string) string { diff --git a/internal/org/repository/eventsourcing/eventstore.go b/internal/org/repository/eventsourcing/eventstore.go index c6bfed3618..8db5c785eb 100644 --- a/internal/org/repository/eventsourcing/eventstore.go +++ b/internal/org/repository/eventsourcing/eventstore.go @@ -429,16 +429,20 @@ func (es *OrgEventstore) ChangeOrgMember(ctx context.Context, member *org_model. return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ara6l", "Errors.Org.InvalidMember") } - existingMember, err := es.OrgMemberByIDs(ctx, member) + org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: member.AggregateID, Sequence: member.Sequence}}) if err != nil { return nil, err } + existingMember, _ := org.MemeberByUserID(member.UserID) + if existingMember == nil { + return nil, errors.ThrowNotFound(nil, "EVENT-VB2Pn", "Errors.Org.MemberNotExisting") + } - member.ObjectRoot = existingMember.ObjectRoot + repoOrg := model.OrgFromModel(org) repoMember := model.OrgMemberFromModel(member) repoExistingMember := model.OrgMemberFromModel(existingMember) - orgAggregate := orgMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoExistingMember, repoMember) + orgAggregate := orgMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoExistingMember, repoMember) err = es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate) if err != nil { return nil, err @@ -452,18 +456,19 @@ func (es *OrgEventstore) RemoveOrgMember(ctx context.Context, member *org_model. return errors.ThrowInvalidArgument(nil, "EVENT-d43fs", "Errors.Org.UserIDMissing") } - existingMember, err := es.OrgMemberByIDs(ctx, member) - if errors.IsNotFound(err) { - return nil - } + org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: member.AggregateID, Sequence: member.Sequence}}) if err != nil { return err } + existingMember, _ := org.MemeberByUserID(member.UserID) + if existingMember == nil { + return nil + } - member.ObjectRoot = existingMember.ObjectRoot + repoOrg := model.OrgFromModel(org) repoMember := model.OrgMemberFromModel(member) - orgAggregate := orgMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoMember) + orgAggregate := orgMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMember) return es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate) } diff --git a/internal/org/repository/eventsourcing/org_member.go b/internal/org/repository/eventsourcing/org_member.go index 7034de287e..24b67c2f38 100644 --- a/internal/org/repository/eventsourcing/org_member.go +++ b/internal/org/repository/eventsourcing/org_member.go @@ -2,6 +2,7 @@ package eventsourcing import ( "context" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" "github.com/caos/zitadel/internal/errors" @@ -31,9 +32,9 @@ func orgMemberAddedAggregate(ctx context.Context, aggCreator *es_models.Aggregat return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.OrgMemberAdded, member) } -func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingMember *model.OrgMember, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { +func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, existingMember, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil || existingMember == nil { + if member == nil || org == nil || existingMember == nil { return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d34fs", "Errors.Internal") } @@ -42,7 +43,7 @@ func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingM return nil, errors.ThrowInvalidArgument(nil, "EVENT-VLMGn", "Errors.NoChangesFound") } - agg, err := OrgAggregate(ctx, aggCreator, existingMember.AggregateID, existingMember.Sequence) + agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) if err != nil { return nil, err } @@ -50,13 +51,13 @@ func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingM } } -func orgMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { +func orgMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dieu7", "member must not be nil") + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-vNPVX", "Errors.Internal") } - agg, err := OrgAggregate(ctx, aggCreator, member.AggregateID, member.Sequence) + agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) if err != nil { return nil, err } diff --git a/internal/org/repository/eventsourcing/org_member_test.go b/internal/org/repository/eventsourcing/org_member_test.go index 9c5c009953..59e571e6f3 100644 --- a/internal/org/repository/eventsourcing/org_member_test.go +++ b/internal/org/repository/eventsourcing/org_member_test.go @@ -78,6 +78,7 @@ func TestOrgMemberChangedAggregate(t *testing.T) { } type args struct { aggCreator *es_models.AggregateCreator + org *model.Org existingMember *model.OrgMember member *model.OrgMember ctx context.Context @@ -92,6 +93,7 @@ func TestOrgMemberChangedAggregate(t *testing.T) { args: args{ aggCreator: es_models.NewAggregateCreator("test"), ctx: authz.NewMockContext("org", "user"), + org: &model.Org{}, member: nil, existingMember: &model.OrgMember{}, }, @@ -104,6 +106,7 @@ func TestOrgMemberChangedAggregate(t *testing.T) { args: args{ aggCreator: es_models.NewAggregateCreator("test"), ctx: authz.NewMockContext("org", "user"), + org: &model.Org{}, existingMember: nil, member: &model.OrgMember{}, }, @@ -122,6 +125,7 @@ func TestOrgMemberChangedAggregate(t *testing.T) { existingMember: &model.OrgMember{ ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, }, + org: &model.Org{}, }, res: res{ isErr: errors.IsErrorInvalidArgument, @@ -140,6 +144,9 @@ func TestOrgMemberChangedAggregate(t *testing.T) { ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, Roles: []string{"asdf", "woeri"}, }, + org: &model.Org{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, + }, }, res: res{ isErr: nil, @@ -149,7 +156,7 @@ func TestOrgMemberChangedAggregate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgMemberChangedAggregate(tt.args.aggCreator, tt.args.existingMember, tt.args.member) + aggregateCreator := orgMemberChangedAggregate(tt.args.aggCreator, tt.args.org, tt.args.existingMember, tt.args.member) aggregate, err := aggregateCreator(tt.args.ctx) if tt.res.isErr == nil && err != nil { t.Errorf("no error expected got: %v", err) @@ -174,6 +181,7 @@ func TestOrgMemberRemovedAggregate(t *testing.T) { } type args struct { aggCreator *es_models.AggregateCreator + org *model.Org member *model.OrgMember ctx context.Context } @@ -187,6 +195,7 @@ func TestOrgMemberRemovedAggregate(t *testing.T) { args: args{ aggCreator: es_models.NewAggregateCreator("test"), ctx: authz.NewMockContext("org", "user"), + org: &model.Org{}, member: nil, }, res: res{ @@ -198,6 +207,9 @@ func TestOrgMemberRemovedAggregate(t *testing.T) { args: args{ aggCreator: es_models.NewAggregateCreator("test"), ctx: authz.NewMockContext("org", "user"), + org: &model.Org{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, + }, member: &model.OrgMember{ ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, }, @@ -210,7 +222,7 @@ func TestOrgMemberRemovedAggregate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgMemberRemovedAggregate(tt.args.aggCreator, tt.args.member) + aggregateCreator := orgMemberRemovedAggregate(tt.args.aggCreator, tt.args.org, tt.args.member) aggregate, err := aggregateCreator(tt.args.ctx) if tt.res.isErr == nil && err != nil { t.Errorf("no error expected got: %v", err) From 42f50de790039bfb591798b556183d5fcfbcfafa Mon Sep 17 00:00:00 2001 From: Silvan Date: Wed, 25 Nov 2020 07:42:06 +0100 Subject: [PATCH 3/4] fix(machine): set creationdate (#1018) * fix(machine): set creationdate * fix(translations): translate `user.human.phone.removed` --- internal/static/i18n/de.yaml | 1 + internal/static/i18n/en.yaml | 1 + .../repository/eventsourcing/model/user_machine.go | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 2c6dec4c5f..a32ac9f4e3 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -294,6 +294,7 @@ EventTypes: code: added: Telefon Code hinzugefügt sent: Telefon Code versendet + removed: Telefonnummer gelöscht profile: changed: Benutzerprofil geändert address: diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 7f82bfa7c7..08579d24bf 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -282,6 +282,7 @@ EventTypes: code: added: Phone number code generated sent: Phone number code sent + removed: Phone number removed profile: changed: User profile changed address: diff --git a/internal/user/repository/eventsourcing/model/user_machine.go b/internal/user/repository/eventsourcing/model/user_machine.go index 25de45e373..a73aee5116 100644 --- a/internal/user/repository/eventsourcing/model/user_machine.go +++ b/internal/user/repository/eventsourcing/model/user_machine.go @@ -86,11 +86,18 @@ func (key *MachineKey) AppendEvents(events ...*es_models.Event) error { return nil } -func (key *MachineKey) AppendEvent(event *es_models.Event) error { +func (key *MachineKey) AppendEvent(event *es_models.Event) (err error) { + key.ObjectRoot.AppendEvent(event) switch event.Type { case MachineKeyAdded: + err = json.Unmarshal(event.Data, key) + if err != nil { + return errors.ThrowInternal(err, "MODEL-SjI4S", "Errors.Internal") + } + case MachineKeyRemoved: + key.ExpirationDate = event.CreationDate } - return nil + return err } func MachineKeyFromModel(machine *model.MachineKey) *MachineKey { From ae26999834ef219eae46039f34874e24643cdf31 Mon Sep 17 00:00:00 2001 From: Max Peintner Date: Wed, 25 Nov 2020 16:53:14 +0100 Subject: [PATCH 4/4] fix(console): formfield changes and ux (#1020) * cnsl-formfield, cnsl-label, cnsl-input, ch prefix * create user cnsl-fields, add cnsl-error * replace user forms with cnsl-fields * replace all other occurrences of mat-form-field with cnsl-fields * improve hover, active, focus behavior, headlin styling * user-grant refactor * style cleanup * stylelint * fix detail layout flexstart, user table header * input dir * error, input directives instead components, on blur handler * error directive, formfield content children * formfield control directive * use new field for new contact dialog * formfield hint, error directive, scss * hint or error binding, animation after view init * avatar changes, policy header * style lint * lint * input control within formfield, errorstatematcher * use matformcontrol to merge with selects * member table min width, lint * lint * implement from matformcontrol insteat custom, add selector * find error * add focus listener * labelfloat * fix input directive * renaming * rm logs * user search overflow, org create i18n, meta cleanup * sidenav shadow * redirect to org table * lint * lint test files * remove usage of formfieldmodule, use input module, layout optim * replace formfieldmodule usage with inputmodule * lint input dir, scss * user grant, user table optimisations * reorganize sidenav, project table empty, tooltips, avatar ch * user grant tooltips, form field error directive accessor * checkbox overflow fix, table dateblock, i18n tooltips * app placeholder, i18n, optimize mobile layout * change refresh table order, i18n, redirect chips * stylelint * chore(deps-dev): bump stylelint from 13.7.2 to 13.8.0 in /console (#1007) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump stylelint from 13.7.2 to 13.8.0 in /console Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.7.2 to 13.8.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/13.7.2...13.8.0) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.0.1 to 11.0.2 in /console (#1006) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump @angular/cli from 11.0.1 to 11.0.2 in /console Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.1 to 11.0.2. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.0.1...v11.0.2) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google-proto-files from 2.2.0 to 2.3.0 in /console (#1005) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps): bump google-proto-files from 2.2.0 to 2.3.0 in /console Bumps [google-proto-files](https://github.com/googleapis/nodejs-proto-files) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/googleapis/nodejs-proto-files/releases) - [Changelog](https://github.com/googleapis/nodejs-proto-files/blob/master/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-proto-files/compare/v2.2.0...v2.3.0) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/node from 14.14.6 to 14.14.9 in /console (#1004) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump @types/node from 14.14.6 to 14.14.9 in /console Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.6 to 14.14.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service from 11.0.0 to 11.0.2 in /console (#999) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump @angular/language-service in /console Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.0.0 to 11.0.2. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.0.2/packages/language-service) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular from 0.1100.1 to 0.1100.2 in /console (#1003) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump @angular-devkit/build-angular in /console Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1100.1 to 0.1100.2. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * chore(deps-dev): bump prettier from 2.1.2 to 2.2.0 in /console (#1002) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump prettier from 2.1.2 to 2.2.0 in /console Bumps [prettier](https://github.com/prettier/prettier) from 2.1.2 to 2.2.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.1.2...2.2.0) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/jasmine from 3.6.1 to 3.6.2 in /console (#1001) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps-dev): bump @types/jasmine from 3.6.1 to 3.6.2 in /console Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * chore(deps): bump file-saver from 2.0.2 to 2.0.5 in /console (#1000) * fix: add project validation (#996) * fix: project add validation (#997) * fix: add project validation * fix: removed loop * chore(deps): bump file-saver from 2.0.2 to 2.0.5 in /console Bumps [file-saver](https://github.com/eligrey/FileSaver.js) from 2.0.2 to 2.0.5. - [Release notes](https://github.com/eligrey/FileSaver.js/releases) - [Changelog](https://github.com/eligrey/FileSaver.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/eligrey/FileSaver.js/commits) Signed-off-by: dependabot[bot] Co-authored-by: Silvan Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * chore(deps-dev): bump jasmine-spec-reporter in /console (#974) Bumps [jasmine-spec-reporter](https://github.com/bcaudan/jasmine-spec-reporter) from 5.0.2 to 6.0.0. - [Release notes](https://github.com/bcaudan/jasmine-spec-reporter/releases) - [Changelog](https://github.com/bcaudan/jasmine-spec-reporter/blob/master/CHANGELOG.md) - [Commits](https://github.com/bcaudan/jasmine-spec-reporter/compare/v5.0.2...v6.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * input field border improvements, primary color * redirect form, conventional ux * redirects inputs on app create * fix dynamic suffix padding, user grant layout, lint * input style accessor, contact view optim, ext idp, card fixes * hide error on untouched formfield, border red on error touched * fix change detector * change, user, form validation, delete refresh * safari font weight adjustment, change refresh emitter * key validation * remove tabls layout from projects * app changes, refactor project, app state, meta layout * add key dialog validation, startdate, rever change tabs * stylelint * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster * finnaly fix fckntimestamp picker * optional key expiry * small state badge * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Silvan Co-authored-by: Florian Forster --- console/angular.json | 2 +- console/package-lock.json | 1793 +++++++++-------- console/package.json | 20 +- console/src/app/animations.ts | 17 + console/src/app/app.component.html | 62 +- console/src/app/app.component.scss | 21 +- console/src/app/app.component.ts | 3 +- console/src/app/app.module.ts | 6 +- .../member-create-dialog.component.html | 12 +- .../member-create-dialog.module.ts | 6 +- .../app/modules/avatar/avatar.component.html | 2 +- .../app/modules/avatar/avatar.component.scss | 3 + .../app/modules/avatar/avatar.component.ts | 34 +- .../src/app/modules/card/card.component.scss | 11 +- .../modules/changes/changes.component.html | 7 +- .../modules/changes/changes.component.scss | 24 +- .../app/modules/changes/changes.component.ts | 32 +- .../src/app/modules/changes/changes.module.ts | 6 + .../contributors/contributors.component.html | 8 +- .../contributors/contributors.component.scss | 11 +- .../contributors/contributors.module.ts | 2 + .../detail-layout.component.scss | 1 + .../src/app/modules/form-field/animations.ts | 18 + .../app/modules/form-field/error.directive.ts | 20 + .../form-field/form-field.component.html | 17 + .../form-field/form-field.component.scss | 45 + .../form-field/form-field.component.spec.ts | 25 + .../form-field/form-field.component.ts | 164 ++ .../modules/form-field/form-field.module.ts | 30 + .../app/modules/form-field/hint.directive.ts | 33 + .../idp-create/idp-create.component.html | 55 +- .../modules/idp-create/idp-create.module.ts | 6 +- .../src/app/modules/idp/idp.component.html | 66 +- console/src/app/modules/idp/idp.module.ts | 10 +- .../src/app/modules/input/error-options.ts | 19 + .../app/modules/input/input.directive.spec.ts | 8 + .../src/app/modules/input/input.directive.ts | 459 +++++ console/src/app/modules/input/input.module.ts | 22 + .../app/modules/label/label.component.html | 3 + .../app/modules/label/label.component.scss | 16 + .../app/modules/label/label.component.spec.ts | 25 + .../src/app/modules/label/label.component.ts | 10 + console/src/app/modules/label/label.module.ts | 20 + .../members-table.component.html | 9 +- .../members-table.component.scss | 9 +- .../members-table/members-table.module.ts | 4 +- .../meta-layout/meta-layout.component.ts | 2 +- console/src/app/modules/meta-layout/meta.scss | 44 - .../label-policy/label-policy.component.html | 16 +- .../label-policy/label-policy.module.ts | 6 +- .../add-idp-dialog.component.html | 12 +- .../add-idp-dialog.component.ts | 3 +- .../add-idp-dialog/add-idp-dialog.module.ts | 4 +- .../login-policy/login-policy.module.ts | 6 +- .../org-iam-policy/org-iam-policy.module.ts | 6 +- .../password-age-policy.module.ts | 6 +- .../password-complexity-policy.module.ts | 6 +- .../password-lockout-policy.module.ts | 6 +- .../policy-grid/policy-grid.component.html | 2 +- .../policy-grid/policy-grid.component.scss | 6 +- .../project-role-detail.component.html | 24 +- .../project-roles.component.html | 5 + .../project-roles.component.scss | 5 - .../project-roles/project-roles.module.ts | 6 +- .../refresh-table.component.html | 17 +- .../refresh-table.component.scss | 11 +- .../refresh-table/refresh-table.component.ts | 1 - ...search-project-autocomplete.component.html | 10 +- .../search-project-autocomplete.module.ts | 6 +- .../search-roles-autocomplete.component.html | 10 +- .../search-roles-autocomplete.module.ts | 6 +- .../search-user-autocomplete.component.html | 28 +- .../search-user-autocomplete.component.scss | 8 +- .../search-user-autocomplete.module.ts | 6 +- .../user-grants/user-grants.component.html | 111 +- .../user-grants/user-grants.component.scss | 41 +- .../user-grants/user-grants.component.ts | 2 +- .../modules/user-grants/user-grants.module.ts | 7 +- .../app/pages/grants/grants.component.html | 8 +- .../app/pages/grants/grants.component.scss | 4 + .../failed-events.component.scss | 5 - .../iam/iam-members/iam-members.component.ts | 1 - .../iam/iam-views/iam-views.component.scss | 5 - console/src/app/pages/iam/iam.module.ts | 6 +- .../orgs/org-create/org-create.component.html | 138 +- .../orgs/org-create/org-create.component.ts | 18 +- .../orgs/org-create/org-create.module.ts | 6 +- .../add-domain-dialog.component.html | 8 +- .../add-domain-dialog.module.ts | 6 +- .../domain-verification.component.html | 1 - .../orgs/org-detail/org-detail.component.scss | 2 +- .../orgs/org-list/org-list.component.html | 8 +- .../orgs/org-list/org-list.component.scss | 5 - .../pages/orgs/org-list/org-list.component.ts | 5 +- .../pages/orgs/org-list/org-list.module.ts | 6 +- ...g-member-roles-autocomplete.component.html | 6 +- .../org-member-roles-autocomplete.module.ts | 6 +- console/src/app/pages/orgs/orgs.module.ts | 6 +- .../apps/app-create/app-create.component.html | 127 +- .../apps/app-create/app-create.component.scss | 24 +- .../apps/app-create/app-create.component.ts | 8 +- .../apps/app-detail/app-detail.component.html | 323 +-- .../apps/app-detail/app-detail.component.scss | 76 +- .../apps/app-detail/app-detail.component.ts | 16 +- .../app/pages/projects/apps/apps.module.ts | 10 +- .../granted-project-detail.component.html | 12 +- .../granted-project-detail.component.scss | 23 +- .../granted-project-grid.component.html | 2 +- .../granted-project-list.component.html | 7 +- .../granted-project-list.component.scss | 5 - .../granted-projects.module.ts | 8 +- .../application-grid.component.html | 2 +- .../application-grid.component.scss | 9 +- .../applications/applications.component.scss | 5 - .../owned-project-detail.component.html | 20 +- .../owned-project-detail.component.scss | 36 +- .../owned-project-detail.component.ts | 7 +- .../owned-project-detail.module.ts | 8 +- .../project-grants.component.html | 37 +- .../project-grants.component.scss | 21 +- .../project-grants.component.ts | 2 +- .../owned-project-grid.component.html | 2 +- .../owned-project-list.component.html | 7 +- .../owned-project-list.component.scss | 5 - .../owned-project-list.component.ts | 1 - .../owned-projects/owned-projects.module.ts | 6 +- .../project-grant-detail.component.html | 6 +- .../project-grant-detail.module.ts | 4 +- ...grant-members-create-dialog.component.html | 6 +- ...ject-grant-members-create-dialog.module.ts | 4 +- .../project-grant-members-datasource.ts | 1 - .../project-create.component.html | 11 +- .../project-create.component.scss | 4 - .../project-create/project-create.module.ts | 8 +- .../project-grant-create.component.html | 8 +- .../project-grant-create.component.ts | 2 - .../project-grant-create.module.ts | 6 +- .../project-role-create.component.html | 24 +- .../project-role-create.module.ts | 6 +- .../user-grant-create.component.html | 6 +- .../user-grant-create.component.ts | 1 - .../user-grant-create.module.ts | 4 +- .../user-create-machine.component.html | 36 +- .../user-create-machine.module.ts | 6 +- .../user-create/user-create.component.html | 102 +- .../user-create/user-create.component.scss | 2 + .../user-create/user-create.component.ts | 24 +- .../users/user-create/user-create.module.ts | 10 +- .../auth-user-detail.component.html | 5 +- .../auth-user-detail.component.ts | 7 +- .../code-dialog/code-dialog.component.html | 8 +- .../dialog-otp/dialog-otp.component.html | 8 +- .../edit-dialog/edit-dialog.component.html | 8 +- .../edit-dialog/edit-dialog.component.spec.ts | 14 +- .../resend-email-dialog.component.html | 8 +- .../resend-email-dialog.component.spec.ts | 16 +- .../contact/contact.component.html | 3 +- .../contact/contact.component.scss | 1 + .../detail-form-machine.component.html | 36 +- .../detail-form-machine.module.ts | 6 +- .../detail-form/detail-form.component.html | 44 +- .../detail-form/detail-form.module.ts | 7 +- .../external-idps.component.scss | 10 + .../add-key-dialog.component.html | 26 +- .../add-key-dialog.component.ts | 12 +- .../add-key-dialog/add-key-dialog.module.ts | 11 +- .../machine-keys/machine-keys.component.ts | 5 +- .../show-key-dialog.component.html | 8 +- .../membership-detail.component.scss | 5 - .../memberships/memberships.component.html | 8 +- .../memberships/memberships.component.scss | 13 +- .../password/password.component.html | 60 +- .../password/password.component.scss | 2 +- .../users/user-detail/user-detail.module.ts | 6 +- .../user-detail/user-detail.component.html | 10 +- .../user-detail/user-detail.component.scss | 22 +- .../user-detail/user-detail.component.ts | 19 +- .../pages/users/user-list/user-list.module.ts | 6 +- .../user-table/user-table.component.html | 19 +- .../user-table/user-table.component.scss | 47 +- .../user-table/user-table.component.ts | 39 +- console/src/app/services/grpc.service.ts | 2 +- console/src/app/services/mgmt.service.ts | 3 +- console/src/assets/i18n/de.json | 38 +- console/src/assets/i18n/en.json | 44 +- console/src/component-themes.scss | 10 +- console/src/styles.scss | 22 +- console/src/styles/error.scss | 19 + console/src/styles/input.scss | 72 + console/src/styles/sidenav-list.scss | 30 +- console/src/styles/table.scss | 47 +- 191 files changed, 3622 insertions(+), 2109 deletions(-) create mode 100644 console/src/app/modules/form-field/animations.ts create mode 100644 console/src/app/modules/form-field/error.directive.ts create mode 100644 console/src/app/modules/form-field/form-field.component.html create mode 100644 console/src/app/modules/form-field/form-field.component.scss create mode 100644 console/src/app/modules/form-field/form-field.component.spec.ts create mode 100644 console/src/app/modules/form-field/form-field.component.ts create mode 100644 console/src/app/modules/form-field/form-field.module.ts create mode 100644 console/src/app/modules/form-field/hint.directive.ts create mode 100644 console/src/app/modules/input/error-options.ts create mode 100644 console/src/app/modules/input/input.directive.spec.ts create mode 100644 console/src/app/modules/input/input.directive.ts create mode 100644 console/src/app/modules/input/input.module.ts create mode 100644 console/src/app/modules/label/label.component.html create mode 100644 console/src/app/modules/label/label.component.scss create mode 100644 console/src/app/modules/label/label.component.spec.ts create mode 100644 console/src/app/modules/label/label.component.ts create mode 100644 console/src/app/modules/label/label.module.ts delete mode 100644 console/src/app/modules/meta-layout/meta.scss create mode 100644 console/src/styles/error.scss create mode 100644 console/src/styles/input.scss diff --git a/console/angular.json b/console/angular.json index 7f63d532d2..b5c0c4a797 100644 --- a/console/angular.json +++ b/console/angular.json @@ -12,7 +12,7 @@ }, "root": "", "sourceRoot": "src", - "prefix": "app", + "prefix": "cnsl", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", diff --git a/console/package-lock.json b/console/package-lock.json index e407c05ae9..495a15a252 100644 --- a/console/package-lock.json +++ b/console/package-lock.json @@ -4,26 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1100.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.1.tgz", - "integrity": "sha512-DIAvTRRY+k7T2xHf4RVV06P16D0V7wSf1MSpGSDWVpfWcA3HNOSGfsk1F+COMlbFehXuKztwieXarv5rXbBCng==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.1", - "rxjs": "6.6.3" - } - }, "@angular-devkit/build-angular": { - "version": "0.1100.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1100.1.tgz", - "integrity": "sha512-w8NcoXuruOHio0D/JbX47iDl9FVH8X9k/OlZ/rSNVQ3uEpV6uxIaTm3fZ1ZSrKffi+97rKEwpHOf2N0DXl4XGQ==", + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1100.2.tgz", + "integrity": "sha512-5Qo3DDKggzUJKibNgeyE5mIMFYP0tVebNvMatpbnYnR/U0fUuuQdvNC68s380M5KoOuubfeXr0Js0VFk0mkaow==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.1", - "@angular-devkit/build-optimizer": "0.1100.1", - "@angular-devkit/build-webpack": "0.1100.1", - "@angular-devkit/core": "11.0.1", + "@angular-devkit/architect": "0.1100.2", + "@angular-devkit/build-optimizer": "0.1100.2", + "@angular-devkit/build-webpack": "0.1100.2", + "@angular-devkit/core": "11.0.2", "@babel/core": "7.12.3", "@babel/generator": "7.12.1", "@babel/plugin-transform-runtime": "7.12.1", @@ -31,7 +21,7 @@ "@babel/runtime": "7.12.1", "@babel/template": "7.10.4", "@jsdevtools/coverage-istanbul-loader": "3.0.5", - "@ngtools/webpack": "11.0.1", + "@ngtools/webpack": "11.0.2", "ansi-colors": "4.1.1", "autoprefixer": "9.8.6", "babel-loader": "8.1.0", @@ -41,7 +31,7 @@ "circular-dependency-plugin": "5.2.0", "copy-webpack-plugin": "6.2.1", "core-js": "3.6.5", - "css-loader": "5.0.0", + "css-loader": "4.3.0", "cssnano": "4.1.10", "file-loader": "6.1.1", "find-cache-dir": "3.3.1", @@ -91,6 +81,29 @@ "worker-plugin": "5.0.0" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.2.tgz", + "integrity": "sha512-wSMMM8eBPol48OtvIyrIq2H9rOIiJmrPEtPbH0BSuPX0B8BckVImeTPzloqxSrpul4tY7Iwx0zwISDEgb59Vbw==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.0.2", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", @@ -158,12 +171,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { @@ -245,9 +258,9 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/template": { @@ -262,17 +275,17 @@ } }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" @@ -298,9 +311,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -308,10 +321,22 @@ "to-fast-properties": "^2.0.0" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -341,9 +366,9 @@ } }, "@angular-devkit/build-optimizer": { - "version": "0.1100.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1100.1.tgz", - "integrity": "sha512-PpqBmDd+/cmaMj9MURe5pSSudo+Qz6BrGdzvYB16ekSp8bSDYLUriv5NvE/bm+ODKwo3jHgFrwWLiwK65vQcxQ==", + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1100.2.tgz", + "integrity": "sha512-2ZdEeAs0a53g9LDkP5H2mCEPLyk7yd9P7eTepNYvIOz3xJ6W6dB2CqotPMfnHgd4o12cbzCOWrPBxbfo/VnMig==", "dev": true, "requires": { "loader-utils": "2.0.0", @@ -362,29 +387,39 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1100.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1100.1.tgz", - "integrity": "sha512-nfgsUfP6WyZ35rxgjqDYydB552Si/JdYLMtwy/kAFybW/6yTpw0sBOgCQoppyQ4mvVwyX9X0ZTQsMNhPOzy3sA==", + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1100.2.tgz", + "integrity": "sha512-XVMtWoxNa3wJLRjJ846Y02PzupdbUizdAtggRu2731RLMvI1KawWlsTURi12MNUnoVQYm9eldiIA/Y1UqeE8mQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.1", - "@angular-devkit/core": "11.0.1", + "@angular-devkit/architect": "0.1100.2", + "@angular-devkit/core": "11.0.2", "rxjs": "6.6.3" - } - }, - "@angular-devkit/core": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.1.tgz", - "integrity": "sha512-ui3g7w/0SpU9oq8uwN9upR8Y1eOXZ+P2p3NyDydBrR7ZEfEkRLS1mhozN/ib8farrwK5N3kIIJxMb5t3187Hng==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.2.tgz", + "integrity": "sha512-wSMMM8eBPol48OtvIyrIq2H9rOIiJmrPEtPbH0BSuPX0B8BckVImeTPzloqxSrpul4tY7Iwx0zwISDEgb59Vbw==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.0.2", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -406,14 +441,47 @@ } }, "@angular-devkit/schematics": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.0.1.tgz", - "integrity": "sha512-rAOnAndcybEH398xf5wzmcUPCoCi0dKiOo/+1dkKU5aTxynw1OUnANt5K6A+ZZTGnJmfjtP0ovkZGYun9IUDxQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.0.2.tgz", + "integrity": "sha512-unNewc+Y9ofrdKxXNoSHKUL6wvV8Vgh2nJMTLI1VAw8nfqgWphI+s5XwbVzog65nhZ10xJeaUm9u5R8pxLDpQg==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.1", + "@angular-devkit/core": "11.0.2", "ora": "5.1.0", "rxjs": "6.6.3" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@angular/animations": { @@ -434,16 +502,16 @@ } }, "@angular/cli": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.1.tgz", - "integrity": "sha512-zB20jTLQxLpkJjhbYelhRyMcgGsjwbD8pSYYAO6QX656Tx1tCtJ2UskEtf4ePQvgzu0Ds2dnAEfco+tekIMRTA==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.2.tgz", + "integrity": "sha512-mebt4ikwXD3gsbHRxKCpn83yW3UVnhiVDEpSXljs1YxscZ1X1dXrxb2g6LdAJwVp9xY5ERqRQeZM7eChqLTrvg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.1", - "@angular-devkit/core": "11.0.1", - "@angular-devkit/schematics": "11.0.1", - "@schematics/angular": "11.0.1", - "@schematics/update": "0.1100.1", + "@angular-devkit/architect": "0.1100.2", + "@angular-devkit/core": "11.0.2", + "@angular-devkit/schematics": "11.0.2", + "@schematics/angular": "11.0.2", + "@schematics/update": "0.1100.2", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.2.0", @@ -461,6 +529,41 @@ "uuid": "8.3.1" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.2.tgz", + "integrity": "sha512-wSMMM8eBPol48OtvIyrIq2H9rOIiJmrPEtPbH0BSuPX0B8BckVImeTPzloqxSrpul4tY7Iwx0zwISDEgb59Vbw==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.0.2", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "debug": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", @@ -494,6 +597,12 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true } } }, @@ -696,9 +805,9 @@ } }, "@angular/language-service": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.0.0.tgz", - "integrity": "sha512-lwUVlaiIASNbKQ/EtCK5KOVIlpiyVvysN6idAD0rJHr6BRtrlqwiayNYbV5as5IJyPYLf2E8au3an9j0E/PFDw==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.0.2.tgz", + "integrity": "sha512-Cfam/NEP8hKkcqBVGlkBVuPkojZukmVOxdtsFIkIjJW/mywad2lIfjHR/0rZ43jD1bPb7s+tyYcJBgNg42p2ng==", "dev": true }, "@angular/material": { @@ -759,9 +868,9 @@ } }, "@babel/compat-data": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.5.tgz", - "integrity": "sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", + "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", "dev": true }, "@babel/core": { @@ -870,15 +979,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001158", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001158.tgz", - "integrity": "sha512-s5loVYY+yKpuVA3HyW8BarzrtJvwHReuzugQXlv1iR3LKSReoFXRm86mT6hT7PEF5RxW+XQZg+6nYjlywYzQ+g==", + "version": "1.0.30001159", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz", + "integrity": "sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.596", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.596.tgz", - "integrity": "sha512-nLO2Wd2yU42eSoNJVQKNf89CcEGqeFZd++QsnN2XIgje1s/19AgctfjLIbPORlvcCO8sYjLwX4iUgDdusOY8Sg==", + "version": "1.3.603", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.603.tgz", + "integrity": "sha512-J8OHxOeJkoSLgBXfV9BHgKccgfLMHh+CoeRo6wJsi6m0k3otaxS/5vrHpMNSEYY4MISwewqanPOuhAtuE8riQQ==", "dev": true }, "escalade": { @@ -888,9 +997,9 @@ "dev": true }, "node-releases": { - "version": "1.1.66", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", - "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==", + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", "dev": true } } @@ -929,12 +1038,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-replace-supers": { @@ -961,23 +1070,23 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" @@ -995,9 +1104,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1006,9 +1115,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -1023,13 +1132,12 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.1.tgz", - "integrity": "sha512-rsZ4LGvFTZnzdNZR5HZdmJVuXK8834R5QkF3WvcnBhrlVtF0HSIUC6zbreL9MgjTywhKokn8RIYRiq99+DLAxA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", "regexpu-core": "^4.7.1" } }, @@ -1054,9 +1162,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1209,15 +1317,6 @@ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, - "@babel/helper-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, "@babel/helper-remap-async-to-generator": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", @@ -1230,9 +1329,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1307,9 +1406,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1372,15 +1471,34 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", + "dev": true + }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + }, + "dependencies": { + "@babel/types": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } } } @@ -1518,9 +1636,9 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz", - "integrity": "sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", + "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1549,9 +1667,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz", - "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", + "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1717,9 +1835,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1784,12 +1902,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-replace-supers": { @@ -1816,23 +1934,23 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" @@ -1850,9 +1968,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1861,9 +1979,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -1993,12 +2111,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { @@ -2069,43 +2187,43 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2114,9 +2232,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -2163,12 +2281,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { @@ -2239,43 +2357,43 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2284,9 +2402,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -2334,12 +2452,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { @@ -2410,43 +2528,43 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2455,9 +2573,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -2502,12 +2620,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { @@ -2578,43 +2696,43 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2623,9 +2741,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -2688,12 +2806,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", - "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.7" } }, "@babel/helper-replace-supers": { @@ -2729,32 +2847,32 @@ } }, "@babel/parser": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", - "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", "dev": true }, "@babel/traverse": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", - "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.7.tgz", + "integrity": "sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.5", - "@babel/types": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2763,9 +2881,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -2837,9 +2955,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -2869,13 +2987,12 @@ } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz", - "integrity": "sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", + "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { @@ -2999,9 +3116,9 @@ } }, "@babel/types": { - "version": "7.12.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", - "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -3140,14 +3257,47 @@ } }, "@ngtools/webpack": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.0.1.tgz", - "integrity": "sha512-z62qQ4J5LhDxW68HjYYCRo+sDK/5yHwX4fCCY2iXngyTtA5cQbGI5WXr3+9B4foX64ft5WvV0WJkx8mjE/VR6w==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.0.2.tgz", + "integrity": "sha512-GbNP6HMBVoee2CkYW/pknprFCeiOLz4FGE06yr4m0700c1i6wuX7AzyHfBcLGAIP6nVblNOT3eh5M41b3cDf8g==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.1", + "@angular-devkit/core": "11.0.2", "enhanced-resolve": "5.3.1", "webpack-sources": "2.0.1" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@ngx-translate/core": { @@ -3264,24 +3414,57 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@schematics/angular": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.0.1.tgz", - "integrity": "sha512-cYq3NhFn4DLSXXtbYYU2w0sginkMfN1w7pXjZLT/+etXXbtANQAXSPrPrDQql004ZNMbuDKuC0aoXjv8hgXOfw==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.0.2.tgz", + "integrity": "sha512-tUIuCYJUzHYuiXGJ2KCuwxMocS56kPHaM8+neVYWwWbOxKzLZXv80gMm/pIWxrqUDCkIUi3yb4ienudFhgQLYg==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.1", - "@angular-devkit/schematics": "11.0.1", + "@angular-devkit/core": "11.0.2", + "@angular-devkit/schematics": "11.0.2", "jsonc-parser": "2.3.1" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@schematics/update": { - "version": "0.1100.1", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1100.1.tgz", - "integrity": "sha512-EVcqdM/d5rC5L1UYnwhFMk/TjHlNgL5LGfroE13C38A+WpKKJquAjgOQLj4nPvJ5csdEZqn3Sui9yeEWc3hklQ==", + "version": "0.1100.2", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1100.2.tgz", + "integrity": "sha512-pETCmQylIQ7RM+8uqDkI3KfOaX5H7nuzmMXby28zdLPMZniYti0gJxieiVFhvdz2Ot2Axj0hznfmraFgC9mQMw==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.1", - "@angular-devkit/schematics": "11.0.1", + "@angular-devkit/core": "11.0.2", + "@angular-devkit/schematics": "11.0.2", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", "npm-package-arg": "^8.0.0", @@ -3290,11 +3473,42 @@ "semver-intersect": "1.4.0" }, "dependencies": { + "@angular-devkit/core": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.2.tgz", + "integrity": "sha512-vUmmUNmNM9oRcDmt0PunU/ayglo0apq4pGL9Z5jj6alf2WwEiTcGHjyuZSDIO9MOLi41519jp3mDx79qXvvyww==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true } } }, @@ -3308,13 +3522,13 @@ } }, "@stylelint/postcss-markdown": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.1.tgz", - "integrity": "sha512-iDxMBWk9nB2BPi1VFQ+Dc5+XpvODBHw2n3tYpaBZuEAFQlbtF9If0Qh5LTTwSi/XwdbJ2jt+0dis3i8omyggpw==", + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz", + "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==", "dev": true, "requires": { - "remark": "^12.0.0", - "unist-util-find-all-after": "^3.0.1" + "remark": "^13.0.0", + "unist-util-find-all-after": "^3.0.2" } }, "@types/bytebuffer": { @@ -3353,9 +3567,9 @@ "integrity": "sha512-6PjMFKl13cgB4kRdYtvyjKl8VVa0PXS2IdVxHhQ8GEKbxBkyJtSbaIeK1eZGjDKN7dvUh4vkOvU9FMwYNv4GQQ==" }, "@types/jasmine": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.1.tgz", - "integrity": "sha512-eeSCVhBsgwHNS1FmaMu4zrLxfykCTWJMLFZv7lmyrZQjw7foUUXoPu4GukSN9v7JvUw7X+/aDH3kCaymirBSTg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.2.tgz", + "integrity": "sha512-AzfesNFLvOs6Q1mHzIsVJXSeUnqVh4ZHG8ngygKJfbkcSLwzrBVm/LKa+mR8KrOfnWtUL47112gde1MC0IXqpQ==", "dev": true }, "@types/jasminewd2": { @@ -3378,6 +3592,15 @@ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -3385,15 +3608,15 @@ "dev": true }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "@types/node": { - "version": "14.14.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", - "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==" + "version": "14.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.9.tgz", + "integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -4245,12 +4468,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -4682,14 +4899,6 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "call-bind": { @@ -4786,12 +4995,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "ccount": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", - "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", - "dev": true - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4809,12 +5012,6 @@ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "dev": true }, - "character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true - }, "character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", @@ -4907,12 +5104,6 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -5055,12 +5246,6 @@ } } }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -5482,15 +5667,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001158", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001158.tgz", - "integrity": "sha512-s5loVYY+yKpuVA3HyW8BarzrtJvwHReuzugQXlv1iR3LKSReoFXRm86mT6hT7PEF5RxW+XQZg+6nYjlywYzQ+g==", + "version": "1.0.30001159", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz", + "integrity": "sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.596", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.596.tgz", - "integrity": "sha512-nLO2Wd2yU42eSoNJVQKNf89CcEGqeFZd++QsnN2XIgje1s/19AgctfjLIbPORlvcCO8sYjLwX4iUgDdusOY8Sg==", + "version": "1.3.603", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.603.tgz", + "integrity": "sha512-J8OHxOeJkoSLgBXfV9BHgKccgfLMHh+CoeRo6wJsi6m0k3otaxS/5vrHpMNSEYY4MISwewqanPOuhAtuE8riQQ==", "dev": true }, "escalade": { @@ -5500,9 +5685,9 @@ "dev": true }, "node-releases": { - "version": "1.1.66", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", - "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==", + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", "dev": true }, "semver": { @@ -5664,66 +5849,31 @@ } }, "css-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.0.tgz", - "integrity": "sha512-9g35eXRBgjvswyJWoqq/seWp+BOxvUl8IinVNTsUBFFxtwfEYvlmEn6ciyn0liXGbGh5HyJjPGCuobDSfqMIVg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", + "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", "dev": true, "requires": { - "camelcase": "^6.1.0", + "camelcase": "^6.0.0", "cssesc": "^3.0.0", - "icss-utils": "^5.0.0", + "icss-utils": "^4.1.1", "loader-utils": "^2.0.0", - "postcss": "^8.1.1", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.3", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", + "schema-utils": "^2.7.1", "semver": "^7.3.2" }, "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "postcss": { - "version": "8.1.7", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.7.tgz", - "integrity": "sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ==", - "dev": true, - "requires": { - "colorette": "^1.2.1", - "line-column": "^1.0.2", - "nanoid": "^3.1.16", - "source-map": "^0.6.1" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -5911,19 +6061,19 @@ }, "dependencies": { "css-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.1.tgz", - "integrity": "sha512-WroX+2MvsYcRGP8QA0p+rxzOniT/zpAoQ/DTKDSJzh5T3IQKUkFHeIIfgIapm2uaP178GWY3Mime1qbk8GO/tA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.1.tgz", + "integrity": "sha512-NVN42M2fjszcUNpDbdkvutgQSlFYsr1z7kqeuCagHnNLBfYor6uP1WL1KrkmdYZ5Y1vTBCIOI/C/+8T98fJ71w==", "dev": true, "requires": { - "mdn-data": "2.0.12", + "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "mdn-data": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.12.tgz", - "integrity": "sha512-ULbAlgzVb8IqZ0Hsxm6hHSlQl3Jckst2YEQS7fODu9ilNWy2LvcoSY7TRFIktABP2mdppBioc66va90T+NUs8Q==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true } } @@ -6093,12 +6243,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -7211,12 +7355,12 @@ } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-loader": { @@ -7255,9 +7399,9 @@ } }, "file-saver": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", - "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" }, "file-uri-to-path": { "version": "1.0.0", @@ -7388,14 +7532,30 @@ } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "flatted": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -7782,9 +7942,9 @@ } }, "google-proto-files": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.2.0.tgz", - "integrity": "sha512-sSzjssqNqLRl3+vF+IdXGcYsOjZAf1veOEQFc5f3cR8WReoNsdg3laxu9sq7vgQ/OL/sjCp7I+917e79iJNcIQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.3.0.tgz", + "integrity": "sha512-A2UMuWes/9dgEWV8jr+KBM95LyyJQpHMlGbBV0wFIuJs1VRlgpPWR1m39fat1J2nKLYPyfhi42TTnEOnGWopWg==", "requires": { "protobufjs": "^6.8.0", "walkdir": "^0.4.0" @@ -7927,14 +8087,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -8244,12 +8396,6 @@ } } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -8328,10 +8474,13 @@ } }, "icss-utils": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.0.0.tgz", - "integrity": "sha512-aF2Cf/CkEZrI/vsu5WI/I+akFgdbwQHVE9YRZxATrhH4PVIe6a3BIjwjEcW+z+jP/hNh+YvM3lAAn1wJQ6opSg==", - "dev": true + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } }, "ieee754": { "version": "1.2.1", @@ -8624,12 +8773,6 @@ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "dev": true }, - "is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", - "dev": true - }, "is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", @@ -8868,9 +9011,9 @@ } }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-plain-object": { @@ -8880,14 +9023,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "is-regex": { @@ -8941,24 +9076,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -8986,13 +9109,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -9151,9 +9271,9 @@ "dev": true }, "jasmine-spec-reporter": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-5.0.2.tgz", - "integrity": "sha512-6gP1LbVgJ+d7PKksQBc2H0oDGNRQI3gKUsWlswKaQ2fif9X5gzhQcgM5+kiJGCQVurOG09jqNhk7payggyp5+g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-6.0.0.tgz", + "integrity": "sha512-MvTOVoMxDZAftQYBApIlSfKnGMzi9cj351nXeqtnZTuXffPlbONN31+Es7F+Ke4okUeQ2xISukt4U1npfzLVrQ==", "dev": true, "requires": { "colors": "1.4.0" @@ -9632,9 +9752,9 @@ "dev": true }, "known-css-properties": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.19.0.tgz", - "integrity": "sha512-eYboRV94Vco725nKMlpkn3nV2+96p9c3gKXRsYqAJSswSENvBhN7n5L+uDhY58xQa0UukWsDMTGELzmD8Q+wTA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.20.0.tgz", + "integrity": "sha512-URvsjaA9ypfreqJ2/ylDr5MUERhJZ+DhguoWRr2xgS5C7aGCalXo+ewL+GixgKBfhT2vuL02nbIgNGqVWgTOYw==", "dev": true }, "lcid": { @@ -9736,16 +9856,6 @@ "immediate": "~3.0.5" } }, - "line-column": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", - "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", - "dev": true, - "requires": { - "isarray": "^1.0.0", - "isobject": "^2.0.0" - } - }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -10037,21 +10147,6 @@ "object-visit": "^1.0.0" } }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true - }, - "markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "dev": true, - "requires": { - "repeat-string": "^1.0.0" - } - }, "mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -10069,15 +10164,38 @@ "safe-buffer": "^5.1.2" } }, - "mdast-util-compact": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-2.0.1.tgz", - "integrity": "sha512-7GlnT24gEwDrdAwEHrU4Vv5lLWrEer4KOkAiKT9nYstsTad7Oc1TwqT2zIMKRdZF7cTuaf+GA1E4Kv7jJh8mPA==", + "mdast-util-from-markdown": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.1.tgz", + "integrity": "sha512-qJXNcFcuCSPqUF0Tb0uYcFDIq67qwB3sxo9RPdf9vG8T90ViKnksFqdB/Coq2a7sTnxL/Ify2y7aIQXDkQFH0w==", "dev": true, "requires": { - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^1.0.0", + "micromark": "~2.10.0", + "parse-entities": "^2.0.0" } }, + "mdast-util-to-markdown": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.5.3.tgz", + "integrity": "sha512-sr8q7fQJ1xoCqZSXW6dO/MYu2Md+a4Hfk9uO+XHCfiBhVM0EgWtfAV7BuN+ff6otUeu2xDyt1o7vhZGwOG3+BA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^1.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -10133,9 +10251,9 @@ } }, "meow": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", - "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz", + "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -10143,35 +10261,62 @@ "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", - "normalize-package-data": "^2.5.0", + "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "hosted-git-info": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", + "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.6", + "resolve": "^1.17.0", + "semver": "^7.3.2", + "validate-npm-package-license": "^3.0.1" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -10208,6 +10353,27 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, + "micromark": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.10.1.tgz", + "integrity": "sha512-fUuVF8sC1X7wsCS29SYQ2ZfIZYbTymp0EYr6sab3idFjigFFjGa5UwoniPlV9tAgntjuapW1t9U+S0yDYeGKHQ==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -10349,6 +10515,14 @@ "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + } } }, "minipass": { @@ -10495,12 +10669,6 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, - "nanoid": { - "version": "3.1.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz", - "integrity": "sha512-+AK8MN0WHji40lj8AEuwLOvLSbWYApQpre/aFJZD71r43wVRLrOYS4FmJOPQYon1TqB462RzrrxlfA74XRES8w==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -11052,14 +11220,6 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "object.assign": { @@ -11091,14 +11251,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "object.values": { @@ -12155,52 +12307,44 @@ } }, "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", "dev": true, "requires": { - "icss-utils": "^5.0.0", + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.4" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", - "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", - "util-deprecate": "^1.0.2" - } - } + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" } }, "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", "dev": true, "requires": { - "icss-utils": "^5.0.0" + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" } }, "postcss-normalize-charset": { @@ -12506,9 +12650,9 @@ "dev": true }, "prettier": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", - "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.0.tgz", + "integrity": "sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw==", "dev": true }, "process": { @@ -12547,9 +12691,9 @@ } }, "protobufjs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", - "integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -12567,9 +12711,9 @@ }, "dependencies": { "@types/node": { - "version": "13.13.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.15.tgz", - "integrity": "sha512-kwbcs0jySLxzLsa2nWUAGOd/s21WU1jebrEdtzhsj1D4Yps1EOuyI1Qcu+FD56dL7NRNIJtDDjcqIG22NwkgLw==" + "version": "13.13.32", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.32.tgz", + "integrity": "sha512-sPBvDnrwZE1uePhkCEyI/qQlgZM5kePPAhHIFDWNsOrWBFRBOk3LKJYmVCLeLZlL9Ub/FzMJb31OTWCg2F+06g==" } } }, @@ -13432,60 +13576,32 @@ } }, "remark": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.1.tgz", - "integrity": "sha512-gS7HDonkdIaHmmP/+shCPejCEEW+liMp/t/QwmF0Xt47Rpuhl32lLtDV1uKWvGoq+kxr5jSgg5oAIpGuyULjUw==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", "dev": true, "requires": { - "remark-parse": "^8.0.0", - "remark-stringify": "^8.0.0", - "unified": "^9.0.0" + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" } }, "remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", "dev": true, "requires": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "mdast-util-from-markdown": "^0.8.0" } }, "remark-stringify": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.1.1.tgz", - "integrity": "sha512-q4EyPZT3PcA3Eq7vPpT6bIdokXzFGp9i85igjmhRyXWmPs0Y6/d2FYwUNotKAWyLch7g0ASZJn/KHHcHZQ163A==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.0.tgz", + "integrity": "sha512-8x29DpTbVzEc6Dwb90qhxCtbZ6hmj3BxWWDpMhA+1WM4dOEGH5U5/GFe3Be5Hns5MvPSFAr1e2KSVtKZkK5nUw==", "dev": true, "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^2.0.0", - "mdast-util-compact": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^3.0.0", - "unherit": "^1.0.4", - "xtend": "^4.0.1" + "mdast-util-to-markdown": "^0.5.0" } }, "remove-trailing-separator": { @@ -14222,12 +14338,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -14365,12 +14480,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -14748,9 +14857,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -14773,9 +14882,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -14845,12 +14954,6 @@ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "dev": true }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -15031,67 +15134,23 @@ } }, "string.prototype.trimend": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", - "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", - "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string_decoder": { @@ -15103,19 +15162,6 @@ "safe-buffer": "~5.2.0" } }, - "stringify-entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", - "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.2", - "is-hexadecimal": "^1.0.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -15210,22 +15256,22 @@ } }, "stylelint": { - "version": "13.7.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.7.2.tgz", - "integrity": "sha512-mmieorkfmO+ZA6CNDu1ic9qpt4tFvH2QUB7vqXgrMVHe5ENU69q7YDq0YUg/UHLuCsZOWhUAvcMcLzLDIERzSg==", + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.8.0.tgz", + "integrity": "sha512-iHH3dv3UI23SLDrH4zMQDjLT9/dDIz/IpoFeuNxZmEx86KtfpjDOscxLTFioQyv+2vQjPlRZnK0UoJtfxLICXQ==", "dev": true, "requires": { "@stylelint/postcss-css-in-js": "^0.37.2", - "@stylelint/postcss-markdown": "^0.36.1", + "@stylelint/postcss-markdown": "^0.36.2", "autoprefixer": "^9.8.6", "balanced-match": "^1.0.0", "chalk": "^4.1.0", "cosmiconfig": "^7.0.0", - "debug": "^4.1.1", + "debug": "^4.2.0", "execall": "^2.0.0", "fast-glob": "^3.2.4", "fastest-levenshtein": "^1.0.12", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.0.1", @@ -15234,14 +15280,14 @@ "ignore": "^5.1.8", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.19.0", + "known-css-properties": "^0.20.0", "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^7.1.1", + "meow": "^8.0.0", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", - "postcss": "^7.0.32", + "postcss": "^7.0.35", "postcss-html": "^0.36.0", "postcss-less": "^3.1.4", "postcss-media-query-parser": "^0.2.3", @@ -15249,7 +15295,7 @@ "postcss-safe-parser": "^4.0.2", "postcss-sass": "^0.4.4", "postcss-scss": "^2.1.1", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^6.0.4", "postcss-syntax": "^0.36.2", "postcss-value-parser": "^4.1.0", "resolve-from": "^5.0.0", @@ -15260,8 +15306,8 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^6.0.1", - "v8-compile-cache": "^2.1.1", + "table": "^6.0.3", + "v8-compile-cache": "^2.2.0", "write-file-atomic": "^3.0.3" }, "dependencies": { @@ -15272,12 +15318,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -15307,9 +15352,9 @@ "dev": true }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -15333,6 +15378,92 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", + "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1", + "util-deprecate": "^1.0.2" + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -15552,9 +15683,9 @@ "dev": true }, "table": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.3.tgz", - "integrity": "sha512-8321ZMcf1B9HvVX/btKv8mMZahCjn2aYrDlpqHaBFCfnox64edeH9kEid0vTLTRR8gWR2A20aDgeuTTea4sVtw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz", + "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -15564,9 +15695,9 @@ }, "dependencies": { "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -15910,24 +16041,12 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "dev": true }, - "trim-trailing-lines": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", - "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", - "dev": true - }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -16082,16 +16201,6 @@ "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==", "dev": true }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -16135,15 +16244,9 @@ }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true } } @@ -16191,29 +16294,20 @@ } }, "unist-util-find-all-after": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.1.tgz", - "integrity": "sha512-0GICgc++sRJesLwEYDjFVJPJttBpVQaTNgc6Jw0Jhzvfs+jtKePEMu+uD+PqkRUrAvGQqwhpDwLGWo1PK8PDEw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", + "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", "dev": true, "requires": { "unist-util-is": "^4.0.0" } }, "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.3.tgz", + "integrity": "sha512-bTofCFVx0iQM8Jqb1TBDVRIQW03YkD3p66JOd/aCWuqzlLyUtx1ZAGw/u+Zw+SttKvSVcvTiKYbfrtLoLefykw==", "dev": true }, - "unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "dev": true, - "requires": { - "unist-util-visit": "^2.0.0" - } - }, "unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -16223,27 +16317,6 @@ "@types/unist": "^2.0.2" } }, - "unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", - "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - }, "universal-analytics": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.23.tgz", @@ -16256,9 +16329,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -16365,12 +16438,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, @@ -16475,9 +16542,9 @@ "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, "validate-npm-package-license": { @@ -16535,19 +16602,13 @@ }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true } } }, - "vfile-location": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.1.0.tgz", - "integrity": "sha512-FCZ4AN9xMcjFIG1oGmZKo61PjwJHRVA+0/tPUP2ul4uIwjGGndIxavEMRpWn5p4xwm/ZsdXp9YNygf1ZyE4x8g==", - "dev": true - }, "vfile-message": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", @@ -16748,13 +16809,6 @@ "binary-extensions": "^1.0.0" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -17009,12 +17063,6 @@ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -17359,9 +17407,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -17449,12 +17497,6 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -17796,15 +17838,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -17920,6 +17953,12 @@ "requires": { "tslib": "^2.0.0" } + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true } } } diff --git a/console/package.json b/console/package.json index 06eeef625e..b20094457d 100644 --- a/console/package.json +++ b/console/package.json @@ -30,8 +30,8 @@ "angular-oauth2-oidc": "^10.0.3", "angularx-qrcode": "^10.0.11", "cors": "^2.8.5", - "file-saver": "^2.0.2", - "google-proto-files": "^2.2.0", + "file-saver": "^2.0.5", + "google-proto-files": "^2.3.0", "google-protobuf": "^3.13.0", "grpc": "^1.24.3", "grpc-web": "^1.2.1", @@ -44,24 +44,24 @@ "zone.js": "~0.11.3" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1100.1", - "@angular/cli": "~11.0.1", + "@angular-devkit/build-angular": "~0.1100.2", + "@angular/cli": "~11.0.2", "@angular/compiler-cli": "~11.0.0", - "@angular/language-service": "~11.0.0", - "@types/jasmine": "~3.6.0", + "@types/jasmine": "~3.6.2", + "@angular/language-service": "~11.0.2", "@types/jasminewd2": "~2.0.3", - "@types/node": "^14.14.6", + "@types/node": "^14.14.9", "codelyzer": "^6.0.0", "jasmine-core": "~3.6.0", - "jasmine-spec-reporter": "~5.0.0", + "jasmine-spec-reporter": "~6.0.0", "karma": "~5.2.3", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", - "prettier": "^2.1.2", + "prettier": "^2.2.0", "protractor": "~7.0.0", - "stylelint": "^13.7.2", + "stylelint": "^13.8.0", "stylelint-config-standard": "^20.0.0", "stylelint-scss": "^3.18.0", "ts-node": "~9.0.0", diff --git a/console/src/app/animations.ts b/console/src/app/animations.ts index acb2ef4e95..dc9fcfcf12 100644 --- a/console/src/app/animations.ts +++ b/console/src/app/animations.ts @@ -27,6 +27,23 @@ export const toolbarAnimation: AnimationTriggerMetadata = ]), ]); +export const adminLineAnimation: AnimationTriggerMetadata = + trigger('adminline', [ + transition(':enter', [ + style({ + transform: 'translateY(100%)', + opacity: 0.5, + }), + animate( + '.2s ease-out', + style({ + transform: 'translateY(0%)', + opacity: 1, + }), + ), + ]), + ]); + export const accountCard: AnimationTriggerMetadata = trigger('accounts', [ transition(':enter', [ style({ diff --git a/console/src/app/app.component.html b/console/src/app/app.component.html index ed66bf1676..a3af0d54be 100644 --- a/console/src/app/app.component.html +++ b/console/src/app/app.component.html @@ -24,10 +24,11 @@ - - - +
+ +
+
  • diff --git a/console/src/app/modules/changes/changes.component.scss b/console/src/app/modules/changes/changes.component.scss index 21c8403652..de886493ee 100644 --- a/console/src/app/modules/changes/changes.component.scss +++ b/console/src/app/modules/changes/changes.component.scss @@ -1,11 +1,23 @@ @import '~@angular/material/theming'; -.header { - display: block; - margin-bottom: 1rem; - font-weight: 400; - margin-top: 1rem; - font-size: 14px; +.change-header { + display: flex; + justify-content: space-between; + align-items: center; + + .ch-header { + display: block; + margin-bottom: 1rem; + font-weight: 400; + margin-top: 1rem; + font-size: 14px; + letter-spacing: .05em; + text-transform: uppercase; + } + + .icon { + font-size: 1.2rem; + } } @mixin changes-theme($theme) { diff --git a/console/src/app/modules/changes/changes.component.ts b/console/src/app/modules/changes/changes.component.ts index bfc57e76ff..eeee5de055 100644 --- a/console/src/app/modules/changes/changes.component.ts +++ b/console/src/app/modules/changes/changes.component.ts @@ -1,6 +1,6 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { BehaviorSubject, from, Observable, of } from 'rxjs'; -import { catchError, scan, take, tap } from 'rxjs/operators'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs'; +import { catchError, debounceTime, scan, take, takeUntil, tap } from 'rxjs/operators'; import { Change, Changes } from 'src/app/proto/generated/management_pb'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { ManagementService } from 'src/app/services/mgmt.service'; @@ -10,6 +10,7 @@ export enum ChangeType { USER = 'user', ORG = 'org', PROJECT = 'project', + APP = 'app', } @Component({ @@ -17,10 +18,12 @@ export enum ChangeType { templateUrl: './changes.component.html', styleUrls: ['./changes.component.scss'], }) -export class ChangesComponent implements OnInit { +export class ChangesComponent implements OnInit, OnDestroy { @Input() public changeType: ChangeType = ChangeType.USER; @Input() public id: string = ''; + @Input() public secId: string = ''; @Input() public sortDirectionAsc: boolean = true; + @Input() public refresh!: Observable; public bottom: boolean = false; private _done: BehaviorSubject = new BehaviorSubject(false); @@ -30,10 +33,23 @@ export class ChangesComponent implements OnInit { loading: Observable = this._loading.asObservable(); public data!: Observable; public changes!: Changes.AsObject; - constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) { } + private destroyed$: Subject = new Subject(); + constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) { + + } ngOnInit(): void { this.init(); + if (this.refresh) { + this.refresh.pipe(takeUntil(this.destroyed$), debounceTime(2000)).subscribe(() => { + console.log('asdf'); + this.init(); + }); + } + } + + ngOnDestroy(): void { + this.destroyed$.next(); } public scrollHandler(e: any): void { @@ -42,7 +58,7 @@ export class ChangesComponent implements OnInit { } } - private init(): void { + public init(): void { let first: Promise; switch (this.changeType) { case ChangeType.MYUSER: first = this.authUserService.GetMyUserChanges(20, 0); @@ -53,6 +69,8 @@ export class ChangesComponent implements OnInit { break; case ChangeType.ORG: first = this.mgmtUserService.OrgChanges(this.id, 20, 0); break; + case ChangeType.APP: first = this.mgmtUserService.ApplicationChanges(this.id, this.secId, 20, 0); + break; } this.mapAndUpdate(first); @@ -78,6 +96,8 @@ export class ChangesComponent implements OnInit { break; case ChangeType.ORG: more = this.mgmtUserService.OrgChanges(this.id, 20, cursor); break; + case ChangeType.APP: more = this.mgmtUserService.ApplicationChanges(this.id, this.secId, 20, cursor); + break; } this.mapAndUpdate(more); diff --git a/console/src/app/modules/changes/changes.module.ts b/console/src/app/modules/changes/changes.module.ts index 5c7165c3a8..c9298c72f4 100644 --- a/console/src/app/modules/changes/changes.module.ts +++ b/console/src/app/modules/changes/changes.module.ts @@ -1,7 +1,10 @@ import { ScrollingModule } from '@angular/cdk/scrolling'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module'; import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module'; @@ -20,10 +23,13 @@ import { ChangesComponent } from './changes.component'; ScrollableModule, MatProgressSpinnerModule, TranslateModule, + MatIconModule, + MatButtonModule, HasRolePipeModule, ScrollingModule, LocalizedDatePipeModule, TimestampToDatePipeModule, + MatTooltipModule, ], exports: [ ChangesComponent, diff --git a/console/src/app/modules/contributors/contributors.component.html b/console/src/app/modules/contributors/contributors.component.html index 03d75a1f84..ec137c2480 100644 --- a/console/src/app/modules/contributors/contributors.component.html +++ b/console/src/app/modules/contributors/contributors.component.html @@ -1,5 +1,5 @@
    - {{ title }} + {{ title }} {{ description }}
    @@ -34,9 +34,9 @@ add -
    diff --git a/console/src/app/modules/contributors/contributors.component.scss b/console/src/app/modules/contributors/contributors.component.scss index 6df27398fd..a5cfb969e0 100644 --- a/console/src/app/modules/contributors/contributors.component.scss +++ b/console/src/app/modules/contributors/contributors.component.scss @@ -1,10 +1,13 @@ .groups { padding-top: 1rem; - .header { + .co-header { display: block; margin-bottom: 1rem; font-weight: 400; + font-size: 14px; + letter-spacing: .05em; + text-transform: uppercase; } .sub-header { @@ -45,7 +48,11 @@ .refresh-img { float: left; - margin: 0 8px 0 -15px; + margin: 0 0 0 -15px; + + .icon { + font-size: 1.2rem; + } } .avatar-circle { diff --git a/console/src/app/modules/contributors/contributors.module.ts b/console/src/app/modules/contributors/contributors.module.ts index a1a22614a5..1edeb2c2eb 100644 --- a/console/src/app/modules/contributors/contributors.module.ts +++ b/console/src/app/modules/contributors/contributors.module.ts @@ -4,6 +4,7 @@ import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { TranslateModule } from '@ngx-translate/core'; import { AvatarModule } from '../avatar/avatar.module'; import { ContributorsComponent } from './contributors.component'; @@ -19,6 +20,7 @@ import { ContributorsComponent } from './contributors.component'; MatTooltipModule, MatButtonModule, MatProgressSpinnerModule, + TranslateModule, ], exports: [ ContributorsComponent, diff --git a/console/src/app/modules/detail-layout/detail-layout.component.scss b/console/src/app/modules/detail-layout/detail-layout.component.scss index 309721c6d7..f109bd6611 100644 --- a/console/src/app/modules/detail-layout/detail-layout.component.scss +++ b/console/src/app/modules/detail-layout/detail-layout.component.scss @@ -15,6 +15,7 @@ padding-bottom: 3rem; .detail-left { + align-self: flex-start; width: 100px; display: flex; padding: 1rem; diff --git a/console/src/app/modules/form-field/animations.ts b/console/src/app/modules/form-field/animations.ts new file mode 100644 index 0000000000..ca0647cdc5 --- /dev/null +++ b/console/src/app/modules/form-field/animations.ts @@ -0,0 +1,18 @@ +import { animate, AnimationTriggerMetadata, state, style, transition, trigger } from '@angular/animations'; + +/** + * Animations used by the CnslFormFieldComponent. + */ +export const cnslFormFieldAnimations: { + readonly transitionMessages: AnimationTriggerMetadata; +} = { + /** Animation that transitions the form field's error and hint messages. */ + transitionMessages: trigger('transitionMessages', [ + // TODO(mmalerba): Use angular animations for label animation as well. + state('enter', style({ opacity: 1, transform: 'translateY(0%)' })), + transition('void => enter', [ + style({ opacity: 0, transform: 'translateY(-100%)' }), + animate('3000ms cubic-bezier(0.55, 0, 0.55, 0.2)'), + ]), + ]), +}; diff --git a/console/src/app/modules/form-field/error.directive.ts b/console/src/app/modules/form-field/error.directive.ts new file mode 100644 index 0000000000..1231f1cd02 --- /dev/null +++ b/console/src/app/modules/form-field/error.directive.ts @@ -0,0 +1,20 @@ +import { Directive, InjectionToken, Input } from '@angular/core'; + +let nextUniqueId = 0; + +export const CNSL_ERROR = new InjectionToken('CnslError'); + +@Directive({ + selector: '[cnsl-error]', + host: { + 'class': 'cnsl-error', + 'role': 'alert', + '[attr.id]': 'id', + }, + providers: [{ provide: CNSL_ERROR, useExisting: CnslErrorDirective }], +}) +export class CnslErrorDirective { + @Input() id: string = `cnsl-error-${nextUniqueId++}`; + + constructor() { } +} diff --git a/console/src/app/modules/form-field/form-field.component.html b/console/src/app/modules/form-field/form-field.component.html new file mode 100644 index 0000000000..5631b68cc1 --- /dev/null +++ b/console/src/app/modules/form-field/form-field.component.html @@ -0,0 +1,17 @@ +
    + +
    + + +
    +
    +
    + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/console/src/app/modules/form-field/form-field.component.scss b/console/src/app/modules/form-field/form-field.component.scss new file mode 100644 index 0000000000..d22ee1fe9f --- /dev/null +++ b/console/src/app/modules/form-field/form-field.component.scss @@ -0,0 +1,45 @@ + +@import '~@angular/material/theming'; + +@mixin cnsl-form-field-theme($theme) { + $primary: map-get($theme, primary); + $primary-color: mat-color($primary, 500); + $is-dark-theme: map-get($theme, is-dark); + + .ng-untouched { + .cnsl-error { + visibility: hidden; + transition: visibility .2 ease; + } + } + + .cnsl-form-field-wrapper { + width: 100%; + margin: 10px 0; + } + + .cnsl-rel { + position: relative; + } + + [cnslSuffix] { + position: absolute; + right: .5rem; + top: 9px; + height: inherit; + vertical-align: middle; + } + + // Wrapper for the hints and error messages. + .cnsl-form-field-subscript-wrapper { + position: absolute; + box-sizing: border-box; + width: 100%; + overflow: hidden; // prevents multi-line errors from overlapping the control + } + + .cnsl-form-field-hint-wrapper, + .cnsl-form-field-error-wrapper { + display: flex; + } +} diff --git a/console/src/app/modules/form-field/form-field.component.spec.ts b/console/src/app/modules/form-field/form-field.component.spec.ts new file mode 100644 index 0000000000..a30d652a71 --- /dev/null +++ b/console/src/app/modules/form-field/form-field.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { CnslFormFieldComponent } from './form-field.component'; + +describe('CnslFormFieldComponent', () => { + let component: CnslFormFieldComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [CnslFormFieldComponent], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CnslFormFieldComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/form-field/form-field.component.ts b/console/src/app/modules/form-field/form-field.component.ts new file mode 100644 index 0000000000..e06efc1485 --- /dev/null +++ b/console/src/app/modules/form-field/form-field.component.ts @@ -0,0 +1,164 @@ +import { + AfterContentInit, + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ContentChild, + ContentChildren, + ElementRef, + HostListener, + Inject, + InjectionToken, + OnDestroy, + QueryList, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { NgControl } from '@angular/forms'; +import { MatFormFieldControl } from '@angular/material/form-field'; +import { Subject } from 'rxjs'; +import { startWith, takeUntil } from 'rxjs/operators'; + +import { cnslFormFieldAnimations } from './animations'; +import { CNSL_ERROR, CnslErrorDirective } from './error.directive'; +import { _CNSL_HINT, CnslHintDirective } from './hint.directive'; + +export const CNSL_FORM_FIELD = new InjectionToken('CnslFormFieldComponent'); + +class CnslFormFieldBase { + constructor(public _elementRef: ElementRef) { } +} + +@Component({ + selector: 'cnsl-form-field', + templateUrl: './form-field.component.html', + styleUrls: ['./form-field.component.scss'], + providers: [ + { provide: CNSL_FORM_FIELD, useExisting: CnslFormFieldComponent }, + ], + host: { + '[class.ng-untouched]': '_shouldForward("untouched")', + '[class.ng-touched]': '_shouldForward("touched")', + '[class.ng-pristine]': '_shouldForward("pristine")', + '[class.ng-dirty]': '_shouldForward("dirty")', + '[class.ng-valid]': '_shouldForward("valid")', + '[class.ng-invalid]': '_shouldForward("invalid")', + '[class.ng-pending]': '_shouldForward("pending")', + // '[class.cnsl-form-field-invalid]': '_control.errorState', + }, + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: [cnslFormFieldAnimations.transitionMessages], +}) +export class CnslFormFieldComponent extends CnslFormFieldBase implements OnDestroy, AfterContentInit, AfterViewInit { + focused: boolean = false; + private _destroyed: Subject = new Subject(); + + @ViewChild('connectionContainer', { static: true }) _connectionContainerRef!: ElementRef; + @ViewChild('inputContainer') _inputContainerRef!: ElementRef; + @ContentChild(MatFormFieldControl) _controlNonStatic!: MatFormFieldControl; + @ContentChild(MatFormFieldControl, { static: true }) _controlStatic!: MatFormFieldControl; + get _control(): MatFormFieldControl { + // TODO(crisbeto): we need this workaround in order to support both Ivy and ViewEngine. + // We should clean this up once Ivy is the default renderer. + return this._explicitFormFieldControl || this._controlNonStatic || this._controlStatic; + } + set _control(value: MatFormFieldControl) { + this._explicitFormFieldControl = value; + } + private _explicitFormFieldControl!: MatFormFieldControl; + readonly stateChanges: Subject = new Subject(); + + _subscriptAnimationState: string = ''; + + @ContentChildren(CNSL_ERROR as any, { descendants: true }) _errorChildren!: QueryList; + @ContentChildren(_CNSL_HINT, { descendants: true }) _hintChildren!: QueryList; + + @HostListener('blur', ['false']) + _focusChanged(isFocused: boolean): void { + console.log('blur1'); + if (isFocused !== this.focused && (!isFocused)) { + this.focused = isFocused; + this.stateChanges.next(); + } + } + + constructor(public _elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef, + @Inject(ElementRef) + // Use `ElementRef` here so Angular has something to inject. + _labelOptions: any) { + super(_elementRef); + + } + + public ngAfterViewInit(): void { + // Avoid animations on load. + this._subscriptAnimationState = 'enter'; + this._changeDetectorRef.detectChanges(); + } + + public ngOnDestroy(): void { + this._destroyed.next(); + this._destroyed.complete(); + } + + public ngAfterContentInit(): void { + this._validateControlChild(); + + const control = this._control; + control.stateChanges.pipe(startWith(null)).subscribe(() => { + this._syncDescribedByIds(); + this._changeDetectorRef.markForCheck(); + }); + + // Run change detection if the value changes. + if (control.ngControl && control.ngControl.valueChanges) { + control.ngControl.valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(() => this._changeDetectorRef.markForCheck()); + } + + // Update the aria-described by when the number of errors changes. + this._errorChildren.changes.pipe(startWith(null)).subscribe(() => { + this._syncDescribedByIds(); + this._changeDetectorRef.markForCheck(); + }); + } + + /** Throws an error if the form field's control is missing. */ + protected _validateControlChild(): void { + if (!this._control) { + throw Error('cnsl-form-field must contain a MatFormFieldControl.'); + } + } + + private _syncDescribedByIds(): void { + if (this._control) { + const ids: string[] = []; + + // TODO(wagnermaciel): Remove the type check when we find the root cause of this bug. + if (this._control.userAriaDescribedBy && + typeof this._control.userAriaDescribedBy === 'string') { + ids.push(...this._control.userAriaDescribedBy.split(' ')); + } + + if (this._errorChildren) { + ids.push(...this._errorChildren.map(error => error.id)); + } + + this._control.setDescribedByIds(ids); + } + } + + /** Determines whether a class from the NgControl should be forwarded to the host element. */ + _shouldForward(prop: keyof NgControl): boolean { + const ngControl = this._control ? this._control.ngControl : null; + return ngControl && ngControl[prop]; + } + + /** Determines whether to display hints or errors. */ + _getDisplayedMessages(): 'error' | 'hint' { + return (this._errorChildren && this._errorChildren.length > 0) ? 'error' : 'hint'; + } +} diff --git a/console/src/app/modules/form-field/form-field.module.ts b/console/src/app/modules/form-field/form-field.module.ts new file mode 100644 index 0000000000..0b447a7822 --- /dev/null +++ b/console/src/app/modules/form-field/form-field.module.ts @@ -0,0 +1,30 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatRippleModule } from '@angular/material/core'; +import { LabelModule } from 'src/app/modules/label/label.module'; + +import { LabelComponent } from '../label/label.component'; +import { CnslErrorDirective } from './error.directive'; +import { CnslFormFieldComponent } from './form-field.component'; +import { CnslHintDirective } from './hint.directive'; + +@NgModule({ + declarations: [ + CnslFormFieldComponent, + CnslErrorDirective, + CnslHintDirective, + ], + imports: [ + CommonModule, + MatRippleModule, + LabelModule, + ], + exports: [ + CnslFormFieldComponent, + LabelComponent, + CnslErrorDirective, + CnslHintDirective, + ], +}) +export class FormFieldModule { } + diff --git a/console/src/app/modules/form-field/hint.directive.ts b/console/src/app/modules/form-field/hint.directive.ts new file mode 100644 index 0000000000..0044f6dc28 --- /dev/null +++ b/console/src/app/modules/form-field/hint.directive.ts @@ -0,0 +1,33 @@ +import { Directive, InjectionToken, Input } from '@angular/core'; + +let nextUniqueId = 0; + +/** + * Injection token that can be used to reference instances of `MatHint`. It serves as + * alternative token to the actual `MatHint` class which could cause unnecessary + * retention of the class and its directive metadata. + * + * *Note*: This is not part of the public API as the MDC-based form-field will not + * need a lightweight token for `MatHint` and we want to reduce breaking changes. + */ +export const _CNSL_HINT = new InjectionToken('CnslHintDirective'); + +/** Hint text to be shown underneath the form field control. */ +@Directive({ + selector: 'cnsl-hint', + host: { + 'class': 'cnsl-hint', + '[class.cnsl-form-field-hint-end]': 'align === "end"', + '[attr.id]': 'id', + // Remove align attribute to prevent it from interfering with layout. + '[attr.align]': 'null', + }, + providers: [{ provide: _CNSL_HINT, useExisting: CnslHintDirective }], +}) +export class CnslHintDirective { + /** Whether to align the hint label at the start or end of the line. */ + @Input() align: 'start' | 'end' = 'start'; + + /** Unique ID for the hint. Used for the aria-describedby on the form field control. */ + @Input() id: string = `mat-hint-${nextUniqueId++}`; +} diff --git a/console/src/app/modules/idp-create/idp-create.component.html b/console/src/app/modules/idp-create/idp-create.component.html index d6f33a4b31..1eabb4c0f7 100644 --- a/console/src/app/modules/idp-create/idp-create.component.html +++ b/console/src/app/modules/idp-create/idp-create.component.html @@ -16,56 +16,57 @@
    - - {{ 'IDP.NAME' | translate }} - - - - {{ 'IDP.ISSUER' | translate }} - - + + {{ 'IDP.NAME' | translate }} + + + + {{ 'IDP.ISSUER' | translate }} + +

    Client Id / Client Secret

    - - {{ 'IDP.CLIENTID' | translate }} - - - - {{ 'IDP.CLIENTSECRET' | translate }} - - + + {{ 'IDP.CLIENTID' | translate }} + + + + {{ 'IDP.CLIENTSECRET' | translate }} + +
    - - {{ 'IDP.SCOPESLIST' | translate }} + + {{ 'IDP.SCOPESLIST' | translate }} {{scope}} cancel - + - +
    - - {{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }} + + {{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }} {{ 'IDP.MAPPINTFIELD.'+field | translate }} - - - {{ 'IDP.USERNAMEMAPPING' | translate }} + + + {{ 'IDP.USERNAMEMAPPING' | translate }} {{ 'IDP.MAPPINTFIELD.'+field | translate }} - +
    diff --git a/console/src/app/modules/idp-create/idp-create.module.ts b/console/src/app/modules/idp-create/idp-create.module.ts index 43028c9be6..bb176bcddc 100644 --- a/console/src/app/modules/idp-create/idp-create.module.ts +++ b/console/src/app/modules/idp-create/idp-create.module.ts @@ -3,13 +3,12 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatChipsModule } from '@angular/material/chips'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; import { IdpCreateRoutingModule } from './idp-create-routing.module'; import { IdpCreateComponent } from './idp-create.component'; @@ -21,8 +20,7 @@ import { IdpCreateComponent } from './idp-create.component'; CommonModule, FormsModule, ReactiveFormsModule, - MatInputModule, - MatFormFieldModule, + InputModule, MatButtonModule, MatSelectModule, MatIconModule, diff --git a/console/src/app/modules/idp/idp.component.html b/console/src/app/modules/idp/idp.component.html index 987cd1b9e0..1d580ec934 100644 --- a/console/src/app/modules/idp/idp.component.html +++ b/console/src/app/modules/idp/idp.component.html @@ -4,22 +4,22 @@
    - - {{ 'IDP.ID' | translate }} - - - - {{ 'IDP.NAME' | translate }} - - - - {{ 'IDP.STYLE' | translate }} + + {{ 'IDP.ID' | translate }} + + + + {{ 'IDP.NAME' | translate }} + + + + {{ 'IDP.STYLE' | translate }} {{ 'IDP.STYLEFIELD.'+field | translate }} - +
    @@ -38,51 +38,51 @@
    - - {{ 'IDP.ISSUER' | translate }} - - - - {{ 'IDP.CLIENTID' | translate }} - - + + {{ 'IDP.ISSUER' | translate }} + + + + {{ 'IDP.CLIENTID' | translate }} + + Update Client Secret - - {{ 'IDP.CLIENTSECRET' | translate }} - - - - {{ 'IDP.SCOPESLIST' | translate }} + + {{ 'IDP.CLIENTSECRET' | translate }} + + + + {{ 'IDP.SCOPESLIST' | translate }} {{scope}} cancel - - + - - {{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }} + + {{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }} {{ 'IDP.MAPPINGFIELD.'+field | translate }} - - - {{ 'IDP.USERNAMEMAPPING' | translate }} + + + {{ 'IDP.USERNAMEMAPPING' | translate }} {{ 'IDP.MAPPINGFIELD.'+field | translate }} - +
    diff --git a/console/src/app/modules/idp/idp.module.ts b/console/src/app/modules/idp/idp.module.ts index 92422d4247..8a1d73cf1d 100644 --- a/console/src/app/modules/idp/idp.module.ts +++ b/console/src/app/modules/idp/idp.module.ts @@ -4,16 +4,15 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; +import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { IdpRoutingModule } from './idp-routing.module'; import { IdpComponent } from './idp.component'; -import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module'; -import { MatSelectModule } from '@angular/material/select'; @NgModule({ declarations: [IdpComponent], @@ -22,8 +21,7 @@ import { MatSelectModule } from '@angular/material/select'; IdpRoutingModule, FormsModule, ReactiveFormsModule, - MatInputModule, - MatFormFieldModule, + InputModule, MatButtonModule, MatIconModule, MatTooltipModule, diff --git a/console/src/app/modules/input/error-options.ts b/console/src/app/modules/input/error-options.ts new file mode 100644 index 0000000000..9e8438f6d4 --- /dev/null +++ b/console/src/app/modules/input/error-options.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { FormControl, FormGroupDirective, NgForm } from '@angular/forms'; + + +/** Provider that defines how form controls behave with regards to displaying error messages. */ +@Injectable({ providedIn: 'root' }) +export class ErrorStateMatcher { + isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { + return !!(control && control.invalid && (control.touched || (form && form.submitted))); + } +} + +/** Error state matcher that matches when a control is invalid and dirty. */ +@Injectable() +export class ShowOnDirtyErrorStateMatcher implements ErrorStateMatcher { + isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { + return !!(control && control.invalid && (control.dirty || (form && form.submitted))); + } +} diff --git a/console/src/app/modules/input/input.directive.spec.ts b/console/src/app/modules/input/input.directive.spec.ts new file mode 100644 index 0000000000..463fed5431 --- /dev/null +++ b/console/src/app/modules/input/input.directive.spec.ts @@ -0,0 +1,8 @@ +import { InputDirective } from './input.directive'; + +describe('InputDirective', () => { + it('should create an instance', () => { + const directive = new InputDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/input/input.directive.ts b/console/src/app/modules/input/input.directive.ts new file mode 100644 index 0000000000..c9277b55c0 --- /dev/null +++ b/console/src/app/modules/input/input.directive.ts @@ -0,0 +1,459 @@ +import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion'; +import { getSupportedInputTypes, Platform } from '@angular/cdk/platform'; +import { AutofillMonitor } from '@angular/cdk/text-field'; +import { + AfterViewInit, + Directive, + DoCheck, + ElementRef, + HostListener, + Inject, + Input, + NgZone, + OnChanges, + OnDestroy, + Optional, + Self, +} from '@angular/core'; +import { FormGroupDirective, NgControl, NgForm } from '@angular/forms'; +import { CanUpdateErrorState, CanUpdateErrorStateCtor, ErrorStateMatcher, mixinErrorState } from '@angular/material/core'; +import { MAT_FORM_FIELD, MatFormField, MatFormFieldControl } from '@angular/material/form-field'; +import { getMatInputUnsupportedTypeError, MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input'; +import { Subject } from 'rxjs'; + + +// Invalid input type. Using one of these will throw an MatInputUnsupportedTypeError. +const MAT_INPUT_INVALID_TYPES = [ + 'button', + 'checkbox', + 'file', + 'hidden', + 'image', + 'radio', + 'range', + 'reset', + 'submit', +]; + +let nextUniqueId = 0; + +// Boilerplate for applying mixins to MatInput. +/** @docs-private */ +class MatInputBase { + constructor(public _defaultErrorStateMatcher: ErrorStateMatcher, + public _parentForm: NgForm, + public _parentFormGroup: FormGroupDirective, + /** @docs-private */ + public ngControl: NgControl) { } +} +const _MatInputMixinBase: CanUpdateErrorStateCtor & typeof MatInputBase = + mixinErrorState(MatInputBase); + +/** Directive that allows a native input to work inside a `MatFormField`. */ +@Directive({ + selector: `input[cnslInput], textarea[cnslInput], select[cnslNativeControl]`, + exportAs: 'cnslInput', + host: { + /** + * @breaking-change 8.0.0 remove .mat-form-field-autofill-control in favor of AutofillMonitor. + */ + // 'class': 'cnsl-input-element cnsl-form-field-autofill-control', + // '[class.mat-input-server]': '_isServer', + // Native input properties that are overwritten by Angular inputs need to be synced with + // the native input element. Otherwise property bindings for those don't work. + '[attr.id]': 'id', + // At the time of writing, we have a lot of customer tests that look up the input based on its + // placeholder. Since we sometimes omit the placeholder attribute from the DOM to prevent screen + // readers from reading it twice, we have to keep it somewhere in the DOM for the lookup. + '[attr.data-placeholder]': 'placeholder', + '[disabled]': 'disabled', + '[required]': 'required', + '[attr.readonly]': 'readonly && !_isNativeSelect || null', + '[attr.aria-invalid]': 'errorState', + '[attr.aria-required]': 'required.toString()', + }, + providers: [{ provide: MatFormFieldControl, useExisting: InputDirective }], +}) +export class InputDirective extends _MatInputMixinBase implements MatFormFieldControl, OnChanges, + OnDestroy, AfterViewInit, DoCheck, CanUpdateErrorState { + protected _uid: string = `cnsl-input-${nextUniqueId++}`; + protected _previousNativeValue: any; + private _inputValueAccessor: { value: any; }; + private _previousPlaceholder!: string | null; + + /** Whether the component is being rendered on the server. */ + readonly _isServer: boolean; + + /** Whether the component is a native html select. */ + readonly _isNativeSelect: boolean; + + /** Whether the component is a textarea. */ + readonly _isTextarea: boolean; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + focused: boolean = false; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + readonly stateChanges: Subject = new Subject(); + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + controlType: string = 'mat-input'; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + autofilled: boolean = false; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + @Input() + get disabled(): boolean { + if (this.ngControl && this.ngControl.disabled !== null) { + return this.ngControl.disabled; + } + return this._disabled; + } + set disabled(value: boolean) { + this._disabled = coerceBooleanProperty(value); + + // Browsers may not fire the blur event if the input is disabled too quickly. + // Reset from here to ensure that the element doesn't become stuck. + if (this.focused) { + this.focused = false; + this.stateChanges.next(); + } + } + protected _disabled: boolean = false; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + @Input() + get id(): string { return this._id; } + set id(value: string) { this._id = value || this._uid; } + protected _id!: string; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + @Input() placeholder!: string; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + @Input() + get required(): boolean { return this._required; } + set required(value: boolean) { this._required = coerceBooleanProperty(value); } + protected _required: boolean = false; + + /** Input type of the element. */ + @Input() + get type(): string { return this._type; } + set type(value: string) { + this._type = value || 'text'; + this._validateType(); + + // When using Angular inputs, developers are no longer able to set the properties on the native + // input element. To ensure that bindings for `type` work, we need to sync the setter + // with the native property. Textarea elements don't support the type property or attribute. + if (!this._isTextarea && getSupportedInputTypes().has(this._type)) { + (this._elementRef.nativeElement as HTMLInputElement).type = this._type; + } + } + protected _type: string = 'text'; + + /** An object used to control when error messages are shown. */ + @Input() errorStateMatcher!: ErrorStateMatcher; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + // tslint:disable-next-line:no-input-rename + @Input('aria-describedby') userAriaDescribedBy!: string; + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + @Input() + get value(): string { return this._inputValueAccessor.value; } + set value(value: string) { + if (value !== this.value) { + this._inputValueAccessor.value = value; + this.stateChanges.next(); + } + } + + /** Whether the element is readonly. */ + @Input() + get readonly(): boolean { return this._readonly; } + set readonly(value: boolean) { this._readonly = coerceBooleanProperty(value); } + private _readonly: boolean = false; + + protected _neverEmptyInputTypes: string[] = [ + 'date', + 'datetime', + 'datetime-local', + 'month', + 'time', + 'week', + ].filter(t => getSupportedInputTypes().has(t)); + + constructor( + protected _elementRef: ElementRef, + protected _platform: Platform, + /** @docs-private */ + @Optional() @Self() public ngControl: NgControl, + @Optional() _parentForm: NgForm, + @Optional() _parentFormGroup: FormGroupDirective, + _defaultErrorStateMatcher: ErrorStateMatcher, + @Optional() @Self() @Inject(MAT_INPUT_VALUE_ACCESSOR) inputValueAccessor: any, + private _autofillMonitor: AutofillMonitor, + ngZone: NgZone, + // TODO: Remove this once the legacy appearance has been removed. We only need + // to inject the form-field for determining whether the placeholder has been promoted. + @Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField) { + + super(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl); + + const element = this._elementRef.nativeElement; + const nodeName = element.nodeName.toLowerCase(); + + // If no input value accessor was explicitly specified, use the element as the input value + // accessor. + this._inputValueAccessor = inputValueAccessor || element; + + this._previousNativeValue = this.value; + + // Force setter to be called in case id was not specified. + this.id = this.id; + + // On some versions of iOS the caret gets stuck in the wrong place when holding down the delete + // key. In order to get around this we need to "jiggle" the caret loose. Since this bug only + // exists on iOS, we only bother to install the listener on iOS. + if (_platform.IOS) { + ngZone.runOutsideAngular(() => { + _elementRef.nativeElement.addEventListener('keyup', (event: Event) => { + const el: HTMLInputElement = event.target as HTMLInputElement; + if (!el.value && !el.selectionStart && !el.selectionEnd) { + // Note: Just setting `0, 0` doesn't fix the issue. Setting + // `1, 1` fixes it for the first time that you type text and + // then hold delete. Toggling to `1, 1` and then back to + // `0, 0` seems to completely fix it. + el.setSelectionRange(1, 1); + el.setSelectionRange(0, 0); + } + }); + }); + } + + this._isServer = !this._platform.isBrowser; + this._isNativeSelect = nodeName === 'select'; + this._isTextarea = nodeName === 'textarea'; + + if (this._isNativeSelect) { + this.controlType = (element as HTMLSelectElement).multiple ? 'mat-native-select-multiple' : + 'mat-native-select'; + } + } + + ngAfterViewInit(): void { + if (this._platform.isBrowser) { + this._autofillMonitor.monitor(this._elementRef.nativeElement).subscribe(event => { + this.autofilled = event.isAutofilled; + this.stateChanges.next(); + }); + } + } + + ngOnChanges(): void { + this.stateChanges.next(); + } + + ngOnDestroy(): void { + this.stateChanges.complete(); + + if (this._platform.isBrowser) { + this._autofillMonitor.stopMonitoring(this._elementRef.nativeElement); + } + } + + ngDoCheck(): void { + if (this.ngControl) { + // We need to re-evaluate this on every change detection cycle, because there are some + // error triggers that we can't subscribe to (e.g. parent form submissions). This means + // that whatever logic is in here has to be super lean or we risk destroying the performance. + this.updateErrorState(); + } + + // We need to dirty-check the native element's value, because there are some cases where + // we won't be notified when it changes (e.g. the consumer isn't using forms or they're + // updating the value using `emitEvent: false`). + this._dirtyCheckNativeValue(); + + // We need to dirty-check and set the placeholder attribute ourselves, because whether it's + // present or not depends on a query which is prone to "changed after checked" errors. + this._dirtyCheckPlaceholder(); + } + + /** Focuses the input. */ + focus(options?: FocusOptions): void { + this._elementRef.nativeElement.focus(options); + } + + // We have to use a `HostListener` here in order to support both Ivy and ViewEngine. + // In Ivy the `host` bindings will be merged when this class is extended, whereas in + // ViewEngine they're overwritten. + // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default. + /** Callback for the cases where the focused state of the input changes. */ + // tslint:disable:no-host-decorator-in-concrete + @HostListener('focus', ['true']) + @HostListener('blur', ['false']) + // tslint:enable:no-host-decorator-in-concrete + _focusChanged(isFocused: boolean): void { + if (isFocused !== this.focused && (!this.readonly || !isFocused)) { + this.focused = isFocused; + this.stateChanges.next(); + } + } + + // We have to use a `HostListener` here in order to support both Ivy and ViewEngine. + // In Ivy the `host` bindings will be merged when this class is extended, whereas in + // ViewEngine they're overwritten. + // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default. + // tslint:disable-next-line:no-host-decorator-in-concrete + @HostListener('input') + _onInput(): void { + // This is a noop function and is used to let Angular know whenever the value changes. + // Angular will run a new change detection each time the `input` event has been dispatched. + // It's necessary that Angular recognizes the value change, because when floatingLabel + // is set to false and Angular forms aren't used, the placeholder won't recognize the + // value changes and will not disappear. + // Listening to the input event wouldn't be necessary when the input is using the + // FormsModule or ReactiveFormsModule, because Angular forms also listens to input events. + } + + /** Does some manual dirty checking on the native input `placeholder` attribute. */ + private _dirtyCheckPlaceholder(): void { + // If we're hiding the native placeholder, it should also be cleared from the DOM, otherwise + // screen readers will read it out twice: once from the label and once from the attribute. + // TODO: can be removed once we get rid of the `legacy` style for the form field, because it's + // the only one that supports promoting the placeholder to a label. + const placeholder = this._formField?._hideControlPlaceholder?.() ? null : this.placeholder; + if (placeholder !== this._previousPlaceholder) { + const element = this._elementRef.nativeElement; + this._previousPlaceholder = placeholder; + placeholder ? + element.setAttribute('placeholder', placeholder) : element.removeAttribute('placeholder'); + } + } + + /** Does some manual dirty checking on the native input `value` property. */ + protected _dirtyCheckNativeValue(): void { + const newValue = this._elementRef.nativeElement.value; + + if (this._previousNativeValue !== newValue) { + this._previousNativeValue = newValue; + this.stateChanges.next(); + } + } + + /** Make sure the input is a supported type. */ + protected _validateType(): void { + if (MAT_INPUT_INVALID_TYPES.indexOf(this._type) > -1) { + throw getMatInputUnsupportedTypeError(this._type); + } + } + + /** Checks whether the input type is one of the types that are never empty. */ + protected _isNeverEmpty(): boolean { + return this._neverEmptyInputTypes.indexOf(this._type) > -1; + } + + /** Checks whether the input is invalid based on the native validation. */ + protected _isBadInput(): boolean { + // The `validity` property won't be present on platform-server. + const validity = (this._elementRef.nativeElement as HTMLInputElement).validity; + return validity && validity.badInput; + } + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + get empty(): boolean { + return !this._isNeverEmpty() && !this._elementRef.nativeElement.value && !this._isBadInput() && + !this.autofilled; + } + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + get shouldLabelFloat(): boolean { + if (this._isNativeSelect) { + // For a single-selection ``, the label *always* floats to avoid + // overlapping the label with the options. + const selectElement = this._elementRef.nativeElement as HTMLSelectElement; + const firstOption: HTMLOptionElement | undefined = selectElement.options[0]; + + // On most browsers the `selectedIndex` will always be 0, however on IE and Edge it'll be + // -1 if the `value` is set to something, that isn't in the list of options, at a later point. + return this.focused || selectElement.multiple || !this.empty || + !!(selectElement.selectedIndex > -1 && firstOption && firstOption.label); + } else { + return this.focused || !this.empty; + } + } + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + setDescribedByIds(ids: string[]): void { + if (ids.length) { + this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' ')); + } else { + this._elementRef.nativeElement.removeAttribute('aria-describedby'); + } + } + + /** + * Implemented as part of MatFormFieldControl. + * @docs-private + */ + onContainerClick(): void { + // Do not re-focus the input element if the element is already focused. Otherwise it can happen + // that someone clicks on a time input and the cursor resets to the "hours" field while the + // "minutes" field was actually clicked. See: https://github.com/angular/components/issues/12849 + if (!this.focused) { + this.focus(); + } + } + // tslint:disable + static ngAcceptInputType_disabled: BooleanInput; + static ngAcceptInputType_readonly: BooleanInput; + static ngAcceptInputType_required: BooleanInput; + + // Accept `any` to avoid conflicts with other directives on `` that may + // accept different types. + static ngAcceptInputType_value: any; + // tslint:enable +} diff --git a/console/src/app/modules/input/input.module.ts b/console/src/app/modules/input/input.module.ts new file mode 100644 index 0000000000..2bcc07f692 --- /dev/null +++ b/console/src/app/modules/input/input.module.ts @@ -0,0 +1,22 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatRippleModule } from '@angular/material/core'; + +import { FormFieldModule } from '../form-field/form-field.module'; +import { LabelModule } from '../label/label.module'; +import { ErrorStateMatcher } from './error-options'; +import { InputDirective } from './input.directive'; + + +@NgModule({ + declarations: [InputDirective], + imports: [ + LabelModule, + CommonModule, + FormFieldModule, + MatRippleModule, + ], + exports: [InputDirective, FormFieldModule], + providers: [ErrorStateMatcher], +}) +export class InputModule { } diff --git a/console/src/app/modules/label/label.component.html b/console/src/app/modules/label/label.component.html new file mode 100644 index 0000000000..cf4beda5c4 --- /dev/null +++ b/console/src/app/modules/label/label.component.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/console/src/app/modules/label/label.component.scss b/console/src/app/modules/label/label.component.scss new file mode 100644 index 0000000000..969f672ac4 --- /dev/null +++ b/console/src/app/modules/label/label.component.scss @@ -0,0 +1,16 @@ + +@import '~@angular/material/theming'; + +@mixin cnsl-label-theme($theme) { + $primary: map-get($theme, primary); + $primary-color: mat-color($primary, 500); + $is-dark-theme: map-get($theme, is-dark); + + .cnsl-label { + display: block; + font-size: 12px; + color: if($is-dark-theme, var(--grey), var(--grey)); + margin-bottom: 4px; + font-weight: 400; + } +} diff --git a/console/src/app/modules/label/label.component.spec.ts b/console/src/app/modules/label/label.component.spec.ts new file mode 100644 index 0000000000..285b088e0c --- /dev/null +++ b/console/src/app/modules/label/label.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { AvatarComponent } from './avatar.component'; + +describe('AvatarComponent', () => { + let component: AvatarComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AvatarComponent], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AvatarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/label/label.component.ts b/console/src/app/modules/label/label.component.ts new file mode 100644 index 0000000000..62902dc0d7 --- /dev/null +++ b/console/src/app/modules/label/label.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'cnsl-label', + templateUrl: './label.component.html', + styleUrls: ['./label.component.scss'], +}) +export class LabelComponent { + constructor() { } +} diff --git a/console/src/app/modules/label/label.module.ts b/console/src/app/modules/label/label.module.ts new file mode 100644 index 0000000000..d549326f07 --- /dev/null +++ b/console/src/app/modules/label/label.module.ts @@ -0,0 +1,20 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatRippleModule } from '@angular/material/core'; + +import { LabelComponent } from './label.component'; + + + +@NgModule({ + declarations: [LabelComponent], + imports: [ + CommonModule, + MatRippleModule, + ], + exports: [ + LabelComponent, + ], +}) +export class LabelModule { } + diff --git a/console/src/app/modules/members-table/members-table.component.html b/console/src/app/modules/members-table/members-table.component.html index cd85a13f20..ecd7ea9476 100644 --- a/console/src/app/modules/members-table/members-table.component.html +++ b/console/src/app/modules/members-table/members-table.component.html @@ -73,17 +73,16 @@ - {{ 'ROLESLABEL' | translate }} - - - {{ 'ROLESLABEL' | translate }} + {{ 'ROLESLABEL' | translate }} + + {{ role }} - + diff --git a/console/src/app/modules/members-table/members-table.component.scss b/console/src/app/modules/members-table/members-table.component.scss index 91ac8176b6..f78698ae9f 100644 --- a/console/src/app/modules/members-table/members-table.component.scss +++ b/console/src/app/modules/members-table/members-table.component.scss @@ -26,11 +26,6 @@ .action { width: 40px; } - - .selection { - width: 50px; - max-width: 50px; - } } tr { @@ -60,3 +55,7 @@ outline: none; cursor: pointer; } + +.role-row { + min-width: 200px; +} diff --git a/console/src/app/modules/members-table/members-table.module.ts b/console/src/app/modules/members-table/members-table.module.ts index 8af969284d..895c771723 100644 --- a/console/src/app/modules/members-table/members-table.module.ts +++ b/console/src/app/modules/members-table/members-table.module.ts @@ -3,7 +3,6 @@ import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatSelectModule } from '@angular/material/select'; @@ -12,6 +11,7 @@ import { MatTableModule } from '@angular/material/table'; import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; import { AvatarModule } from '../avatar/avatar.module'; import { RefreshTableModule } from '../refresh-table/refresh-table.module'; @@ -23,7 +23,7 @@ import { MembersTableComponent } from './members-table.component'; ], imports: [ CommonModule, - MatFormFieldModule, + InputModule, MatSelectModule, MatCheckboxModule, MatIconModule, diff --git a/console/src/app/modules/meta-layout/meta-layout.component.ts b/console/src/app/modules/meta-layout/meta-layout.component.ts index f96b778b75..922d0e7891 100644 --- a/console/src/app/modules/meta-layout/meta-layout.component.ts +++ b/console/src/app/modules/meta-layout/meta-layout.component.ts @@ -15,7 +15,7 @@ export class MetaLayoutComponent { } public hidden: boolean = false; public isSmallScreen$: Observable = this.breakpointObserver - .observe('(max-width: 899px)') + .observe('(max-width: 1000px)') .pipe(map(result => { return result.matches; })); diff --git a/console/src/app/modules/meta-layout/meta.scss b/console/src/app/modules/meta-layout/meta.scss deleted file mode 100644 index 2f4d9881b1..0000000000 --- a/console/src/app/modules/meta-layout/meta.scss +++ /dev/null @@ -1,44 +0,0 @@ -@import '~@angular/material/theming'; - -@mixin meta-theme($theme) { - /* stylelint-disable */ - $primary: map-get($theme, primary); - $primary-color: mat-color($primary, 500); - $primary-dark: mat-color($primary, A800); - /* stylelint-enable */ - - .meta-wrapper { - .meta { - position: relative; - flex: 1 0 300px; - - &::after { - border-left: 2px solid $primary-color; - -webkit-border-image: - -webkit-gradient( - linear, - left top, - left bottom, - from($primary-color), - to(rgb(0, 0, 0, .5)), - color-stop( - 01, - $primary-dark - ) - ) 50 21; - border-image: - -webkit-gradient( - linear, - left top, - left bottom, - from($primary-color), - to(rgb(0, 0, 0, .5)), - color-stop( - 01, - $primary-dark - ) - ) 50 21; - } - } - } -} diff --git a/console/src/app/modules/policies/label-policy/label-policy.component.html b/console/src/app/modules/policies/label-policy/label-policy.component.html index 5e5a9bb257..25da1dc81d 100644 --- a/console/src/app/modules/policies/label-policy/label-policy.component.html +++ b/console/src/app/modules/policies/label-policy/label-policy.component.html @@ -2,15 +2,15 @@ [description]="'POLICY.LABEL.DESCRIPTION' | translate">
    - - {{'POLICY.LABEL.PRIMARYCOLOR' | translate}} - - + + {{'POLICY.LABEL.PRIMARYCOLOR' | translate}} + + - - {{'POLICY.LABEL.SECONDARYCOLOR' | translate}} - - + + {{'POLICY.LABEL.SECONDARYCOLOR' | translate}} + +
    diff --git a/console/src/app/modules/policies/label-policy/label-policy.module.ts b/console/src/app/modules/policies/label-policy/label-policy.module.ts index 173b7ff6fe..d05ba9acf7 100644 --- a/console/src/app/modules/policies/label-policy/label-policy.module.ts +++ b/console/src/app/modules/policies/label-policy/label-policy.module.ts @@ -2,14 +2,13 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { LabelPolicyRoutingModule } from './label-policy-routing.module'; import { LabelPolicyComponent } from './label-policy.component'; @@ -20,8 +19,7 @@ import { LabelPolicyComponent } from './label-policy.component'; LabelPolicyRoutingModule, CommonModule, FormsModule, - MatInputModule, - MatFormFieldModule, + InputModule, MatButtonModule, MatSlideToggleModule, MatIconModule, diff --git a/console/src/app/modules/policies/login-policy/add-idp-dialog/add-idp-dialog.component.html b/console/src/app/modules/policies/login-policy/add-idp-dialog/add-idp-dialog.component.html index 0e500ef85b..0872b9f34a 100644 --- a/console/src/app/modules/policies/login-policy/add-idp-dialog/add-idp-dialog.component.html +++ b/console/src/app/modules/policies/login-policy/add-idp-dialog/add-idp-dialog.component.html @@ -4,25 +4,25 @@

    {{'LOGINPOLICY.ADDIDP.DESCRIPTION' | translate}}

    - - {{ 'IDP.TYPE' | translate }} + + {{ 'IDP.TYPE' | translate }} {{ 'IDP.TYPES.'+type | translate}} - +

    {{'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate}}

    - - {{ 'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate }} + + {{ 'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate }} {{ idp.name }} - +
    - +
    + + + + + + {{role.key}} + + + + + - - - {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} - - - {{role}} - - - - - + + + + + + {{role}} + + + + + +
    @@ -144,6 +149,10 @@ +
    + + {{'GRANTS.EMPTY' | translate}} +
    @@ -152,7 +161,7 @@ \ No newline at end of file diff --git a/console/src/app/modules/user-grants/user-grants.component.scss b/console/src/app/modules/user-grants/user-grants.component.scss index 98feec09a7..eefa886195 100644 --- a/console/src/app/modules/user-grants/user-grants.component.scss +++ b/console/src/app/modules/user-grants/user-grants.component.scss @@ -23,21 +23,21 @@ th { .search-button { - display: none; + visibility: hidden; + width: 30px; + + .icon { + font-size: 1.2rem; + } } &:hover, &.search-active { .search-button { - display: inline-block; + visibility: visible; } } } - - .selection { - width: 50px; - max-width: 50px; - } } } @@ -68,7 +68,9 @@ button { margin: .5rem 0; + display: block; max-width: 120px; + box-sizing: border-box; i { font-size: 1.2rem; @@ -77,10 +79,35 @@ } } +.row-form { + display: flex; + align-items: center; + + .form-field { + flex: 1; + } +} + .fill-space { flex: 1; } +.role-data { + min-width: 180px; +} + +.date-block { + margin: .5rem 0; + display: block; + min-width: 120px; + + .date-sub { + font-size: 13px; + color: var(--grey); + display: block; + } +} + .filtername { margin-right: 1rem; } diff --git a/console/src/app/modules/user-grants/user-grants.component.ts b/console/src/app/modules/user-grants/user-grants.component.ts index 0d29873727..9263d85fc6 100644 --- a/console/src/app/modules/user-grants/user-grants.component.ts +++ b/console/src/app/modules/user-grants/user-grants.component.ts @@ -67,7 +67,7 @@ export class UserGrantsComponent implements OnInit, AfterViewInit { @Input() public displayedColumns: string[] = ['select', 'user', 'org', - 'projectId', 'creationDate', 'changeDate', 'roleNamesList']; + 'projectId', 'dates', 'roleNamesList']; public ngOnInit(): void { this.dataSource = new UserGrantsDataSource(this.userService); diff --git a/console/src/app/modules/user-grants/user-grants.module.ts b/console/src/app/modules/user-grants/user-grants.module.ts index 1370036ce8..332fb0fa48 100644 --- a/console/src/app/modules/user-grants/user-grants.module.ts +++ b/console/src/app/modules/user-grants/user-grants.module.ts @@ -3,9 +3,7 @@ import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; @@ -18,12 +16,12 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module'; import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module'; +import { InputModule } from '../../modules/input/input.module'; import { AvatarModule } from '../avatar/avatar.module'; import { RefreshTableModule } from '../refresh-table/refresh-table.module'; import { UserGrantsComponent } from './user-grants.component'; - @NgModule({ declarations: [UserGrantsComponent], imports: [ @@ -40,13 +38,12 @@ import { UserGrantsComponent } from './user-grants.component'; MatCheckboxModule, MatTooltipModule, MatSelectModule, - MatInputModule, - MatFormFieldModule, TranslateModule, HasRolePipeModule, TimestampToDatePipeModule, RefreshTableModule, LocalizedDatePipeModule, + InputModule, ], exports: [ UserGrantsComponent, diff --git a/console/src/app/pages/grants/grants.component.html b/console/src/app/pages/grants/grants.component.html index 91267c1377..99fd9ca528 100644 --- a/console/src/app/pages/grants/grants.component.html +++ b/console/src/app/pages/grants/grants.component.html @@ -1,9 +1,9 @@
    -

    {{ 'GRANTS.TITLE' | translate }}

    +

    {{ 'GRANTS.TITLE' | translate }}

    {{'GRANTS.DESC' | translate }}

    - + [disableDelete]="((['user.grant.delete$'] | hasRole) | async) == false" + [refreshOnPreviousRoutes]="['/grant-create']">
    \ No newline at end of file diff --git a/console/src/app/pages/grants/grants.component.scss b/console/src/app/pages/grants/grants.component.scss index 204270a91a..9fb7ff0c3f 100644 --- a/console/src/app/pages/grants/grants.component.scss +++ b/console/src/app/pages/grants/grants.component.scss @@ -1,3 +1,7 @@ +h1 { + margin-top: 0; +} + .desc { color: var(--grey); margin-bottom: 2rem; diff --git a/console/src/app/pages/iam/failed-events/failed-events.component.scss b/console/src/app/pages/iam/failed-events/failed-events.component.scss index fed66762df..b776dcba8c 100644 --- a/console/src/app/pages/iam/failed-events/failed-events.component.scss +++ b/console/src/app/pages/iam/failed-events/failed-events.component.scss @@ -19,11 +19,6 @@ padding-right: 0; } } - - .selection { - width: 50px; - max-width: 50px; - } } } diff --git a/console/src/app/pages/iam/iam-members/iam-members.component.ts b/console/src/app/pages/iam/iam-members/iam-members.component.ts index 4ce1a5a511..731a83dd87 100644 --- a/console/src/app/pages/iam/iam-members/iam-members.component.ts +++ b/console/src/app/pages/iam/iam-members/iam-members.component.ts @@ -59,7 +59,6 @@ export class IamMembersComponent { } public removeMemberSelection(): void { - console.log(this.selection); Promise.all(this.selection.map(member => { return this.adminService.RemoveIamMember(member.userId).then(() => { this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true); diff --git a/console/src/app/pages/iam/iam-views/iam-views.component.scss b/console/src/app/pages/iam/iam-views/iam-views.component.scss index fed66762df..b776dcba8c 100644 --- a/console/src/app/pages/iam/iam-views/iam-views.component.scss +++ b/console/src/app/pages/iam/iam-views/iam-views.component.scss @@ -19,11 +19,6 @@ padding-right: 0; } } - - .selection { - width: 50px; - max-width: 50px; - } } } diff --git a/console/src/app/pages/iam/iam.module.ts b/console/src/app/pages/iam/iam.module.ts index cc644d34a3..da36250a9e 100644 --- a/console/src/app/pages/iam/iam.module.ts +++ b/console/src/app/pages/iam/iam.module.ts @@ -6,19 +6,18 @@ import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; -import { MatTabsModule } from '@angular/material/tabs'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; @@ -46,10 +45,9 @@ import { IamComponent } from './iam.component'; MatCheckboxModule, MetaLayoutModule, MatIconModule, - MatTabsModule, MatTableModule, MatPaginatorModule, - MatFormFieldModule, + InputModule, MatSortModule, MatTooltipModule, ReactiveFormsModule, diff --git a/console/src/app/pages/orgs/org-create/org-create.component.html b/console/src/app/pages/orgs/org-create/org-create.component.html index 9802a7b704..5da50bd098 100644 --- a/console/src/app/pages/orgs/org-create/org-create.component.html +++ b/console/src/app/pages/orgs/org-create/org-create.component.html @@ -12,17 +12,18 @@ -

    {{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}

    +

    {{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}

    +
    - - {{ 'ORG_DETAIL.DETAIL.NAME' | translate }} - - - - {{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }} - - + + {{ 'ORG_DETAIL.DETAIL.NAME' | translate }} + + + + {{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }} + +
    @@ -42,67 +43,67 @@

    {{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}

    - - {{ 'USER.PROFILE.USERNAME' | translate }} - - + + {{ 'USER.PROFILE.USERNAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PROFILE.EMAIL' | translate }} - - + + + + {{ 'USER.PROFILE.EMAIL' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PROFILE.FIRSTNAME' | translate }} - - + + + + {{ 'USER.PROFILE.FIRSTNAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PROFILE.LASTNAME' | translate }} - - + + + + {{ 'USER.PROFILE.LASTNAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PROFILE.NICKNAME' | translate }} - - + + + + {{ 'USER.PROFILE.NICKNAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - + +

    {{ 'USER.CREATE.GENDERLANGSECTION' | translate }}

    - - {{ 'USER.PROFILE.GENDER' | translate }} + + {{ 'USER.PROFILE.GENDER' | translate }} {{ 'GENDERS.'+gender | translate }} - + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }} + + + + {{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }} {{ 'LANGUAGES.'+language | translate }} - {{ 'USER.VALIDATION.REQUIRED' | translate }} - + - + @@ -116,28 +117,28 @@ - - {{ 'USER.PASSWORD.NEW' | translate }} - + {{ 'USER.PASSWORD.NEW' | translate }} + - + {{ 'USER.VALIDATION.REQUIRED' | translate }} - + - - - {{ 'USER.PASSWORD.CONFIRM' | translate }} - + + {{ 'USER.PASSWORD.CONFIRM' | translate }} + - + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - + + {{ 'USER.PASSWORD.NOTEQUAL' | translate }} - - + +
    @@ -157,13 +158,14 @@
    -

    {{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}

    +

    {{'ORG.PAGES.ORGDETAIL_TITLE_WITHOUT_DOMAIN' | translate}}

    +
    - - {{ 'ORG_DETAIL.DETAIL.NAME' | translate }} - - + + {{ 'ORG_DETAIL.DETAIL.NAME' | translate }} + +
    diff --git a/console/src/app/pages/orgs/org-create/org-create.component.ts b/console/src/app/pages/orgs/org-create/org-create.component.ts index d487201638..5261a80d69 100644 --- a/console/src/app/pages/orgs/org-create/org-create.component.ts +++ b/console/src/app/pages/orgs/org-create/org-create.component.ts @@ -107,8 +107,15 @@ export class OrgCreateComponent { this.adminService .SetUpOrg(createOrgRequest, humanRequest) - .then((data: OrgSetUpResponse) => { - this.router.navigate(['orgs', data.toObject().org?.id]); + .then((org: OrgSetUpResponse) => { + this.router.navigate(['/org/overview']); + // const orgResp = org.getOrg(); + // if (orgResp) { + // this.authService.setActiveOrg(orgResp.toObject()); + // this.router.navigate(['/org']); + // } else { + // this.router.navigate(['/org', 'overview']); + // } }) .catch(error => { this.toast.showError(error); @@ -193,7 +200,12 @@ export class OrgCreateComponent { public createOrgForSelf(): void { if (this.name && this.name.value) { this.mgmtService.CreateOrg(this.name.value).then((org) => { - this.router.navigate(['orgs', org.toObject().id]); + this.router.navigate(['/org/overview']); + // const newOrg = org.toObject(); + // setTimeout(() => { + // this.authService.setActiveOrg(newOrg); + // this.router.navigate(['/org']); + // }, 1000); }).catch(error => { this.toast.showError(error); }); diff --git a/console/src/app/pages/orgs/org-create/org-create.module.ts b/console/src/app/pages/orgs/org-create/org-create.module.ts index 27fbb008c3..f86e6a412f 100644 --- a/console/src/app/pages/orgs/org-create/org-create.module.ts +++ b/console/src/app/pages/orgs/org-create/org-create.module.ts @@ -3,13 +3,12 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module'; import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module'; @@ -23,8 +22,7 @@ import { OrgCreateComponent } from './org-create.component'; CommonModule, FormsModule, ReactiveFormsModule, - MatInputModule, - MatFormFieldModule, + InputModule, MatButtonModule, MatIconModule, MatSelectModule, diff --git a/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html b/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html index 7f00acc917..b793c9aebb 100644 --- a/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html +++ b/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html @@ -2,10 +2,10 @@

    {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}

    - - Domain - - + + Domain + +
    diff --git a/console/src/app/pages/orgs/org-detail/org-detail.component.scss b/console/src/app/pages/orgs/org-detail/org-detail.component.scss index b14d23b209..24cc3880fc 100644 --- a/console/src/app/pages/orgs/org-detail/org-detail.component.scss +++ b/console/src/app/pages/orgs/org-detail/org-detail.component.scss @@ -10,7 +10,6 @@ .domain { display: flex; align-items: center; - padding: .5rem 0; flex-wrap: wrap; .title { @@ -55,6 +54,7 @@ &:hover { .rem-button { visibility: visible; + transition: none; } } } diff --git a/console/src/app/pages/orgs/org-list/org-list.component.html b/console/src/app/pages/orgs/org-list/org-list.component.html index 1d67ebddf1..6c1432639b 100644 --- a/console/src/app/pages/orgs/org-list/org-list.component.html +++ b/console/src/app/pages/orgs/org-list/org-list.component.html @@ -5,11 +5,11 @@ - - {{'ORG.PAGES.FILTER' | translate}} - + {{'ORG.PAGES.FILTER' | translate}} + - + diff --git a/console/src/app/pages/orgs/org-list/org-list.component.scss b/console/src/app/pages/orgs/org-list/org-list.component.scss index e3d50b0123..f80d45b669 100644 --- a/console/src/app/pages/orgs/org-list/org-list.component.scss +++ b/console/src/app/pages/orgs/org-list/org-list.component.scss @@ -23,11 +23,6 @@ h1 { padding-right: 0; } } - - .selection { - width: 50px; - max-width: 50px; - } } .pointer { diff --git a/console/src/app/pages/orgs/org-list/org-list.component.ts b/console/src/app/pages/orgs/org-list/org-list.component.ts index a5db909cc1..a614451773 100644 --- a/console/src/app/pages/orgs/org-list/org-list.component.ts +++ b/console/src/app/pages/orgs/org-list/org-list.component.ts @@ -1,5 +1,4 @@ -import { AfterViewInit, Component, ViewChild } from '@angular/core'; -import { MatInput } from '@angular/material/input'; +import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; @@ -23,7 +22,7 @@ export class OrgListComponent implements AfterViewInit { @ViewChild(MatPaginator) public paginator!: MatPaginator; @ViewChild(MatSort) sort!: MatSort; - @ViewChild('input') public filter!: MatInput; + @ViewChild('input') public filter!: Input; public dataSource!: MatTableDataSource; public displayedColumns: string[] = ['select', 'id', 'name']; diff --git a/console/src/app/pages/orgs/org-list/org-list.module.ts b/console/src/app/pages/orgs/org-list/org-list.module.ts index b7fa9f12ba..d3eb9806f5 100644 --- a/console/src/app/pages/orgs/org-list/org-list.module.ts +++ b/console/src/app/pages/orgs/org-list/org-list.module.ts @@ -2,15 +2,14 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatRadioModule } from '@angular/material/radio'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module'; import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module'; @@ -34,8 +33,7 @@ import { OrgListComponent } from './org-list.component'; MatButtonModule, MatTooltipModule, MatRadioModule, - MatFormFieldModule, - MatInputModule, + InputModule, FormsModule, ], }) diff --git a/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.component.html b/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.component.html index 707a003d55..8cfb69ef25 100644 --- a/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.component.html +++ b/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.component.html @@ -1,6 +1,6 @@ - - Role Name + + Role Name @@ -10,5 +10,5 @@ {{ role }} - + \ No newline at end of file diff --git a/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.module.ts b/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.module.ts index 9cd9f70cdc..a2257a988e 100644 --- a/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.module.ts +++ b/console/src/app/pages/orgs/org-member-roles-autocomplete/org-member-roles-autocomplete.module.ts @@ -2,12 +2,11 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; import { OrgMemberRolesAutocompleteComponent } from './org-member-roles-autocomplete.component'; @@ -17,9 +16,8 @@ import { OrgMemberRolesAutocompleteComponent } from './org-member-roles-autocomp CommonModule, MatButtonModule, MatSelectModule, - MatFormFieldModule, + InputModule, MatIconModule, - MatInputModule, ReactiveFormsModule, MatProgressSpinnerModule, FormsModule, diff --git a/console/src/app/pages/orgs/orgs.module.ts b/console/src/app/pages/orgs/orgs.module.ts index 22a6b25b39..5bb283c3d1 100644 --- a/console/src/app/pages/orgs/orgs.module.ts +++ b/console/src/app/pages/orgs/orgs.module.ts @@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatTabsModule } from '@angular/material/tabs'; @@ -17,6 +15,7 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module'; import { CardModule } from 'src/app/modules/card/card.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module'; import { SharedModule } from 'src/app/modules/shared/shared.module'; @@ -37,8 +36,7 @@ import { OrgsRoutingModule } from './orgs-routing.module'; OrgsRoutingModule, FormsModule, HasRoleModule, - MatFormFieldModule, - MatInputModule, + InputModule, MatButtonModule, MatDialogModule, CardModule, diff --git a/console/src/app/pages/projects/apps/app-create/app-create.component.html b/console/src/app/pages/projects/apps/app-create/app-create.component.html index 0f7b0b955f..c43900be68 100644 --- a/console/src/app/pages/projects/apps/app-create/app-create.component.html +++ b/console/src/app/pages/projects/apps/app-create/app-create.component.html @@ -21,18 +21,18 @@ {{'APP.OIDC.NAMEANDTYPESECTION' | translate}}

    {{'APP.OIDC.TITLEFIRST' | translate}}

    - - {{ 'APP.NAME' | translate }} - - {{'PROJECT.APP.NAMEREQUIRED' | translate}} - + + {{ 'APP.NAME' | translate }} + + {{'PROJECT.APP.NAMEREQUIRED' | translate}} +

    {{'APP.OIDC.TYPETITLE' | translate}}

    -
    {{'APP.OIDC.APPTYPE'+type.key | translate}}
    +
    {{('APP.OIDC.APPTYPE'+type.key.toString()) | translate}}
    @@ -89,19 +89,24 @@

    {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

    - - {{ 'APP.OIDC.REDIRECT' | translate }} - - - {{uri}} cancel - - - - +
    + + {{ 'APP.OIDC.REDIRECT' | translate }} + + + + + + + {{uri}} cancel + + +

    {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    {{'APP.OIDC.POSTREDIRECTTITLE' | translate}}

    @@ -112,20 +117,25 @@ *ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT"> {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

    - - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} - - - {{uri}} cancel - - - - +
    + + {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} + + + + + + + {{uri}} cancel + + +

    {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    @@ -223,71 +233,72 @@
    - - {{ 'APP.NAME' | translate }} - - + + {{ 'APP.NAME' | translate }} + + - - {{ 'APP.OIDC.APPTYPE' | translate }} + + {{ 'APP.OIDC.APPTYPE' | translate }} {{ 'APP.OIDC.APPTYPE'+type | translate }} - + - - {{ 'APP.OIDC.GRANT' | translate }} + + {{ 'APP.OIDC.GRANT' | translate }} {{ ('APP.OIDC.GRANT' + grant.type) | translate }} - + - - {{ 'APP.OIDC.RESPONSE' | translate }} + + {{ 'APP.OIDC.RESPONSE' | translate }} {{ 'APP.OIDC.RESPONSE'+type.type | translate }} - + - - {{ 'APP.OIDC.AUTHMETHOD' | translate }} + + {{ 'APP.OIDC.AUTHMETHOD' | translate }} {{ 'APP.OIDC.AUTHMETHOD'+type.type | translate }} - + - - {{ 'APP.OIDC.REDIRECT' | translate }} + + {{ 'APP.OIDC.REDIRECT' | translate }} {{uri}} cancel - + - + - - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} + + {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} {{uri}} cancel - - +
    diff --git a/console/src/app/pages/projects/apps/app-create/app-create.component.scss b/console/src/app/pages/projects/apps/app-create/app-create.component.scss index bff6716fc7..d577037af1 100644 --- a/console/src/app/pages/projects/apps/app-create/app-create.component.scss +++ b/console/src/app/pages/projects/apps/app-create/app-create.component.scss @@ -56,8 +56,9 @@ p.desc { margin: 0 -1.5rem; .step-title { - font-size: 1.2rem; - color: var(--grey); + font-size: 1rem; + text-transform: uppercase; + letter-spacing: .05em; } .step-description { @@ -65,12 +66,31 @@ p.desc { color: var(--grey); } + .chip-form { + width: 100%; + display: flex; + align-items: center; + + .formfield { + flex: 1; + } + + button { + margin-top: 1rem; + } + } + .error { font-size: 13px; color: #f44336; margin-top: 0; } + .chip { + border-radius: 4px; + height: 40px; + } + .chip[color='white'] { background-color: #fafafa; } diff --git a/console/src/app/pages/projects/apps/app-create/app-create.component.ts b/console/src/app/pages/projects/apps/app-create/app-create.component.ts index ce2e2edb59..25ae4bb42d 100644 --- a/console/src/app/pages/projects/apps/app-create/app-create.component.ts +++ b/console/src/app/pages/projects/apps/app-create/app-create.component.ts @@ -1,8 +1,7 @@ import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes'; import { Location } from '@angular/common'; import { Component, OnDestroy, OnInit } from '@angular/core'; -import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; -import { MatChipInputEvent } from '@angular/material/chips'; +import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { Subscription } from 'rxjs'; @@ -216,9 +215,8 @@ export class AppCreateComponent implements OnInit, OnDestroy { } } - public addUri(event: MatChipInputEvent, target: string): void { - const input = event.input; - const value = event.value.trim(); + public addUri(input: any, target: string): void { + const value = input.value.trim(); if (value !== '') { if (target === 'REDIRECT' && this.redirectControl.valid) { diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html index 5570add6e3..58c711675f 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html @@ -1,182 +1,207 @@ -
    -
    - - arrow_back - -

    {{ 'APP.PAGES.TITLE' | translate }} {{app?.name}}

    + +
    +
    + + arrow_back + +

    {{ 'APP.PAGES.TITLE' | translate }} {{app?.name}}

    -

    {{ 'APP.PAGES.DESCRIPTION' | translate }}

    -

    {{'PROJECT.PAGES.ZITADELPROJECT' | translate}}

    -
    - - {{errorMessage}} - - - -
    - - - {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}} - - - {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}} - - - - - {{ 'APP.NAME' | translate }} - - - -

    Discovery Endpoint: {{docs.discoveryEndpoint}}

    -

    Issuer: {{docs.issuer}}

    -
    -
    - -
    - -
    - - -
    - +

    {{ 'APP.PAGES.DESCRIPTION' | translate }}

    +

    {{'PROJECT.PAGES.ZITADELPROJECT' | translate}}

    -
    -

    - {{problem.localizedMessage}} -

    -
    -
    -
    - - {{ 'APP.OIDC.CLIENTID' | translate }} - - + {{errorMessage}} - - {{ 'APP.OIDC.RESPONSE' | translate }} - - - {{ 'APP.OIDC.RESPONSE'+type | translate }} - - - + + +
    + + + {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}} + + + {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}} + + - - {{ 'APP.OIDC.GRANT' | translate }} - - - {{ 'APP.OIDC.GRANT'+grant | translate }} - - - + + {{ 'APP.NAME' | translate }} + + - - {{ 'APP.OIDC.APPTYPE' | translate }} - - - {{ 'APP.OIDC.APPTYPE'+type | translate }} - - - +

    Discovery Endpoint: {{docs.discoveryEndpoint}} +

    +

    Issuer: {{docs.issuer}}

    +
    +
    + +
    + +
    - - {{ 'APP.OIDC.AUTHMETHOD' | translate }} - - - {{ 'APP.OIDC.AUTHMETHOD'+type | translate }} - - - + +
    + +
    -
    +
    +

    + {{problem.localizedMessage}} +

    +
    +
    +
    + + {{ 'APP.OIDC.CLIENTID' | translate }} + + -

    {{'APP.OIDC.TOKENSECTIONTITLE' | translate}}

    + + {{ 'APP.OIDC.RESPONSE' | translate }} + + + {{ 'APP.OIDC.RESPONSE'+type | translate }} + + + - - {{ 'APP.OIDC.TOKENTYPE' | translate }} - - - {{ 'APP.OIDC.TOKENTYPE'+type | translate }} - - - + + {{ 'APP.OIDC.GRANT' | translate }} + + + {{ 'APP.OIDC.GRANT'+grant | translate }} + + + - - {{'APP.OIDC.ACCESSTOKENROLEASSERTION' | translate}} -

    {{'APP.OIDC.ACCESSTOKENROLEASSERTION_DESCRIPTION' | translate}}

    - - {{'APP.OIDC.IDTOKENROLEASSERTION' | translate}} -

    {{'APP.OIDC.IDTOKENROLEASSERTION_DESCRIPTION' | translate}}

    + + {{ 'APP.OIDC.APPTYPE' | translate }} + + + {{ 'APP.OIDC.APPTYPE'+type | translate }} + + + -
    + + {{ 'APP.OIDC.AUTHMETHOD' | translate }} + + + {{ 'APP.OIDC.AUTHMETHOD'+type | translate }} + + + -

    {{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}

    +
    - - {{ 'APP.OIDC.DEVMODE' | translate }} - +

    {{'APP.OIDC.TOKENSECTIONTITLE' | translate}}

    -

    {{'APP.OIDC.DEVMODEDESC' | translate}}

    -

    - {{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}}

    -

    - {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

    + + {{ 'APP.OIDC.TOKENTYPE' | translate }} + + + {{ 'APP.OIDC.TOKENTYPE'+type | translate }} + + + - - {{ 'APP.OIDC.REDIRECT' | translate }} - + + {{'APP.OIDC.ACCESSTOKENROLEASSERTION' | translate}} +

    {{'APP.OIDC.ACCESSTOKENROLEASSERTION_DESCRIPTION' | translate}}

    + + {{'APP.OIDC.IDTOKENROLEASSERTION' | translate}} +

    {{'APP.OIDC.IDTOKENROLEASSERTION_DESCRIPTION' | translate}}

    + +
    + +

    {{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}

    + + + {{ 'APP.OIDC.DEVMODE' | translate }} + + +

    {{'APP.OIDC.DEVMODEDESC' | translate}}

    +

    + {{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}}

    +

    + {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

    + + + + {{ 'APP.OIDC.REDIRECT' | translate }} + + + + + + {{redirect}} cancel - -
    -

    - {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    +

    + {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    - - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} - +
    + + {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} + + + + + + [matTooltip]="!redirect?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''" + [color]="!redirect?.startsWith('https://') ? 'warn': 'green'"> {{redirect}} cancel - -
    -

    - {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    +

    + {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

    +
    +
    + + +
    + + +
    +
    + +
    +
    +
    + {{'PROJECT.STATE.TITLE' | translate}}: + {{'APP.PAGES.DETAIL.STATE.'+app.state | translate}}
    -
    +
    - -
    - - - -
    \ No newline at end of file + +
    +
    \ No newline at end of file diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss b/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss index 3cf6017101..901685e035 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss @@ -60,6 +60,24 @@ } } + .chiplist { + margin-bottom: 1rem; + } + + .chip-form { + width: 100%; + display: flex; + align-items: center; + + .formfield { + flex: 1; + } + + button { + margin-top: 1rem; + } + } + .section-title { margin-bottom: 1.5rem; } @@ -103,7 +121,7 @@ .toggle { outline: none; align-self: flex-start; - margin-bottom: 1rem; + margin-top: 1rem; margin-right: 1rem; border-radius: .5rem; @@ -127,6 +145,11 @@ } } +.chip { + border-radius: 4px; + height: 40px; +} + .chip[color='green'] { background-color: #56a392 !important; } @@ -137,3 +160,54 @@ height: 1px; background-color: var(--grey); } + +.side { + .details { + margin-bottom: 1rem; + border-bottom: 1px solid #81868a40; + padding-bottom: 1rem; + + .row { + display: flex; + margin-bottom: .5rem; + align-items: center; + + .first { + flex: 1; + font-size: 13px; + margin-right: .5rem; + } + + .fill-space { + flex: 1; + } + + .state { + border-radius: 50vw; + padding: 2px .5rem; + letter-spacing: .05em; + font-size: 13px; + background-color: #8795a120; + + &.active { + background-color: #85d996; + color: black; + } + + &.inactive { + background-color: #ff8981; + color: black; + } + } + } + } + + .mat-tab-label { + min-width: 100px !important; + } + + .flex-col { + display: flex; + flex-direction: column; + } +} diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts index 56537a1b2f..719a4e4c8c 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts @@ -3,12 +3,12 @@ import { Location } from '@angular/common'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { MatButtonToggleChange } from '@angular/material/button-toggle'; -import { MatChipInputEvent } from '@angular/material/chips'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; import { take } from 'rxjs/operators'; +import { ChangeType } from 'src/app/modules/changes/changes.component'; import { Application, AppState, @@ -91,7 +91,7 @@ export class AppDetailComponent implements OnInit, OnDestroy { public redirectControl: FormControl = new FormControl({ value: '', disabled: true }); public postRedirectControl: FormControl = new FormControl({ value: '', disabled: true }); - + public ChangeType: any = ChangeType; constructor( public translate: TranslateService, private route: ActivatedRoute, @@ -180,19 +180,17 @@ export class AppDetailComponent implements OnInit, OnDestroy { } } - public add(event: MatChipInputEvent, target: RedirectType): void { + public add(input: any, target: RedirectType): void { if (target === RedirectType.POSTREDIRECT && this.postRedirectControl.valid) { - const input = event.input; - if (event.value !== '' && event.value !== ' ' && event.value !== '/') { - this.postLogoutRedirectUrisList.push(event.value); + if (input.value !== '' && input.value !== ' ' && input.value !== '/') { + this.postLogoutRedirectUrisList.push(input.value); } if (input) { input.value = ''; } } else if (target === RedirectType.REDIRECT && this.redirectControl.valid) { - const input = event.input; - if (event.value !== '' && event.value !== ' ' && event.value !== '/') { - this.redirectUrisList.push(event.value); + if (input.value !== '' && input.value !== ' ' && input.value !== '/') { + this.redirectUrisList.push(input.value); } if (input) { input.value = ''; diff --git a/console/src/app/pages/projects/apps/apps.module.ts b/console/src/app/pages/projects/apps/apps.module.ts index ff3c5208a7..768bbe8107 100644 --- a/console/src/app/pages/projects/apps/apps.module.ts +++ b/console/src/app/pages/projects/apps/apps.module.ts @@ -6,9 +6,7 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -21,6 +19,9 @@ import { TranslateModule } from '@ngx-translate/core'; import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { CardModule } from 'src/app/modules/card/card.module'; +import { ChangesModule } from 'src/app/modules/changes/changes.module'; +import { InputModule } from 'src/app/modules/input/input.module'; +import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { AppCreateComponent } from './app-create/app-create.component'; import { AppDetailComponent } from './app-detail/app-detail.component'; @@ -40,8 +41,6 @@ import { AppsRoutingModule } from './apps-routing.module'; TranslateModule, ReactiveFormsModule, HasRoleModule, - MatFormFieldModule, - MatInputModule, MatMenuModule, MatChipsModule, MatIconModule, @@ -59,6 +58,9 @@ import { AppsRoutingModule } from './apps-routing.module'; MatRadioModule, CopyToClipboardModule, MatSlideToggleModule, + InputModule, + MetaLayoutModule, + ChangesModule, ], exports: [TranslateModule], }) diff --git a/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.html b/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.html index 58afb475fa..ed46448a5e 100644 --- a/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.html +++ b/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.html @@ -17,7 +17,7 @@ description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}"> @@ -29,22 +29,22 @@
    {{'PROJECT.STATE.TITLE' | translate}}: - {{'PROJECT.STATE.'+project.state | translate}} + {{'PROJECT.STATE.'+project.state | translate}}
    - + [disabled]="(['project.member.write$', 'project.member.write:'+ project.projectId]| hasRole | async) == false"> - +
    diff --git a/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.scss b/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.scss index a44156df05..ff25a9436a 100644 --- a/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.scss +++ b/console/src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component.scss @@ -53,7 +53,7 @@ .first { flex: 1; - font-size: .8rem; + font-size: 13px; margin-right: .5rem; } @@ -61,11 +61,22 @@ flex: 1; } - .second { - font-size: .8rem; - text-overflow: ellipsis; - overflow: hidden; - margin-left: 1rem; + .state { + border-radius: 50vw; + padding: 2px .5rem; + letter-spacing: .05em; + font-size: 11px; + background-color: #8795a120; + + &.active { + background-color: #85d996; + color: black; + } + + &.inactive { + background-color: #ff8981; + color: black; + } } } } diff --git a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-grid/granted-project-grid.component.html b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-grid/granted-project-grid.component.html index 7724188bdc..5a7ab7bd20 100644 --- a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-grid/granted-project-grid.component.html +++ b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-grid/granted-project-grid.component.html @@ -1,5 +1,5 @@
    -
    diff --git a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.html b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.html index 92e8f886da..98b2666f65 100644 --- a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.html +++ b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.html @@ -3,7 +3,8 @@
    -
    @@ -67,6 +68,10 @@ [routerLink]="['/granted-projects', row.projectId, 'grant', row.id]">
    +
    + + {{'PROJECT.TABLE.EMPTY' | translate}} +
    diff --git a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.scss b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.scss index a9b1a25369..e1e0f01e09 100644 --- a/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.scss +++ b/console/src/app/pages/projects/granted-projects/granted-project-list/granted-project-list.component.scss @@ -31,11 +31,6 @@ padding-right: 0; } } - - .selection { - width: 50px; - max-width: 50px; - } } } diff --git a/console/src/app/pages/projects/granted-projects/granted-projects.module.ts b/console/src/app/pages/projects/granted-projects/granted-projects.module.ts index ffd9727d37..c1de234cff 100644 --- a/console/src/app/pages/projects/granted-projects/granted-projects.module.ts +++ b/console/src/app/pages/projects/granted-projects/granted-projects.module.ts @@ -3,9 +3,7 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -20,6 +18,7 @@ import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/memb import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; @@ -53,16 +52,15 @@ import { GrantedProjectsComponent } from './granted-projects.component'; HasRoleModule, MatTableModule, MatPaginatorModule, - MatFormFieldModule, - MatInputModule, + InputModule, ChangesModule, MatIconModule, MatSelectModule, MatButtonModule, + MatTabsModule, MatProgressSpinnerModule, MetaLayoutModule, MatProgressBarModule, - MatTabsModule, ProjectRolesModule, MatCheckboxModule, CardModule, diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html index 44800df12c..b34e25bdaa 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html @@ -7,7 +7,7 @@
    - +
    - - {{'PROJECT.NAME' | translate}} - - - @@ -80,10 +81,11 @@

    {{'PROJECT.ROLE.OPTIONS' | translate}}

    - + {{'PROJECT.ROLE.ASSERTION' | translate}}

    {{'PROJECT.ROLE.ASSERTION_DESCRIPTION' | translate}}

    - + {{'PROJECT.ROLE.CHECK' | translate}}

    {{'PROJECT.ROLE.CHECK_DESCRIPTION' | translate}}

    @@ -111,8 +113,8 @@
    {{'PROJECT.STATE.TITLE' | translate}}: - {{'PROJECT.STATE.'+project.state | translate}} + {{'PROJECT.STATE.'+project.state | translate}}
    diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.scss b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.scss index 2ab632c081..92cb54503d 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.scss +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.scss @@ -41,6 +41,19 @@ } } +.line { + .formfield { + flex: 1; + } + + button { + margin-top: 1rem; + } + + display: flex; + align-items: center; +} + .side { .details { margin-bottom: 1rem; @@ -54,15 +67,26 @@ .first { flex: 1; - font-size: .8rem; + font-size: 13px; margin-right: .5rem; } - .second { - font-size: .8rem; - text-overflow: ellipsis; - overflow: hidden; - margin-left: 1rem; + .state { + border-radius: 50vw; + padding: 2px .5rem; + letter-spacing: .05em; + font-size: 11px; + background-color: #8795a120; + + &.active { + background-color: #85d996; + color: black; + } + + &.inactive { + background-color: #ff8981; + color: black; + } } } } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.ts index 7044e99e28..14f291b64f 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.ts @@ -1,6 +1,6 @@ import { SelectionModel } from '@angular/cdk/collections'; import { Location } from '@angular/common'; -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, EventEmitter, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Params, Router } from '@angular/router'; @@ -73,6 +73,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy { = new BehaviorSubject([]); private loadingSubject: BehaviorSubject = new BehaviorSubject(true); public loading$: Observable = this.loadingSubject.asObservable(); + public refreshChanges$: EventEmitter = new EventEmitter(); constructor( public translate: TranslateService, @@ -139,6 +140,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy { this.mgmtService.ReactivateProject(this.projectId).then(() => { this.toast.showInfo('PROJECT.TOAST.REACTIVATED', true); this.project.state = ProjectState.PROJECTSTATE_ACTIVE; + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); @@ -160,6 +162,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy { this.mgmtService.DeactivateProject(this.projectId).then(() => { this.toast.showInfo('PROJECT.TOAST.DEACTIVATED', true); this.project.state = ProjectState.PROJECTSTATE_INACTIVE; + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); @@ -194,9 +197,9 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy { } public saveProject(): void { - console.log(this.project); this.mgmtService.UpdateProject(this.project.projectId, this.project).then(() => { this.toast.showInfo('PROJECT.TOAST.UPDATED', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts index 930c81c7f6..269742928c 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts @@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatRippleModule } from '@angular/material/core'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; @@ -19,6 +17,7 @@ import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/memb import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; @@ -48,11 +47,10 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen TranslateModule, ReactiveFormsModule, HasRoleModule, - MatInputModule, - MatTabsModule, MatButtonModule, MatIconModule, ContributorsModule, + MatTabsModule, WarnDialogModule, MatTooltipModule, ProjectRolesModule, @@ -60,7 +58,7 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen UserGrantsModule, TimestampToDatePipeModule, MatTableModule, - MatFormFieldModule, + InputModule, CardModule, MatPaginatorModule, MatRippleModule, diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.html index 4e29faeb68..e76f6d1453 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.html @@ -40,33 +40,33 @@ {{grant.grantedOrgName}} - - {{ 'PROJECT.GRANT.CREATIONDATE' | translate }} + + {{ 'PROJECT.GRANT.DATES' | translate }} - {{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} - - - - {{ 'PROJECT.GRANT.CHANGEDATE' | translate }} - - {{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} - +
    + {{ 'PROJECT.GRANT.CREATIONDATE' | translate }}: + {{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} +
    +
    + {{ 'PROJECT.GRANT.CHANGEDATE' | translate }} + {{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} +
    - {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} - - - {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} + {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} + + + + {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} {{role.key}} - + @@ -75,6 +75,11 @@ +
    + + {{'PROJECT.GRANT.EMPTY' | translate}} +
    + diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.scss b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.scss index bd754cd3d9..3f48607765 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.scss +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.scss @@ -39,11 +39,6 @@ tr.detail-row { height: 0; } - - .selection { - width: 50px; - max-width: 50px; - } } } @@ -51,3 +46,19 @@ outline: none; cursor: pointer; } + +.role-row { + min-width: 100px; +} + +.date-block { + margin: .5rem 0; + display: block; + min-width: 120px; + + .date-sub { + font-size: 13px; + color: var(--grey); + display: block; + } +} diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.ts index 895943fc31..74e89876f9 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/project-grants/project-grants.component.ts @@ -34,7 +34,7 @@ export class ProjectGrantsComponent implements OnInit, AfterViewInit { public memberRoleOptions: ProjectRoleView.AsObject[] = []; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ - public displayedColumns: string[] = ['select', 'grantedOrgName', 'creationDate', 'changeDate', 'roleNamesList']; + public displayedColumns: string[] = ['select', 'grantedOrgName', 'dates']; constructor(private mgmtService: ManagementService, private toast: ToastService) { } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-grid/owned-project-grid.component.html b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-grid/owned-project-grid.component.html index 5b87846dd3..fa9b85661b 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-grid/owned-project-grid.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-grid/owned-project-grid.component.html @@ -1,5 +1,5 @@
    -
    diff --git a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.html b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.html index 649ecaf830..be42b7f795 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.html @@ -4,7 +4,8 @@
    -
    @@ -77,6 +78,10 @@ [routerLink]="['/projects', row.projectId]"> +
    + + {{'PROJECT.TABLE.EMPTY' | translate}} +
    diff --git a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.scss b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.scss index f78e21b880..a2aa3ea710 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.scss +++ b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.scss @@ -40,11 +40,6 @@ h1 { padding-right: 0; } } - - .selection { - width: 50px; - max-width: 50px; - } } } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.ts b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.ts index 4cb9d30dc4..86d510c845 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-list/owned-project-list.component.ts @@ -73,7 +73,6 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy { public ngOnInit(): void { this.route.queryParams.pipe(take(1)).subscribe(params => { - console.log(params); this.getData(); if (params.deferredReload) { setTimeout(() => { diff --git a/console/src/app/pages/projects/owned-projects/owned-projects.module.ts b/console/src/app/pages/projects/owned-projects/owned-projects.module.ts index 63fc30ca76..1debf45fa9 100644 --- a/console/src/app/pages/projects/owned-projects/owned-projects.module.ts +++ b/console/src/app/pages/projects/owned-projects/owned-projects.module.ts @@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -17,6 +15,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { AvatarModule } from 'src/app/modules/avatar/avatar.module'; import { CardModule } from 'src/app/modules/card/card.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; import { SharedModule } from 'src/app/modules/shared/shared.module'; import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module'; @@ -48,8 +47,7 @@ import { OwnedProjectsComponent } from './owned-projects.component'; HasRoleModule, MatTableModule, MatPaginatorModule, - MatFormFieldModule, - MatInputModule, + InputModule, MatChipsModule, MatIconModule, WarnDialogModule, diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html index c9872fb86e..6e72151365 100644 --- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html +++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html @@ -25,14 +25,14 @@
    - - {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} + + {{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }} {{role.key}} - +
    diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.module.ts b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.module.ts index 5ec566c2c6..78c7fa49f6 100644 --- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.module.ts +++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.module.ts @@ -6,7 +6,6 @@ import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -16,6 +15,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MembersTableModule } from 'src/app/modules/members-table/members-table.module'; import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module'; @@ -39,7 +39,7 @@ import { MatIconModule, MatTableModule, MatPaginatorModule, - MatFormFieldModule, + InputModule, MatTooltipModule, ReactiveFormsModule, MatProgressSpinnerModule, diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-members-create-dialog/project-grant-members-create-dialog.component.html b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-members-create-dialog/project-grant-members-create-dialog.component.html index 90d58baa8c..639b0915dd 100644 --- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-members-create-dialog/project-grant-members-create-dialog.component.html +++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-members-create-dialog/project-grant-members-create-dialog.component.html @@ -6,14 +6,14 @@ - - {{ 'PROJECT.MEMBER.ROLES' | translate }} + + {{ 'PROJECT.MEMBER.ROLES' | translate }} {{ key }} - +

    {{'PROJECT.PAGES.CREATE_DESC' | translate}}

    -
    +
    - - {{'PROJECT.NAME' | translate}} - - + + {{'PROJECT.NAME' | translate}} + +
    \ No newline at end of file diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.ts b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.ts index 0931878e49..5cd08d9f0f 100644 --- a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.ts +++ b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component, EventEmitter, OnDestroy } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; @@ -41,6 +41,7 @@ export class AuthUserDetailComponent implements OnDestroy { public UserState: any = UserState; public USERGRANTCONTEXT: UserGrantContext = UserGrantContext.USER; + public refreshChanges$: EventEmitter = new EventEmitter(); constructor( public translate: TranslateService, @@ -53,6 +54,7 @@ export class AuthUserDetailComponent implements OnDestroy { } refreshUser(): void { + this.refreshChanges$.emit(); this.userService.GetMyUser().then(user => { this.user = user.toObject(); this.loading = false; @@ -86,6 +88,7 @@ export class AuthUserDetailComponent implements OnDestroy { .then((data: UserProfile) => { this.toast.showInfo('USER.TOAST.SAVED', true); this.user = Object.assign(this.user, data.toObject()); + this.refreshChanges$.emit(); }) .catch(error => { this.toast.showError(error); @@ -122,6 +125,7 @@ export class AuthUserDetailComponent implements OnDestroy { public resendPhoneVerification(): void { this.userService.ResendPhoneVerification().then(() => { this.toast.showInfo('USER.TOAST.PHONEVERIFICATIONSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); @@ -130,6 +134,7 @@ export class AuthUserDetailComponent implements OnDestroy { public resendEmailVerification(): void { this.userService.ResendMyEmailVerificationMail().then(() => { this.toast.showInfo('USER.TOAST.EMAILVERIFICATIONSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/code-dialog/code-dialog.component.html b/console/src/app/pages/users/user-detail/auth-user-detail/code-dialog/code-dialog.component.html index 90b963b343..f741b82d9d 100644 --- a/console/src/app/pages/users/user-detail/auth-user-detail/code-dialog/code-dialog.component.html +++ b/console/src/app/pages/users/user-detail/auth-user-detail/code-dialog/code-dialog.component.html @@ -3,10 +3,10 @@

    {{'USER.CODEDIALOG.DESCRIPTION' | translate}}

    - - {{ 'USER.CODEDIALOG.CODE' | translate }} - - + + {{ 'USER.CODEDIALOG.CODE' | translate }} + +
    - - Code - - + + Code + +
    diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/edit-dialog/edit-dialog.component.html b/console/src/app/pages/users/user-detail/auth-user-detail/edit-dialog/edit-dialog.component.html index 72facd2d68..37056e74fe 100644 --- a/console/src/app/pages/users/user-detail/auth-user-detail/edit-dialog/edit-dialog.component.html +++ b/console/src/app/pages/users/user-detail/auth-user-detail/edit-dialog/edit-dialog.component.html @@ -3,10 +3,10 @@

    {{data.descriptionKey | translate}}

    - - {{data.labelKey | translate }} - - + + {{data.labelKey | translate }} + +
    -
    diff --git a/console/src/app/pages/users/user-detail/contact/contact.component.scss b/console/src/app/pages/users/user-detail/contact/contact.component.scss index 8141f72f16..e73caf50eb 100644 --- a/console/src/app/pages/users/user-detail/contact/contact.component.scss +++ b/console/src/app/pages/users/user-detail/contact/contact.component.scss @@ -8,6 +8,7 @@ justify-content: space-between; align-items: center; padding: .5rem; + padding-right: 0; border-bottom: 1px solid #ffffff20; flex-wrap: wrap; diff --git a/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.component.html b/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.component.html index acfbd1e1e2..a5f13b128c 100644 --- a/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.component.html +++ b/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.component.html @@ -1,26 +1,26 @@
    - - {{ 'USER.MACHINE.USERNAME' | translate }} - - + + {{ 'USER.MACHINE.USERNAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - + + {{ 'USER.VALIDATION.NOEMAIL' | translate }} - - - - {{ 'USER.MACHINE.NAME' | translate }} - - + + + + {{ 'USER.MACHINE.NAME' | translate }} + + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.MACHINE.DESCRIPTION' | translate }} - - + + + + {{ 'USER.MACHINE.DESCRIPTION' | translate }} + +
    diff --git a/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.module.ts b/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.module.ts index 43eca9974a..4b6c95222c 100644 --- a/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.module.ts +++ b/console/src/app/pages/users/user-detail/detail-form-machine/detail-form-machine.module.ts @@ -2,11 +2,10 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; import { DetailFormMachineComponent } from './detail-form-machine.component'; @@ -20,8 +19,7 @@ import { DetailFormMachineComponent } from './detail-form-machine.component'; FormsModule, ReactiveFormsModule, TranslateModule, - MatFormFieldModule, - MatInputModule, + InputModule, MatSelectModule, MatButtonModule, MatIconModule, diff --git a/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html b/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html index 22f06e4a0a..b6d8149213 100644 --- a/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html +++ b/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html @@ -1,37 +1,37 @@
    - - {{ 'USER.PROFILE.USERNAME' | translate }} - - - - {{ 'USER.PROFILE.FIRSTNAME' | translate }} - - - - {{ 'USER.PROFILE.LASTNAME' | translate }} - - - - {{ 'USER.PROFILE.NICKNAME' | translate }} - - - - {{ 'USER.PROFILE.GENDER' | translate }} + + {{ 'USER.PROFILE.USERNAME' | translate }} + + + + {{ 'USER.PROFILE.FIRSTNAME' | translate }} + + + + {{ 'USER.PROFILE.LASTNAME' | translate }} + + + + {{ 'USER.PROFILE.NICKNAME' | translate }} + + + + {{ 'USER.PROFILE.GENDER' | translate }} {{ 'GENDERS.'+gender | translate }} - - - {{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }} + + + {{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }} {{ 'LANGUAGES.'+language | translate }} - +
    -
    +
    - diff --git a/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.component.ts b/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.component.ts index d47044df9f..83e48426c9 100644 --- a/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.component.ts +++ b/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.component.ts @@ -1,6 +1,6 @@ import { Component, Inject } from '@angular/core'; +import { FormControl } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { Moment } from 'moment'; import { MachineKeyType } from 'src/app/proto/generated/management_pb'; @Component({ @@ -9,22 +9,26 @@ import { MachineKeyType } from 'src/app/proto/generated/management_pb'; styleUrls: ['./add-key-dialog.component.scss'], }) export class AddKeyDialogComponent { + public startDate: Date = new Date(); types: MachineKeyType[] = [ MachineKeyType.MACHINEKEY_JSON, ]; - date!: Moment; public type: MachineKeyType = MachineKeyType.MACHINEKEY_JSON; + public dateControl: FormControl = new FormControl('', []); constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, - ) { } + ) { + const today = new Date(); + this.startDate.setDate(today.getDate() + 1); + } public closeDialog(): void { this.dialogRef.close(false); } public closeDialogWithSuccess(): void { - this.dialogRef.close({ type: this.type, date: this.date }); + this.dialogRef.close({ type: this.type, date: this.dateControl.value }); } } diff --git a/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.module.ts b/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.module.ts index e44f13d555..498ea22a5b 100644 --- a/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.module.ts +++ b/console/src/app/pages/users/user-detail/machine-keys/add-key-dialog/add-key-dialog.module.ts @@ -1,14 +1,14 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatMomentDateModule } from '@angular/material-moment-adapter'; import { MatButtonModule } from '@angular/material/button'; import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; +import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module'; import { AddKeyDialogComponent } from './add-key-dialog.component'; @@ -18,13 +18,14 @@ import { AddKeyDialogComponent } from './add-key-dialog.component'; CommonModule, TranslateModule, MatButtonModule, - MatFormFieldModule, + InputModule, MatSelectModule, - MatInputModule, MatIconModule, FormsModule, MatDatepickerModule, MatMomentDateModule, + ReactiveFormsModule, + LocalizedDatePipeModule, ], }) export class AddKeyDialogModule { } diff --git a/console/src/app/pages/users/user-detail/machine-keys/machine-keys.component.ts b/console/src/app/pages/users/user-detail/machine-keys/machine-keys.component.ts index f13c17921c..07f85bee7c 100644 --- a/console/src/app/pages/users/user-detail/machine-keys/machine-keys.component.ts +++ b/console/src/app/pages/users/user-detail/machine-keys/machine-keys.component.ts @@ -87,18 +87,16 @@ export class MachineKeysComponent implements OnInit { if (resp.date as Moment) { const ts = new Timestamp(); - console.log(resp.date.toDate().getTime()); + console.log(resp.date.toDate()); const milliseconds = resp.date.toDate().getTime(); const seconds = Math.abs(milliseconds / 1000); const nanos = (milliseconds - seconds * 1000) * 1000 * 1000; ts.setSeconds(seconds); ts.setNanos(nanos); date = ts; - console.log(date.toObject()); } if (type) { - console.log(this.userId, type, date); return this.userService.AddMachineKey(this.userId, type, date).then((response) => { if (response) { setTimeout(() => { @@ -126,7 +124,6 @@ export class MachineKeysComponent implements OnInit { this.userService.SearchMachineKeys(this.userId, limit, offset).then(resp => { this.keyResult = resp.toObject(); this.dataSource.data = this.keyResult.resultList; - console.log(this.keyResult.resultList); this.loadingSubject.next(false); }).catch((error: any) => { this.toast.showError(error); diff --git a/console/src/app/pages/users/user-detail/machine-keys/show-key-dialog/show-key-dialog.component.html b/console/src/app/pages/users/user-detail/machine-keys/show-key-dialog/show-key-dialog.component.html index 928a1555e4..bf0bdde670 100644 --- a/console/src/app/pages/users/user-detail/machine-keys/show-key-dialog/show-key-dialog.component.html +++ b/console/src/app/pages/users/user-detail/machine-keys/show-key-dialog/show-key-dialog.component.html @@ -11,12 +11,14 @@

    {{'USER.MACHINE.KEYTYPES.'+addedKey?.type | translate}}

    -

    {{'USER.MACHINE.EXPIRATIONDATE' | translate}}

    -

    {{addedKey?.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}

    +

    {{'USER.MACHINE.CREATIONDATE' | translate}}

    +

    {{addedKey?.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM YYYY, HH:mm' }} +

    {{'USER.MACHINE.EXPIRATIONDATE' | translate}}

    -

    {{addedKey?.expirationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}

    +

    {{addedKey?.expirationDate | timestampToDate | localizedDate: 'EEE dd. MMM YYYY, HH:mm'}} +

    diff --git a/console/src/app/pages/users/user-detail/membership-detail/membership-detail.component.scss b/console/src/app/pages/users/user-detail/membership-detail/membership-detail.component.scss index 6f3cf2fdc2..7d60e0e32f 100644 --- a/console/src/app/pages/users/user-detail/membership-detail/membership-detail.component.scss +++ b/console/src/app/pages/users/user-detail/membership-detail/membership-detail.component.scss @@ -27,11 +27,6 @@ .action { width: 40px; } - - .selection { - width: 50px; - max-width: 50px; - } } } diff --git a/console/src/app/pages/users/user-detail/memberships/memberships.component.html b/console/src/app/pages/users/user-detail/memberships/memberships.component.html index c4b9fa3611..f5010e16ec 100644 --- a/console/src/app/pages/users/user-detail/memberships/memberships.component.html +++ b/console/src/app/pages/users/user-detail/memberships/memberships.component.html @@ -1,5 +1,5 @@
    - {{ 'USER.MEMBERSHIPS.TITLE' | translate }} + {{ 'USER.MEMBERSHIPS.TITLE' | translate }}
    @@ -34,9 +34,9 @@ add -
    diff --git a/console/src/app/pages/users/user-detail/memberships/memberships.component.scss b/console/src/app/pages/users/user-detail/memberships/memberships.component.scss index f145943423..d8b533f2cb 100644 --- a/console/src/app/pages/users/user-detail/memberships/memberships.component.scss +++ b/console/src/app/pages/users/user-detail/memberships/memberships.component.scss @@ -9,11 +9,14 @@ /* stylelint-enable */ .membership-groups { - .header { + .me-header { display: block; margin-bottom: 1rem; font-weight: 400; margin-top: 0; + font-size: 14px; + letter-spacing: .05em; + text-transform: uppercase; } .sub-header { @@ -33,7 +36,6 @@ .img-list { width: 100%; - margin-top: .5rem; margin-left: 1rem; display: flex; align-items: center; @@ -54,7 +56,11 @@ .refresh-img { float: left; - margin: 0 8px 0 -15px; + margin: 0 0 0 -15px; + + .icon { + font-size: 1.2rem; + } } .avatar-circle { @@ -97,6 +103,7 @@ display: block; white-space: nowrap; overflow: hidden; + letter-spacing: .05em; } i { diff --git a/console/src/app/pages/users/user-detail/password/password.component.html b/console/src/app/pages/users/user-detail/password/password.component.html index 4b59e6ccfc..a3355c29d7 100644 --- a/console/src/app/pages/users/user-detail/password/password.component.html +++ b/console/src/app/pages/users/user-detail/password/password.component.html @@ -10,22 +10,22 @@
    - - {{ 'USER.PASSWORD.NEW' | translate }} - + + {{ 'USER.PASSWORD.NEW' | translate }} + - + {{ 'USER.VALIDATION.REQUIRED' | translate }} - - - - {{ 'USER.PASSWORD.CONFIRM' | translate }} - + + + {{ 'USER.PASSWORD.CONFIRM' | translate }} + - + {{ 'USER.PASSWORD.NOTEQUAL' | translate }} - - + +
    diff --git a/console/src/app/pages/users/user-detail/password/password.component.scss b/console/src/app/pages/users/user-detail/password/password.component.scss index 367b764660..0632dabe19 100644 --- a/console/src/app/pages/users/user-detail/password/password.component.scss +++ b/console/src/app/pages/users/user-detail/password/password.component.scss @@ -28,6 +28,6 @@ padding: .5rem 4rem; } -.mat-error { +.cnsl-error { display: block; } diff --git a/console/src/app/pages/users/user-detail/user-detail.module.ts b/console/src/app/pages/users/user-detail/user-detail.module.ts index 8bc4dd7525..a217c0e7b8 100644 --- a/console/src/app/pages/users/user-detail/user-detail.module.ts +++ b/console/src/app/pages/users/user-detail/user-detail.module.ts @@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -20,6 +18,7 @@ import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/memb import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; @@ -83,9 +82,7 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component'; ShowKeyDialogModule, MatCheckboxModule, HasRolePipeModule, - MatFormFieldModule, UserGrantsModule, - MatInputModule, MatButtonModule, MatIconModule, CardModule, @@ -104,6 +101,7 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component'; MemberCreateDialogModule, TimestampToDatePipeModule, LocalizedDatePipeModule, + InputModule, ], }) export class UserDetailModule { } diff --git a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.html b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.html index 98ba28223e..634356493a 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.html +++ b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.html @@ -89,7 +89,7 @@ @@ -102,12 +102,18 @@ {{'USER.PREFERRED_LOGINNAME' | translate}} {{user.preferredLoginName}}
    +
    + {{'ORG.PAGES.STATE' | translate}} + {{'USER.DATA.STATE'+user.state | translate}} +
    - + +
    \ No newline at end of file diff --git a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss index 8b0d7b9296..7e6257f7e4 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss +++ b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss @@ -41,18 +41,36 @@ .first { flex: 1; - font-size: .8rem; + font-size: 13px; margin-right: .5rem; white-space: nowrap; } .second { - font-size: .8rem; + font-size: .13px; text-overflow: ellipsis; overflow: hidden; margin-left: 1rem; text-align: right; } + + .state { + border-radius: 50vw; + padding: 2px .5rem; + letter-spacing: .05em; + font-size: 11px; + background-color: #8795a120; + + &.active { + background-color: #85d996; + color: black; + } + + &.inactive { + background-color: #ff8981; + color: black; + } + } } } diff --git a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts index 65d93bb058..ba7d839385 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts +++ b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts @@ -1,7 +1,7 @@ import { Location } from '@angular/common'; -import { Component, OnInit } from '@angular/core'; +import { Component, EventEmitter, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { take } from 'rxjs/operators'; import { ChangeType } from 'src/app/modules/changes/changes.component'; @@ -47,6 +47,7 @@ export class UserDetailComponent implements OnInit { public USERGRANTCONTEXT: UserGrantContext = UserGrantContext.USER; public EditDialogType: any = EditDialogType; + public refreshChanges$: EventEmitter = new EventEmitter(); constructor( public translate: TranslateService, @@ -55,9 +56,11 @@ export class UserDetailComponent implements OnInit { public mgmtUserService: ManagementService, private _location: Location, private dialog: MatDialog, + private router: Router, ) { } refreshUser(): void { + this.refreshChanges$.emit(); this.route.params.pipe(take(1)).subscribe(params => { const { id } = params; this.mgmtUserService.GetUserByID(id).then(user => { @@ -109,6 +112,7 @@ export class UserDetailComponent implements OnInit { .then((data: UserProfile) => { this.toast.showInfo('USER.TOAST.SAVED', true); this.user = Object.assign(this.user, data.toObject()); + this.refreshChanges$.emit(); }) .catch(error => { this.toast.showError(error); @@ -128,6 +132,7 @@ export class UserDetailComponent implements OnInit { .then((data: MachineResponse) => { this.toast.showInfo('USER.TOAST.SAVED', true); this.user = Object.assign(this.user, data.toObject()); + this.refreshChanges$.emit(); }) .catch(error => { this.toast.showError(error); @@ -138,15 +143,16 @@ export class UserDetailComponent implements OnInit { public resendEmailVerification(): void { this.mgmtUserService.ResendEmailVerification(this.user.id).then(() => { this.toast.showInfo('USER.TOAST.EMAILVERIFICATIONSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); } public resendPhoneVerification(): void { - console.log('resend phone ver', this.user.id); this.mgmtUserService.ResendPhoneVerification(this.user.id).then(() => { this.toast.showInfo('USER.TOAST.PHONEVERIFICATIONSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); @@ -201,6 +207,7 @@ export class UserDetailComponent implements OnInit { this.mgmtUserService.SendSetPasswordNotification(this.user.id, NotificationType.NOTIFICATIONTYPE_EMAIL) .then(() => { this.toast.showInfo('USER.TOAST.PASSWORDNOTIFICATIONSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); @@ -220,7 +227,10 @@ export class UserDetailComponent implements OnInit { dialogRef.afterClosed().subscribe(resp => { if (resp) { this.mgmtUserService.DeleteUser(this.user.id).then(() => { - this.navigateBack(); + const params: Params = { + 'deferredReload': true, + }; + this.router.navigate(['/users/list', this.user.human ? 'humans' : 'machines'], { queryParams: params }); this.toast.showInfo('USER.TOAST.DELETED', true); }).catch(error => { this.toast.showError(error); @@ -238,6 +248,7 @@ export class UserDetailComponent implements OnInit { if (resp.send && this.user.id) { this.mgmtUserService.ResendInitialMail(this.user.id, resp.email ?? '').then(() => { this.toast.showInfo('USER.TOAST.INITEMAILSENT', true); + this.refreshChanges$.emit(); }).catch(error => { this.toast.showError(error); }); diff --git a/console/src/app/pages/users/user-list/user-list.module.ts b/console/src/app/pages/users/user-list/user-list.module.ts index f9f3159c0a..2c174c0c91 100644 --- a/console/src/app/pages/users/user-list/user-list.module.ts +++ b/console/src/app/pages/users/user-list/user-list.module.ts @@ -4,9 +4,7 @@ import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatTableModule } from '@angular/material/table'; @@ -15,6 +13,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { AvatarModule } from 'src/app/modules/avatar/avatar.module'; import { CardModule } from 'src/app/modules/card/card.module'; +import { InputModule } from 'src/app/modules/input/input.module'; import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module'; import { SharedModule } from 'src/app/modules/shared/shared.module'; import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module'; @@ -48,8 +47,7 @@ import { UserTableComponent } from './user-table/user-table.component'; TranslateModule, SharedModule, RefreshTableModule, - MatFormFieldModule, - MatInputModule, + InputModule, ], exports: [ UserListComponent, diff --git a/console/src/app/pages/users/user-list/user-table/user-table.component.html b/console/src/app/pages/users/user-list/user-table/user-table.component.html index 83ec16168a..a508c5d858 100644 --- a/console/src/app/pages/users/user-list/user-table/user-table.component.html +++ b/console/src/app/pages/users/user-list/user-table/user-table.component.html @@ -1,11 +1,10 @@ - - {{'USER.PAGES.FILTER' | translate}} - + - +
    @@ -144,7 +149,7 @@ \ No newline at end of file diff --git a/console/src/app/pages/users/user-list/user-table/user-table.component.scss b/console/src/app/pages/users/user-list/user-table/user-table.component.scss index 4f910725e3..d3a7f7e8e7 100644 --- a/console/src/app/pages/users/user-list/user-table/user-table.component.scss +++ b/console/src/app/pages/users/user-list/user-table/user-table.component.scss @@ -7,21 +7,27 @@ td, th { - padding: .5rem; - outline: none; + padding-left: .5rem; + padding-right: .5rem; &:first-child { padding-left: 0; - padding-right: 1rem; + padding-right: .5rem; } &:last-child { padding-right: 0; } + } - .search-button, - .dlt-button { + th { + .search-button { visibility: hidden; + width: 30px; + + .icon { + font-size: 1.2rem; + } } &:hover, @@ -33,17 +39,16 @@ } tr { + .dlt-button { + visibility: hidden; + } + &:hover { .dlt-button { visibility: visible; } } } - - .selection { - width: 50px; - max-width: 50px; - } } } @@ -60,3 +65,25 @@ margin: auto; } } + +td { + outline: none; +} + +.state { + border-radius: 50vw; + padding: 2px .5rem; + letter-spacing: .05em; + font-size: 11px; + background-color: #8795a120; + + &.active { + background-color: #85d996; + color: black; + } + + &.inactive { + background-color: #ff8981; + color: black; + } +} diff --git a/console/src/app/pages/users/user-list/user-table/user-table.component.ts b/console/src/app/pages/users/user-list/user-table/user-table.component.ts index a79be84eb7..0e338445b6 100644 --- a/console/src/app/pages/users/user-list/user-table/user-table.component.ts +++ b/console/src/app/pages/users/user-list/user-table/user-table.component.ts @@ -1,15 +1,22 @@ import { SelectionModel } from '@angular/cdk/collections'; import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { MatInput } from '@angular/material/input'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { MatTableDataSource } from '@angular/material/table'; +import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; import { enterAnimations } from 'src/app/animations'; import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component'; import { UserView } from 'src/app/proto/generated/auth_pb'; -import { SearchMethod, UserSearchKey, UserSearchQuery, UserSearchResponse } from 'src/app/proto/generated/management_pb'; +import { + SearchMethod, + UserSearchKey, + UserSearchQuery, + UserSearchResponse, + UserState, +} from 'src/app/proto/generated/management_pb'; import { ManagementService } from 'src/app/services/mgmt.service'; import { ToastService } from 'src/app/services/toast.service'; @@ -30,7 +37,7 @@ export class UserTableComponent implements OnInit { @Input() refreshOnPreviousRoutes: string[] = []; @Input() disabled: boolean = false; @ViewChild(MatPaginator) public paginator!: MatPaginator; - @ViewChild('input') public filter!: MatInput; + @ViewChild('input') public filter!: Input; public dataSource: MatTableDataSource = new MatTableDataSource(); public selection: SelectionModel = new SelectionModel(true, []); public userResult!: UserSearchResponse.AsObject; @@ -41,11 +48,14 @@ export class UserTableComponent implements OnInit { @Output() public changedSelection: EventEmitter> = new EventEmitter(); UserSearchKey: any = UserSearchKey; + public UserState: any = UserState; + constructor( public translate: TranslateService, private userService: ManagementService, private toast: ToastService, private dialog: MatDialog, + private route: ActivatedRoute, ) { this.selection.changed.subscribe(() => { this.changedSelection.emit(this.selection.selected); @@ -53,7 +63,14 @@ export class UserTableComponent implements OnInit { } ngOnInit(): void { - this.getData(10, 0, this.userType); + this.route.queryParams.pipe(take(1)).subscribe(params => { + this.getData(10, 0, this.userType); + if (params.deferredReload) { + setTimeout(() => { + this.getData(10, 0, this.userType); + }, 2000); + } + }); } public isAllSelected(): boolean { @@ -78,7 +95,12 @@ export class UserTableComponent implements OnInit { return this.userService.DeactivateUser(value.id); })).then(() => { this.toast.showInfo('USER.TOAST.SELECTEDDEACTIVATED', true); - this.getData(10, 0, this.userType); + this.selection.clear(); + setTimeout(() => { + this.refreshPage(); + }, 1000); + }).catch(error => { + this.toast.showError(error); }); } @@ -87,7 +109,12 @@ export class UserTableComponent implements OnInit { return this.userService.ReactivateUser(value.id); })).then(() => { this.toast.showInfo('USER.TOAST.SELECTEDREACTIVATED', true); - this.getData(10, 0, this.userType); + this.selection.clear(); + setTimeout(() => { + this.refreshPage(); + }, 1000); + }).catch(error => { + this.toast.showError(error); }); } diff --git a/console/src/app/services/grpc.service.ts b/console/src/app/services/grpc.service.ts index 055c583b23..a2a305dfe4 100644 --- a/console/src/app/services/grpc.service.ts +++ b/console/src/app/services/grpc.service.ts @@ -76,7 +76,7 @@ export class GrpcService { } return Promise.resolve(data); }).catch(() => { - console.log('Failed to load environment from assets'); + console.error('Failed to load environment from assets'); }); } } diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index f003e5c456..31fef046a0 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -917,9 +917,10 @@ export class ManagementService { // - public ApplicationChanges(id: string, limit: number, offset: number): Promise { + public ApplicationChanges(id: string, secId: string, limit: number, offset: number): Promise { const req = new ChangeRequest(); req.setId(id); + req.setSecId(secId); req.setLimit(limit); req.setSequenceOffset(offset); return this.grpcService.mgmt.applicationChanges(req); diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 8869315d36..b9b787d416 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -38,7 +38,8 @@ "PERSONAL_INFO": "Persönliche Informationen", "IAM":"Administration", "ORGANIZATION": "Organisation", - "ADMINSECTION":"Administration", + "ADMINSECTION":"ZITADEL Administration", + "ORGSECTION":"Organisation", "PROJECTSSECTION":"Projektsektion", "PROJECT": "Projekte", "GRANTEDPROJECT":"Berechtigte Projekte", @@ -50,7 +51,17 @@ "IAMADMIN":"Du bist ein IAM-Administrator. Beachte, dass Du erhöhte Rechte besitzt.", "SHOWORGS":"Alle Organisationen anzeigen", "GRANTSECTION":"Berechtigungssektion", - "GRANTS":"Berechtigungen" + "GRANTS":"Berechtigungen", + "TOOLTIP": { + "PERSONAL":"Verwalte deinen persönlichen Account, deine IDPs, Login Methoden, Faktoren und Berechtigungen", + "IAM":"Verwalte ZITADELs globale Zugangsrichtlinien, bereinige views und fehlerhafte events", + "ORG":"Verwalte die Zugangsrichtlinien und Domains deiner Organisation ", + "SELFPROJECTS":"Verwalte die Projekte deiner Organisation", + "GRANTEDPROJECTS":"Verwalte die berechtigten Projekte von anderen Organisationen", + "HUMANUSERS":"Verwalte die Menschlichen Benutzer deiner Organisation", + "MACHINEUSERS":"Verwalte die Service Benutzer deiner Organisation", + "AUTHZ":"Verwalte die Berechtigungen deiner Organisationsbenutzer" + } }, "ACTIONS": { "SAVE": "Speichern", @@ -81,6 +92,9 @@ "SEND":"Senden", "NEWVALUE":"Neuer Wert" }, + "TABLE": { + "NOROWS":"Keine Daten" + }, "ERRORS": { "REQUIRED": "Bitte fülle alle benötigten Felder aus.", "TOKENINVALID": { @@ -131,7 +145,8 @@ "6":"Nach Email filtern", "10":"Nach Organisationsname filtern", "12":"Project Name" - } + }, + "EMPTY":"Keine Einträge" }, "MFA": { "TABLETYPE":"Typ", @@ -217,7 +232,8 @@ "KEYSDESC":"Definiere Deine Schlüssel mit einem optionalen Ablaufdatum.", "ID":"Schlüssel-ID", "TYPE":"Typ", - "EXPIRYDATE":"Ablaufdatum", + "EXPIRATIONDATE":"Ablaufdatum", + "CHOOSEDATEAFTER":"Geben Sie ein valides Ablaufdatum an. Ab", "CHOOSEEXPIRY":"Definiere ein Ablaufdatum", "CREATIONDATE":"Erstelldatum", "KEYDETAILS":"Schlüssel Details", @@ -286,6 +302,7 @@ }, "VALIDATION": { "INVALIDPATTERN": "Das Passwort erfüllt nicht die vorgegebenen Regeln.", + "NOTANEMAIL":"Der eingegebene Wert ist keine E-Mail Adresse.", "REQUIRED": "Das Eingagefeld ist leer.", "MINLENGTH":"Das Password muss mindestens {{requiredLength}} Zeichen lang sein.", "NOEMAIL":"Benutzername darf keine E-Mail-Adresse sein.", @@ -410,6 +427,7 @@ "ACTIVE":"Aktiv", "CREATE":"Organisation erstellen", "ORGDETAIL_TITLE":"Gebe den Namen und die Domain für die neue Organisation ein.", + "ORGDETAIL_TITLE_WITHOUT_DOMAIN":"Geben Sie den Namen der neuen Organisation ein.", "ORGDETAILUSER_TITLE":"Organisationsbesitzer hinzufügen", "ORGDOMAIN": { "TITLE":"Verifikation der Domain der Organisation", @@ -558,7 +576,7 @@ "ADDDESCRIPTION": "Gebe die E-Mail-Adressen der hinzuzufügenden Benutzer ein." }, "TABLE": { - "TOTAL": "Einträge gesamt:", + "TOTAL": "Einträge gesamt", "SELECTION": "Ausgewählte Elemente", "DEACTIVATE": "Benutzer deaktivieren", "ACTIVATE": "Benutzer aktivieren", @@ -626,6 +644,7 @@ "USERID": "Benutzer-ID" }, "GRANT": { + "EMPTY":"Noch keine Organisation berechtigt", "TITLE": "Berechtigte Organisationen", "DESCRIPTION": "Gewähre einer anderen Organisation Zugriff auf dieses Projekt.", "CREATE": { @@ -661,6 +680,7 @@ "GRANTEDORGNAME":"Name der Organisation", "CREATIONDATE": "Erstelldatum", "CHANGEDATE": "Letzte Änderung", + "DATES":"Datum", "ROLENAMESLIST": "Rollen", "NOROLES":"Keine Rollen", "TOAST":{ @@ -679,6 +699,7 @@ "NAMEREQUIRED":"Der Name ist erforderlich." }, "ROLE": { + "EMPTY":"Noch keine Rollen erstellt!", "ADDNEWLINE":"Zusätzliche Rolle hinzufügen", "KEY":"Key", "TITLE": "Rollen", @@ -712,7 +733,10 @@ "TYPE":"Typ", "CREATIONDATE":"Erstelldatum", "CHANGEDATE":"Letzte Änderung", - "RESOURCEOWNER":"Besitzer" + "RESOURCEOWNER":"Besitzer", + "SHOWTABLE":"Tabellendarstellung", + "SHOWGRID":"Rasterdarstellung", + "EMPTY":"Kein Projekt gefunden" }, "TOAST":{ "MEMBERREMOVED":"Manager entfernt.", @@ -836,6 +860,7 @@ "REDIRECTDESCRIPTIONWEB":"Die Weiterleitung muss mit https:// beginnen. http:// ist nur im Entwicklermodus zulässig.", "REDIRECTDESCRIPTIONNATIVE":"Die Weiterleitung muss mit einem eigenen Protokoll oder http://localhost beginnen.", "REDIRECTNOTVALID":"Diese Weiterleitung ist nicht zulässig.", + "COMMAORENTERSEPERATION":"mit ↵ trennen", "POSTREDIRECTTITLE":"Das ist die Weiterleitung nach einem Log-out.", "TYPEREQUIRED":"Der Typ ist notwendig.", "TITLE": "OIDC-Konfiguration", @@ -912,6 +937,7 @@ "TITLE":"Berechtigungen", "DESC":"Hier kannst Du die Berechtigungen Deiner Organisation verwalten.", "DELETE":"Berechtigung löschen", + "EMPTY":"Keine Berechtigungen gefunden", "ADD":"Berechtigung erstellen", "ADD_BTN":"Neu", "PROJECT": { diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index e5e6f78bd3..4a3239bc1e 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -38,7 +38,8 @@ "PERSONAL_INFO": "Personal Information", "IAM":"Administration", "ORGANIZATION": "Organisation", - "ADMINSECTION":"Administration", + "ADMINSECTION":"ZITADEL Administration", + "ORGSECTION":"Organisation", "PROJECTSSECTION":"Projects Section", "PROJECT": "Projects", "GRANTEDPROJECT":"Granted Projects", @@ -50,7 +51,17 @@ "IAMADMIN":"You are an IAM Administrator. Note that you have extended permissions.", "SHOWORGS":"Show All Organisations", "GRANTSECTION":"Authorization Section", - "GRANTS":"Authorizations" + "GRANTS":"Authorizations", + "TOOLTIP": { + "PERSONAL":"Show your Personal Account, your IDPs, Login methods, Factors and Authorisations", + "IAM":"Show ZITADELs global access policies, clear views and failed events", + "ORG":"Show your organisations access policies, and manage your domain names", + "SELFPROJECTS":"Show your organisations own projects", + "GRANTEDPROJECTS":"Show projects your organisation was granted access", + "HUMANUSERS":"Show all registered human users on your organisation", + "MACHINEUSERS":"Show service users of your organisation", + "AUTHZ":"Show authorizations available to your organisation users" + } }, "ACTIONS": { "SAVE": "Save", @@ -81,6 +92,9 @@ "SEND":"Send", "NEWVALUE":"New Value" }, + "TABLE": { + "NOROWS":"No data" + }, "ERRORS": { "REQUIRED": "Some required fields are missing.", "TOKENINVALID": { @@ -131,7 +145,8 @@ "6":"filter for email", "10":"filter for organisation name", "12":"filter for project name" - } + }, + "EMPTY":"No entries" }, "MFA": { "TABLETYPE":"Type", @@ -176,9 +191,9 @@ "DESCRIPTION": "Please provide the necesary information.", "NAMEANDEMAILSECTION":"Name and E-mail", "GENDERLANGSECTION":"Gender and Language", - "PHONESECTION":"Phonen Numbers", + "PHONESECTION":"Phonenumbers", "PASSWORDSECTION":"Initial Password", - "ADDRESSANDPHONESECTION":"Phone Number" + "ADDRESSANDPHONESECTION":"Phonenumber" }, "CODEDIALOG": { "TITLE":"Verify Phone Number", @@ -198,7 +213,7 @@ "PROFILE": { "TITLE": "Profile", "EMAIL": "E-mail", - "PHONE": "Phonen Number", + "PHONE": "Phonenumber", "USERNAME": "User Name", "FIRSTNAME": "First Name", "LASTNAME": "Last Name", @@ -217,7 +232,8 @@ "KEYSDESC":"Define your keys and add an optional expiration date.", "ID":"Key ID", "TYPE":"Type", - "EXPIRYDATE":"Expiration date", + "EXPIRATIONDATE":"Expiration date", + "CHOOSEDATEAFTER":"Enter a valid expiration after", "CHOOSEEXPIRY":"Select an expiration date", "CREATIONDATE":"Creation Date", "KEYDETAILS":"Key Details", @@ -286,6 +302,7 @@ }, "VALIDATION": { "INVALIDPATTERN": "The password does not fulfil the defined rules.", + "NOTANEMAIL":"The given value is not an e-mail address", "REQUIRED": "The input field is empty.", "MINLENGTH":"The password has to be at least {{requiredLength}} characters long.", "NOEMAIL":"The user name cannot be an e-mail address.", @@ -410,6 +427,7 @@ "ACTIVE":"Active", "CREATE":"Create Organisation", "ORGDETAIL_TITLE":"Enter the name and domain of your new organisation.", + "ORGDETAIL_TITLE_WITHOUT_DOMAIN":"Enter the name of your new organisation.", "ORGDETAILUSER_TITLE":"Configure Organisation Owner", "ORGDOMAIN": { "TITLE":"Organisation Domain Ownership Verification", @@ -558,7 +576,7 @@ "ADDDESCRIPTION": "Enter the e-mail addresses of the users to be added." }, "TABLE": { - "TOTAL": "Entries total:", + "TOTAL": "Entries total", "SELECTION": "Selected Elements", "DEACTIVATE": "Deactivate User", "ACTIVATE": "Activate User", @@ -626,6 +644,7 @@ "USERID":"User ID" }, "GRANT": { + "EMPTY":"No granted organisation.", "TITLE": "Granted Organisations", "DESCRIPTION": "Allow an other organisation to use your project.", "CREATE": { @@ -661,6 +680,7 @@ "GRANTEDORGNAME":"Organisation Name", "CREATIONDATE": "Creation Date", "CHANGEDATE": "Last modified", + "DATES":"Dates", "ROLENAMESLIST": "Roles", "NOROLES":"No roles", "TOAST": { @@ -679,6 +699,7 @@ "NAMEREQUIRED":"A name ist required." }, "ROLE": { + "EMPTY":"No role has been created yet.", "ADDNEWLINE":"Add additional role", "KEY":"Key", "TITLE": "Roles", @@ -712,7 +733,10 @@ "TYPE":"Type", "CREATIONDATE":"Created at", "CHANGEDATE":"Last modified", - "RESOURCEOWNER":"Owner" + "RESOURCEOWNER":"Owner", + "SHOWTABLE":"Show table", + "SHOWGRID":"Show grid", + "EMPTY":"No project found" }, "TOAST":{ "MEMBERREMOVED":"Manager removed.", @@ -837,6 +861,7 @@ "REDIRECTDESCRIPTIONWEB":"Redirect URIs must begin with https://. http:// is only valid with enabled development mode.", "REDIRECTDESCRIPTIONNATIVE":"Redirect URIs must begin with your own protocol or http://localhost.", "REDIRECTNOTVALID":"This redirect URI is not valid.", + "COMMAORENTERSEPERATION":"seperate with ↵", "TYPEREQUIRED":"The type is required.", "TITLE": "OIDC Configuration", "CLIENTID": "Client ID", @@ -912,6 +937,7 @@ "TITLE":"Authorizations", "DESC":"Here you can manage authorizations of your organization users.", "DELETE":"Delete Authorization", + "EMPTY":"No authorization found", "ADD":"Create Authorization", "ADD_BTN":"New", "PROJECT": { diff --git a/console/src/component-themes.scss b/console/src/component-themes.scss index ea92746ca4..3f8d7983fd 100644 --- a/console/src/component-themes.scss +++ b/console/src/component-themes.scss @@ -1,15 +1,18 @@ @import 'src/app/modules/card/card'; @import './styles/table'; +@import './styles/input.scss'; +@import './styles/error.scss'; @import './styles/link.scss'; @import './styles/sidenav-list'; @import 'src/app/modules/avatar/avatar.component'; @import 'src/app/modules/changes/changes.component'; @import 'src/app/modules/detail-layout/detail-layout.component'; @import 'src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component'; -@import 'src/app/modules/meta-layout/meta'; @import 'src/app/pages/users/user-detail/auth-user-detail/theme-setting/theme-card'; @import 'src/app/pages/users/user-detail/memberships/memberships.component'; @import 'src/app/app.component.scss'; +@import 'src/app/modules/form-field/form-field.component.scss'; +@import 'src/app/modules/label/label.component.scss'; @mixin component-themes($theme) { @include avatar-theme($theme); @@ -20,8 +23,11 @@ @include application-grid-theme($theme); @include membership-theme($theme); @include changes-theme($theme); - @include meta-theme($theme); @include theme-card($theme); + @include input-theme($theme); @include textvar($theme); + @include cnsl-form-field-theme($theme); + @include cnsl-label-theme($theme); + @include cnsl-error-theme($theme); @include link-theme($theme); } diff --git a/console/src/styles.scss b/console/src/styles.scss index 5d9daaa0d2..6103a34bef 100644 --- a/console/src/styles.scss +++ b/console/src/styles.scss @@ -160,7 +160,7 @@ $custom-typography: .mat-dialog-container, .mat-raised-button, .mat-stroked-button { - border-radius: .5rem !important; + border-radius: 6px !important; } .light-theme { @@ -168,7 +168,6 @@ $custom-typography: @include angular-material-theme($light-theme); --grey: #697386; - --table-row-back: #e7ebf0; --color-main: #5469d4; .sidenav, @@ -179,8 +178,8 @@ $custom-typography: } ::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); - box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); + box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); background-color: #fafafa; border-radius: 8px; } @@ -206,7 +205,6 @@ $custom-typography: @include component-themes($dark-theme); @include angular-material-theme($dark-theme); - --table-row-back: #292a2b; --color-main: #5282c1; .sidenav, @@ -265,6 +263,14 @@ body { sans-serif; } +h2 { + font-size: 1.3rem; +} + +.mat-paginator .mat-select { + border: none; +} + .max-width-container { max-width: 1350px; padding: 0 1.5rem; @@ -280,7 +286,8 @@ body { } @media only screen and (max-width: 500px) { - padding-left: 1.5rem; + padding-left: .5rem; + padding-right: .5rem; } } @@ -290,7 +297,8 @@ body { padding-left: 4rem; @media only screen and (max-width: 500px) { - padding-left: 1.5rem; + padding-left: .5rem; + padding-right: .5rem; } } diff --git a/console/src/styles/error.scss b/console/src/styles/error.scss new file mode 100644 index 0000000000..02ff8722c7 --- /dev/null +++ b/console/src/styles/error.scss @@ -0,0 +1,19 @@ + +@import '~@angular/material/theming'; + +@mixin cnsl-error-theme($theme) { + $warn: map-get($theme, warn); + $warn-color: mat-color($warn, 500); + $is-dark-theme: map-get($theme, is-dark); + + .cnsl-error { + display: block; + font-size: 12px; + color: $warn-color; + margin-bottom: 5px; + + // &.block { + // display: block; + // } + } +} diff --git a/console/src/styles/input.scss b/console/src/styles/input.scss new file mode 100644 index 0000000000..886e23ee8a --- /dev/null +++ b/console/src/styles/input.scss @@ -0,0 +1,72 @@ +@import '~@angular/material/theming'; + +@mixin input-theme($theme) { + /* stylelint-disable */ + $primary: map-get($theme, primary); + $primary-dark: mat-color($primary, A900); + $secondary-dark: mat-color($primary, A800); + $inv-color: mat-color($primary, A600); + $primary-color: mat-color($primary, 500); + $primary-light-color: mat-color($primary, 200); + $warn: map-get($theme, warn); + $warn-color: mat-color($warn, 500); + $foreground: map-get($theme, foreground); + $is-dark-theme: map-get($theme, is-dark); + + [cnslInput], + .mat-select { + display: block; + box-sizing: border-box; + padding-inline-start: 10px; + outline: none; + display: inline-block; + text-align: start; + background-color: inherit; + cursor: text; + border-radius: 8px; + transform: all .2 linear; + font-size: 1rem; + border: none; + border: 1px solid if($is-dark-theme, #403e3e, #00000040); + background-color:if($is-dark-theme, #00000020, #fafafa50); + border-radius: 4px; + height: 40px; + padding: 10px; + transition: border-color .2s ease-in-out; + width: 100%; + color: mat-color($foreground, text); + margin-bottom: 2px; + + &:hover { + border-color: if($is-dark-theme,#aeafb1, #1a1b1b); + } + + &:active, + &:focus { + border-color: $primary-color; + } + + &.ng-touched { + &.ng-invalid { + border-color: $warn-color; + } + } + + &[disabled] { + border-color: if($is-dark-theme,#36373850,#cccdce50); + cursor: not-allowed; + } + } + + [cnslInput]::placeholder { + font-size: 14px; + color: var(--grey); + font-style: italic; + } + + .mat-paginator { + .mat-select { + background-color: inherit; + } + } +} diff --git a/console/src/styles/sidenav-list.scss b/console/src/styles/sidenav-list.scss index a2f88e9bff..e08e318e53 100644 --- a/console/src/styles/sidenav-list.scss +++ b/console/src/styles/sidenav-list.scss @@ -9,8 +9,13 @@ $primary-dark: mat-color($primary, A900); $foreground: map-get($theme, foreground); $sec-dark: mat-color($primary, A800); + $is-dark-theme: map-get($theme, is-dark); /* stylelint-enable */ + .meta { + box-shadow: inset 1px 0 if($is-dark-theme, #303131, #e3e8ee); + } + .nav-item { color: mat-color($foreground, text) !important; @@ -56,6 +61,8 @@ .admin-line { position: fixed; + display: flex; + align-items: center; bottom: 0; left: 0; right: calc(100vw - 300px); @@ -67,6 +74,7 @@ transform: translateY(75%); transition: all .2s; border-top-right-radius: 5px; + border-top-left-radius: 5px; span { display: none; @@ -85,18 +93,6 @@ } } - &::before { - content: ''; - position: absolute; - width: 0; - height: 0; - top: 0; - left: 0; - border-bottom: 20px solid transparent; - border-left: 20px solid $primary-dark; - transition: border-color .3s cubic-bezier(.645, .045, .355, 1); - } - &.expanded, &:hover { transform: translateY(0%); @@ -107,4 +103,14 @@ } } } + + .divider { + .span { + border-color: if($is-dark-theme, #303131, #e3e8ee); + } + + .line { + background-color: if($is-dark-theme, #303131, #e3e8ee); + } + } } diff --git a/console/src/styles/table.scss b/console/src/styles/table.scss index dae3cccb91..a935730508 100644 --- a/console/src/styles/table.scss +++ b/console/src/styles/table.scss @@ -3,10 +3,14 @@ @mixin table-theme($theme) { /* stylelint-disable */ $primary: map-get($theme, primary); + $warn: map-get($theme, warn); + $warn-color: mat-color($warn, 500); + $primary-color: mat-color($primary, 500); $primary-dark: mat-color($primary, A900); $secondary-dark: mat-color($primary, A800); $inv-color: mat-color($primary, A600); $foreground: map-get($theme, foreground); + $is-dark-theme: map-get($theme, is-dark); .mat-table, .mat-paginator { @@ -24,21 +28,60 @@ padding: 3px 1rem; } + th { + text-transform: uppercase; + letter-spacing: .05em; + font-weight: bold; + white-space: nowrap; + + &.mat-header-cell { + color: var(--grey); + font-size: 11px; + font-weight: 400; + } + } + td { - .mat-form-field-wrapper { + .cnsl-form-field-wrapper { padding-bottom: 0; } } tr { + &.mat-header-row { + height: 40px; + padding-bottom: 4px; + } + &.highlight { cursor: pointer; &:hover { td { - background: var(--table-row-back); // rgba($inv-color, .05); + background: if($is-dark-theme, #292a2b, #f4f4f4); // rgba($inv-color, .05); } } } } + + .mat-checkbox { + margin-left: 1rem; + } + + .no-content-row { + background-color: if($is-dark-theme, #00000030, #f4f4f470); + // color: $primary-color; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + display: flex; + align-items: center; + padding: .5rem; + font-size: 14px; + justify-content: center; + } + + .selection { + width: 65px; + max-width: 65px; + } }