mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 20:43:41 +00:00
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:
@@ -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 {
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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> {}
|
||||
@@ -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,
|
||||
125
web/projects/shared/src/components/prompt.component.ts
Normal file
125
web/projects/shared/src/components/prompt.component.ts
Normal 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
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
|
||||
import { TickerComponent } from './ticker.component'
|
||||
|
||||
@NgModule({
|
||||
declarations: [TickerComponent],
|
||||
exports: [TickerComponent],
|
||||
})
|
||||
export class TickerModule {}
|
||||
Reference in New Issue
Block a user