mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-01 20:02:15 +00:00
feat(console): message and login texts, privacy policy (#2016)
* message texts wrapper components * message-text sub, i18n, grid * fix routing * pack * pack * update material * audit * fix mgmt service for labelplcy * map conv * edit text from map * request map * fetch data, mgmt admin service * warn box, i18n * resetbtn * login texts * login text requests * reset, default, i18n * disabled, features, message text setter, service * locale switcher * policy grid * password reset, domain claimed i18n * lint files * fix admin service, i18n, lang setter * fix scss duplicate * privacy policy, cleanup grid, fix message, login texts (#2031) * policy grid everywhere 🦒 * cleanup home * log login text request * patch all data * refresh toggle * fix: add dialog for unsaved changes (#2057) * logintexts dialog * check for dialog on pairwise operation * fix: patch value to local state after save * fix: i18n and custom login texts (#2060) * fix: i18n and custom login texts * fix: tos and privacy texts * fix frontend * fix: tos and privacy texts and tests * fix: i18n, tos and privacy texts and tests * fix frontend maps * i18n * add ResetCustomLoginTextToDefault in admin api and fix template remove in handlers * resetlogintexttodefault Co-authored-by: Livio Amstutz <[email protected]>
This commit is contained in:
co-authored by
Livio Amstutz
parent
26e4e607bc
commit
2e684684de
@@ -0,0 +1,31 @@
|
||||
<div *ngIf="currentMap">
|
||||
|
||||
|
||||
<form [formGroup]="form" >
|
||||
<ng-container *ngFor="let key of (current$ | async) | keyvalue">
|
||||
<div class="block">
|
||||
<div class="flex" *ngIf="(default$ | async) as defaultmap">
|
||||
<cnsl-form-field class="formfield" >
|
||||
<cnsl-label>{{key.key}}</cnsl-label>
|
||||
<textarea class="text" cnslInput [formControlName]="key.key" [placeholder]="defaultmap[key.key]" [name]="key.key" [ngClass]="{'defaulttext': form.get(key.key)?.value === ''}"></textarea>
|
||||
<div class="chips" *ngIf="warnText[key.key] == undefined">
|
||||
<ng-container *ngFor="let chip of chips" >
|
||||
<div class="chip" appCopyToClipboard [valueToCopy]="chip.value" (copiedValue)="copied = $event" (click)="addChip(key.key, chip.value)">
|
||||
<span class="key">{{chip.key | translate}}</span>
|
||||
<span class="value">{{chip.value}}</span>
|
||||
<i *ngIf="copied != chip.value" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied == chip.value" class="las la-clipboard-check"></i>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</cnsl-form-field>
|
||||
<div class="actions">
|
||||
<button matTooltip="{{'ACTIONS.RESETDEFAULT'| translate }}" mat-icon-button [disabled]="form.get(key.key)?.value == defaultmap[key.key] || disabled" (click)="form.get(key.key)?.setValue(defaultmap[key.key])" (mouseenter) = "form.get(key.key)?.value != defaultmap[key.key] && setWarnText(key.key, defaultmap[key.key])" (mouseleave) ="setWarnText(key.key, undefined)"><i class="las la-history"></i></button>
|
||||
<button matTooltip="{{'ACTIONS.RESETCURRENT'| translate }}" mat-icon-button [disabled]="form.get(key.key)?.value == currentMap[key.key] || disabled" (click)="form.get(key.key)?.setValue(currentMap[key.key])" (mouseenter) = "form.get(key.key)?.value != currentMap[key.key] && setWarnText(key.key, currentMap[key.key])" (mouseleave) ="setWarnText(key.key, undefined)"><i class="las la-undo"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<cnsl-info-section *ngIf="warnText[key.key] !== undefined" class="info" type="WARN">{{'ACTIONS.RESETTO'| translate }} <cite>'{{warnText[key.key]}}'</cite></cnsl-info-section>
|
||||
</ng-container>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,96 @@
|
||||
.block {
|
||||
display: block;
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
|
||||
.text {
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
&.hovering {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
opacity: 0;
|
||||
margin: 0 -.25rem;
|
||||
transition: all .2s ease;
|
||||
|
||||
.chip {
|
||||
border-radius: 50vw;
|
||||
padding: 4px .5rem;
|
||||
font-size: 12px;
|
||||
background: #5282c1;
|
||||
color: white;
|
||||
margin: .25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
|
||||
* {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
i {
|
||||
opacity: .5;
|
||||
font-size: 1.1rem;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.key {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.key {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cnsl-focused {
|
||||
.chips {
|
||||
opacity: 1;
|
||||
cursor: copy;
|
||||
}
|
||||
}
|
||||
|
||||
.chips:hover {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
display: block;
|
||||
margin-right: 40px;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EditTextComponent } from './edit-text.component';
|
||||
|
||||
describe('EditTextComponent', () => {
|
||||
let component: EditTextComponent;
|
||||
let fixture: ComponentFixture<EditTextComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [EditTextComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditTextComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-edit-text',
|
||||
templateUrl: './edit-text.component.html',
|
||||
styleUrls: ['./edit-text.component.scss'],
|
||||
})
|
||||
export class EditTextComponent implements OnInit, OnDestroy {
|
||||
@Input() label: string = '';
|
||||
@Input() current$!: Observable<{ [key: string]: any | string; }>;
|
||||
@Input() default$!: Observable<{ [key: string]: any | string; }>;
|
||||
@Input() currentlyDragged: string = '';
|
||||
@Output() changedValues: EventEmitter<{ [key: string]: string; }> = new EventEmitter();
|
||||
public currentMap: { [key: string]: string; } = {};
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
public form!: FormGroup;
|
||||
public warnText: { [key: string]: string | undefined; } = {};
|
||||
|
||||
@Input() public chips: any[] = [];
|
||||
@Input() public disabled: boolean = true;
|
||||
|
||||
public copied: string = '';
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.current$.pipe(takeUntil(this.destroy$)).subscribe(value => {
|
||||
this.currentMap = value;
|
||||
this.form = new FormGroup({});
|
||||
Object.keys(value).map(key => {
|
||||
const control = new FormControl({ value: value[key], disabled: this.disabled });
|
||||
this.form.addControl(key, control);
|
||||
});
|
||||
|
||||
this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(values => this.changedValues.emit(values));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
public setWarnText(key: string, text: string | undefined): void {
|
||||
this.warnText[key] = text;
|
||||
}
|
||||
|
||||
public addChip(key: string, value: string): void {
|
||||
const c = this.form.get(key)?.value;
|
||||
this.form.get(key)?.setValue(`${c} ${value}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { TextFieldModule } from '@angular/cdk/text-field';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { FormFieldModule } from '../form-field/form-field.module';
|
||||
import { InfoSectionModule } from '../info-section/info-section.module';
|
||||
import { EditTextComponent } from './edit-text.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
EditTextComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
InfoSectionModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
InputModule,
|
||||
FormFieldModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
MatTooltipModule,
|
||||
TextFieldModule,
|
||||
CopyToClipboardModule,
|
||||
],
|
||||
exports: [
|
||||
EditTextComponent,
|
||||
],
|
||||
})
|
||||
export class EditTextModule { }
|
||||
Reference in New Issue
Block a user