Refactor i18n approach (#2875)

* Refactor i18n approach

* chore: move to shared

* chore: add default

* create DialogService and update LoadingService (#2876)

* complete translation infra for ui project, currently broken

* cleanup and more dictionaries

* chore: fix

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
Alex Inkin
2025-04-17 22:00:59 +07:00
committed by GitHub
parent 47b6509f70
commit 50755d8ba3
175 changed files with 4141 additions and 1831 deletions

View File

@@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { TuiProgress } from '@taiga-ui/kit'
import { LogsWindowComponent } from './logs-window.component'
import { i18nPipe } from '../i18n/i18n.pipe'
@Component({
standalone: true,
@@ -9,10 +10,10 @@ import { LogsWindowComponent } from './logs-window.component'
template: `
<section>
<h1 [style.font-size.rem]="2" [style.margin-bottom.rem]="2">
Setting up your server
{{ 'Setting up your server' | i18n }}
</h1>
<div *ngIf="progress.total">
Progress: {{ (progress.total * 100).toFixed(0) }}%
{{ 'Progress' | i18n }}: {{ (progress.total * 100).toFixed(0) }}%
</div>
<progress
tuiProgressBar
@@ -49,7 +50,7 @@ import { LogsWindowComponent } from './logs-window.component'
background: #181818;
}
`,
imports: [CommonModule, LogsWindowComponent, TuiProgress],
imports: [CommonModule, LogsWindowComponent, TuiProgress, i18nPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InitializingComponent {

View File

@@ -1,19 +0,0 @@
@import '@taiga-ui/core/styles/taiga-ui-local';
:host {
display: flex;
align-items: center;
max-width: 80%;
margin: auto;
padding: 1.5rem;
background: var(--tui-background-elevation-1);
border-radius: var(--tui-radius-m);
box-shadow: var(--tui-shadow-popup);
--tui-background-accent-1: var(--tui-status-warning);
}
tui-loader {
flex-shrink: 0;
min-width: 2rem;
}

View File

@@ -1,14 +0,0 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { TuiLoader } from '@taiga-ui/core'
import { injectContext, PolymorpheusContent } from '@taiga-ui/polymorpheus'
@Component({
standalone: true,
template: '<tui-loader [textContent]="content" />',
styleUrls: ['./loading.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiLoader],
})
export class LoadingComponent {
readonly content = injectContext<{ content: PolymorpheusContent }>().content
}

View File

@@ -1,11 +0,0 @@
import { TuiPopoverService } from '@taiga-ui/cdk'
import { Injectable } from '@angular/core'
import { TUI_DIALOGS } from '@taiga-ui/core'
import { LoadingComponent } from './loading.component'
@Injectable({
providedIn: `root`,
useFactory: () => new LoadingService(TUI_DIALOGS, LoadingComponent),
})
export class LoadingService extends TuiPopoverService<unknown> {}

View File

@@ -7,7 +7,7 @@ import {
} from '@ng-web-apis/intersection-observer'
import { WaMutationObserver } from '@ng-web-apis/mutation-observer'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { SetupLogsService } from '../../services/setup-logs.service'
import { SetupLogsService } from '../services/setup-logs.service'
@Component({
standalone: true,

View File

@@ -0,0 +1,125 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { TuiAutoFocus } from '@taiga-ui/cdk'
import { TuiButton, TuiDialogContext } from '@taiga-ui/core'
import { TuiInputModule, TuiTextfieldControllerModule } from '@taiga-ui/legacy'
import {
POLYMORPHEUS_CONTEXT,
PolymorpheusComponent,
} from '@taiga-ui/polymorpheus'
import { i18nPipe } from '../i18n/i18n.pipe'
import { i18nKey } from '../i18n/i18n.providers'
@Component({
standalone: true,
template: `
<p>{{ options.message }}</p>
<p *ngIf="options.warning" class="warning">{{ options.warning }}</p>
<form (ngSubmit)="submit(value.trim())">
<tui-input
tuiAutoFocus
[tuiTextfieldLabelOutside]="!options.label"
[tuiTextfieldCustomContent]="options.useMask ? toggle : ''"
[ngModelOptions]="{ standalone: true }"
[(ngModel)]="value"
>
{{ options.label }}
<span *ngIf="options.required !== false && options.label">*</span>
<input
tuiTextfieldLegacy
[class.masked]="options.useMask && masked && value"
[placeholder]="options.placeholder || ''"
/>
</tui-input>
<footer class="g-buttons">
<button
tuiButton
type="button"
appearance="secondary"
(click)="cancel()"
>
{{ 'Cancel' | i18n }}
</button>
<button tuiButton [disabled]="!value && options.required !== false">
{{ options.buttonText || ('Submit' | i18n) }}
</button>
</footer>
</form>
<ng-template #toggle>
<button
tuiIconButton
type="button"
appearance="icon"
title="Toggle masking"
size="xs"
class="button"
[iconStart]="masked ? '@tui.eye' : '@tui.eye-off'"
(click)="masked = !masked"
></button>
</ng-template>
`,
styles: [
`
.warning {
color: var(--tui-status-warning);
}
.button {
pointer-events: auto;
margin-left: 0.25rem;
}
.masked {
-webkit-text-security: disc;
}
`,
],
imports: [
CommonModule,
FormsModule,
TuiInputModule,
TuiButton,
TuiTextfieldControllerModule,
TuiAutoFocus,
i18nPipe,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PromptModal {
masked = this.options.useMask
value = this.options.initialValue || ''
constructor(
@Inject(POLYMORPHEUS_CONTEXT)
private readonly context: TuiDialogContext<string, PromptOptions>,
) {}
get options(): PromptOptions {
return this.context.data
}
cancel() {
this.context.$implicit.complete()
}
submit(value: string) {
if (value || !this.options.required) {
this.context.$implicit.next(value)
}
}
}
export const PROMPT = new PolymorpheusComponent(PromptModal)
export interface PromptOptions {
message: i18nKey
label?: i18nKey
warning?: i18nKey
buttonText?: i18nKey
placeholder?: i18nKey
required?: boolean
useMask?: boolean
initialValue?: string | null
}

View File

@@ -1,6 +1,6 @@
import { DatePipe } from '@angular/common'
import { Component, inject, input } from '@angular/core'
import { TuiDialogService, TuiIcon, TuiTitle } from '@taiga-ui/core'
import { Component, input } from '@angular/core'
import { TuiIcon, TuiTitle } from '@taiga-ui/core'
import { TuiCell } from '@taiga-ui/layout'
import { StartOSDiskInfo } from '../types/api'

View File

@@ -7,9 +7,24 @@ import {
} from '@angular/core'
@Component({
standalone: true,
selector: '[ticker]',
template: '<ng-content />',
styleUrls: ['./ticker.component.scss'],
styles: `
:host {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: text-indent 1s;
&:hover {
text-indent: var(--indent, 0);
text-overflow: clip;
cursor: default;
}
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TickerComponent {

View File

@@ -1,13 +0,0 @@
:host {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: text-indent 1s;
&:hover {
text-indent: var(--indent, 0);
text-overflow: clip;
cursor: default;
}
}

View File

@@ -1,9 +0,0 @@
import { NgModule } from '@angular/core'
import { TickerComponent } from './ticker.component'
@NgModule({
declarations: [TickerComponent],
exports: [TickerComponent],
})
export class TickerModule {}