From 020fb59b12959c0dfbda19db167bf9cc7f621f90 Mon Sep 17 00:00:00 2001 From: Roman Sedov Date: Fri, 4 Dec 2020 09:44:52 +0300 Subject: [PATCH] feat(all): i18n for packages (#49) * chore(icons): fix dist paths * chore(kit): finish kit i18n * chore(demo): update logo * chore(addon-table): add i18n * chore(core, kit, tablebars): i18n issues * chore(commerce): add i18n * chore(editor): i18n * chore(all): fix comments and tests * ci(build): build all packages * refactor(package-json): build command * chore(adon-editor): fix build * chore(adon-editor): fix import --- .github/workflows/build.yml | 14 +- package.json | 13 +- .../input-card-grouped.component.ts | 6 + .../input-card-grouped.template.html | 6 +- projects/addon-commerce/index.ts | 1 + projects/addon-commerce/tokens/i18n.ts | 15 ++ projects/addon-commerce/tokens/index.ts | 1 + projects/addon-commerce/tokens/package.json | 7 + .../validators/luhn.validator.ts | 7 +- .../validators/test/luhn.validator.spec.ts | 12 +- .../color-selector.component.ts | 10 +- .../components/toolbar/toolbar.component.ts | 12 +- .../components/toolbar/toolbar.template.html | 61 ++++---- projects/addon-editor/enums/editor-tool.ts | 2 +- projects/addon-editor/tokens/i18n.ts | 63 +++++++++ projects/addon-editor/tokens/index.ts | 1 + .../components/reorder/reorder.component.ts | 5 +- .../components/reorder/reorder.template.html | 3 +- .../table-pagination.component.ts | 11 +- .../table-pagination.template.html | 14 +- projects/addon-table/index.ts | 1 + projects/addon-table/tokens/i18n.ts | 18 +++ projects/addon-table/tokens/index.ts | 1 + projects/addon-table/tokens/package.json | 7 + .../table-bars-host.component.ts | 7 +- .../table-bars-host.template.html | 3 +- .../data-list/data-list.component.ts | 6 +- projects/core/tokens/i18n.ts | 7 + .../src/assets/android-chrome-192x192.png | Bin 2799 -> 3564 bytes .../src/assets/android-chrome-512x512.png | Bin 6066 -> 18597 bytes projects/demo/src/assets/apple-touch-icon.png | Bin 1921 -> 2035 bytes projects/demo/src/assets/browserconfig.xml | 2 +- projects/demo/src/assets/favicon-16x16.png | Bin 792 -> 736 bytes projects/demo/src/assets/favicon-32x32.png | Bin 1085 -> 1056 bytes projects/demo/src/assets/favicon.ico | Bin 15086 -> 15086 bytes projects/demo/src/assets/images/taiga.svg | 2 +- projects/demo/src/assets/mstile-144x144.png | Bin 2097 -> 0 bytes projects/demo/src/assets/mstile-150x150.png | Bin 2177 -> 2324 bytes projects/demo/src/assets/mstile-310x150.png | Bin 2297 -> 0 bytes projects/demo/src/assets/mstile-310x310.png | Bin 3821 -> 0 bytes projects/demo/src/assets/mstile-70x70.png | Bin 1795 -> 0 bytes .../demo/src/assets/safari-pinned-tab.svg | 133 ++++++++++++++---- projects/demo/src/index.html | 4 +- .../input-card/input-card.component.ts | 5 +- projects/icons/ng-package.json | 2 +- projects/icons/scripts/copy-icons.js | 2 +- .../calendar-range.component.ts | 6 +- .../test/range-calendar.component.spec.ts | 13 +- .../data-list-wrapper.component.ts | 9 +- .../input-file/file/file.component.ts | 3 +- .../input-file/input-file.component.ts | 13 +- .../unfinished-validator.directive.ts | 4 +- projects/kit/tokens/i18n.ts | 69 +++++---- .../create-default-day-range-periods.ts | 24 ++-- .../kit/validators/unfinished.validator.ts | 5 +- 55 files changed, 433 insertions(+), 177 deletions(-) create mode 100644 projects/addon-commerce/tokens/i18n.ts create mode 100644 projects/addon-commerce/tokens/index.ts create mode 100644 projects/addon-commerce/tokens/package.json create mode 100644 projects/addon-editor/tokens/i18n.ts create mode 100644 projects/addon-table/tokens/i18n.ts create mode 100644 projects/addon-table/tokens/index.ts create mode 100644 projects/addon-table/tokens/package.json delete mode 100644 projects/demo/src/assets/mstile-144x144.png delete mode 100644 projects/demo/src/assets/mstile-310x150.png delete mode 100644 projects/demo/src/assets/mstile-310x310.png delete mode 100644 projects/demo/src/assets/mstile-70x70.png diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27618e9f21c6..44a488fd5052 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,14 @@ jobs: run: npm ci # End of setup - run: | - npm run build:cdk - npm run build:core - npm run build:kit + npm run build cdk + npm run build core + npm run build kit + npm run build addon-charts + npm run build addon-commerce + npm run build addon-mobile + npm run build addon-doc + npm run build addon-editor + npm run build addon-table + npm run build addon-tablebars + diff --git a/package.json b/package.json index 0f69c725cf03..f819a9a81590 100644 --- a/package.json +++ b/package.json @@ -19,21 +19,12 @@ "clear": "prettier --write '**/projects/**/*.{js,ts,html,md,less,json}' && tslint '**/projects/**/*.ts' --fix", "typecheck": "tsc --noEmit --skipLibCheck", "*** build **": "use package=name command to build a package", - "build": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng run $package:build --configuration=production", - "build:cdk": "package=cdk npm run build", - "build:core": "package=core npm run build", - "build:kit": "package=kit npm run build", - "build:addon-charts": "package=addon-charts npm run build", - "build:addon-commerce": "package=addon-commerce npm run build", - "build:addon-doc": "package=addon-doc npm run build", - "build:addon-mobile": "package=addon-mobile npm run build", - "build:addon-table": "package=addon-table npm run build", - "build:addon-tablebars": "package=addon-tablebars npm run build", + "build": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng build --configuration=production", "build:tools": "ng build cypress-testing && ng build testing", "*** Icons ***": "", "compile:icons": "ts-node --project ./tsconfig.compiler.json scripts/compileIcons.ts", "prebuild:icons": "npm run compile:icons projects/icons", - "build:icons": "ng run icons:build", + "build:icons": "ng run icons:build --configuration=production", "postbuild:icons": "node projects/icons/scripts/copy-icons.js", "*** Release ***": "", "release": "standard-version", diff --git a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts index 7257fd72ef8f..9b5f225ae42c 100644 --- a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts +++ b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts @@ -24,6 +24,10 @@ import { tuiIconVisa, } from '@taiga-ui/addon-commerce/icons'; import {TuiCard} from '@taiga-ui/addon-commerce/interfaces'; +import { + TUI_CARD_EXPIRY_TEXTS, + TUI_CARD_NUMBER_TEXTS, +} from '@taiga-ui/addon-commerce/tokens'; import { getPaymentSystem, isCardLengthValid, @@ -161,6 +165,8 @@ export class TuiInputCardGroupedComponent @Optional() @Inject(TuiModeDirective) private readonly modeDirective: TuiModeDirective | null, + @Inject(TUI_CARD_NUMBER_TEXTS) readonly cardNumberTexts: [string, string], + @Inject(TUI_CARD_EXPIRY_TEXTS) readonly cardExpiryTexts: [string, string], ) { super(control, changeDetectorRef); diff --git a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.template.html b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.template.html index f55710d658ff..af4f7a3d7a6b 100644 --- a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.template.html +++ b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.template.html @@ -24,8 +24,7 @@ class="placeholder" [class.placeholder_raised]="placeholderRaised" > - - {{isMobile ? 'Номер' : 'Номер карты'}} + {{isMobile ? cardNumberTexts[0] : cardNumberTexts[1]}} ( + `nubmer and card number i18n`, + { + factory: () => ['Number', 'Card number'], + }, +); + +export const TUI_CARD_EXPIRY_TEXTS = new InjectionToken<[string, string]>( + `Expiry and card expiry i18n`, + { + factory: () => ['Expiry', 'Card expiry'], + }, +); diff --git a/projects/addon-commerce/tokens/index.ts b/projects/addon-commerce/tokens/index.ts new file mode 100644 index 000000000000..e82230f1bf13 --- /dev/null +++ b/projects/addon-commerce/tokens/index.ts @@ -0,0 +1 @@ +export * from './i18n'; diff --git a/projects/addon-commerce/tokens/package.json b/projects/addon-commerce/tokens/package.json new file mode 100644 index 000000000000..289d2d373a50 --- /dev/null +++ b/projects/addon-commerce/tokens/package.json @@ -0,0 +1,7 @@ +{ + "ngPackage": { + "lib": { + "entryFile": "index.ts" + } + } +} diff --git a/projects/addon-commerce/validators/luhn.validator.ts b/projects/addon-commerce/validators/luhn.validator.ts index 5d09be2d84bc..b6ae70f1c4f0 100644 --- a/projects/addon-commerce/validators/luhn.validator.ts +++ b/projects/addon-commerce/validators/luhn.validator.ts @@ -4,12 +4,7 @@ import {TuiValidationError} from '@taiga-ui/cdk'; import {TUI_NON_DIGITS_REGEXP} from '@taiga-ui/core'; import {PolymorpheusContent} from '@tinkoff/ng-polymorpheus'; -// TODO: i18n -const error = 'Неверный формат карты'; - -export function tuiCreateLuhnValidator( - message: PolymorpheusContent = error, -): ValidatorFn { +export function tuiCreateLuhnValidator(message: PolymorpheusContent): ValidatorFn { return ({value}: AbstractControl) => { const cardNumber = String(value).replace(TUI_NON_DIGITS_REGEXP, ''); diff --git a/projects/addon-commerce/validators/test/luhn.validator.spec.ts b/projects/addon-commerce/validators/test/luhn.validator.spec.ts index 1dea45db506c..0f02f5de54df 100644 --- a/projects/addon-commerce/validators/test/luhn.validator.spec.ts +++ b/projects/addon-commerce/validators/test/luhn.validator.spec.ts @@ -3,9 +3,8 @@ import {TuiValidationError} from '@taiga-ui/cdk'; import {tuiCreateLuhnValidator} from '../luhn.validator'; describe('tuiCreateLuhnValidator', () => { - const control = new FormControl('', tuiCreateLuhnValidator()); - const controlCustom = new FormControl('', tuiCreateLuhnValidator('ошибка')); - const error = {luhn: new TuiValidationError('Неверный формат карты')}; + const control = new FormControl('', tuiCreateLuhnValidator('error')); + const error = {luhn: new TuiValidationError('error')}; it('Валидный номер карты валиден, проверка 1', () => { control.setValue('4111 1111 1111 1111'); @@ -48,11 +47,4 @@ describe('tuiCreateLuhnValidator', () => { expect(control.errors).toEqual(error); }); - - it('Кастомный текст ошибки', () => { - controlCustom.setValue('2345 7823 4095 8723'); - controlCustom.updateValueAndValidity(); - - expect(controlCustom.errors).toEqual({luhn: new TuiValidationError('ошибка')}); - }); }); diff --git a/projects/addon-editor/components/color-selector/color-selector.component.ts b/projects/addon-editor/components/color-selector/color-selector.component.ts index b9deb12dbdf0..a22cff71fd68 100644 --- a/projects/addon-editor/components/color-selector/color-selector.component.ts +++ b/projects/addon-editor/components/color-selector/color-selector.component.ts @@ -7,6 +7,7 @@ import { Output, } from '@angular/core'; import {DomSanitizer, SafeStyle} from '@angular/platform-browser'; +import {TUI_EDITOR_COLOR_SELECTOR_MODE_NAMES} from '@taiga-ui/addon-editor/tokens'; import {TuiGradientDirection} from '@taiga-ui/addon-editor/types'; import {getGradientData, parseColor, parseGradient} from '@taiga-ui/addon-editor/utils'; import {tuiDefaultProp, tuiPure, tuiRequiredSetter} from '@taiga-ui/cdk'; @@ -29,6 +30,7 @@ const ICONS: Record = { 'to top': 'tuiIconArrowLongUp', }; +// @dynamic @Component({ selector: 'tui-color-selector', templateUrl: './color-selector.template.html', @@ -52,9 +54,6 @@ export class TuiColorSelectorComponent { color: [number, number, number, number] = [0, 0, 0, 1]; - // TODO: i18n - readonly modes = ['Сплошной цвет', 'Градиент']; - currentMode = this.modes[0]; readonly buttons: ReadonlyArray = [ @@ -74,7 +73,10 @@ export class TuiColorSelectorComponent { private direction: TuiGradientDirection = 'to bottom'; - constructor(@Inject(DomSanitizer) private readonly sanitizer: DomSanitizer) {} + constructor( + @Inject(DomSanitizer) private readonly sanitizer: DomSanitizer, + @Inject(TUI_EDITOR_COLOR_SELECTOR_MODE_NAMES) readonly modes: [string, string], + ) {} get palette(): Map { return this.filterPalette(this.colors, this.isGradient); diff --git a/projects/addon-editor/components/toolbar/toolbar.component.ts b/projects/addon-editor/components/toolbar/toolbar.component.ts index 804b27762b36..79498c10ea01 100644 --- a/projects/addon-editor/components/toolbar/toolbar.component.ts +++ b/projects/addon-editor/components/toolbar/toolbar.component.ts @@ -18,7 +18,11 @@ import {USER_AGENT} from '@ng-web-apis/common'; import {defaultEditorTools} from '@taiga-ui/addon-editor/constants'; import {TuiEditorTool} from '@taiga-ui/addon-editor/enums'; import {TuiEditorFontOption} from '@taiga-ui/addon-editor/interfaces'; -import {TUI_IMAGE_LOADER} from '@taiga-ui/addon-editor/tokens'; +import { + EditorToolbarTexts, + TUI_EDITOR_TOOLBAR_TEXTS, + TUI_IMAGE_LOADER, +} from '@taiga-ui/addon-editor/tokens'; import {isSelectionIn, tuiInsertHtml} from '@taiga-ui/addon-editor/utils'; import { EMPTY_QUERY, @@ -36,10 +40,9 @@ import { TuiButtonComponent, TuiHostedDropdownComponent, } from '@taiga-ui/core'; -import {LEFT_ALIGNED_DROPDOWN_CONTROLLER_PROVIDER} from '@taiga-ui/kit/providers'; +import {LEFT_ALIGNED_DROPDOWN_CONTROLLER_PROVIDER} from '@taiga-ui/kit'; import {merge, Observable} from 'rxjs'; import {take, takeUntil} from 'rxjs/operators'; -import {TUI_CANCEL_WORD} from '../../../kit'; const DEFAULT_FONT = 'haas, helvetica, arial, sans-serif'; const MONOSPACE_FONT = 'Courier'; @@ -145,7 +148,8 @@ export class TuiToolbarComponent { @Inject(TUI_IMAGE_LOADER) private readonly imageLoader: TuiHandler>, @Inject(USER_AGENT) private readonly userAgent: string, - @Inject(TUI_CANCEL_WORD) readonly cancelWord: string, + @Inject(TUI_EDITOR_TOOLBAR_TEXTS) + readonly texts: Record, ) { this.documentRef = shadowRootRef || documentRef; diff --git a/projects/addon-editor/components/toolbar/toolbar.template.html b/projects/addon-editor/components/toolbar/toolbar.template.html index c96f8e0b4a42..3f817cd3cae1 100644 --- a/projects/addon-editor/components/toolbar/toolbar.template.html +++ b/projects/addon-editor/components/toolbar/toolbar.template.html @@ -12,7 +12,7 @@ class="button button_margin" appearance="icon" tuiHintDirection="top-left" - [tuiHint]="cancelWord" + [tuiHint]="texts.undo" [tuiHintId]="undoBtn.id" [tuiDescribedBy]="undoBtn.id" [disabled]="undoDisabled" @@ -31,7 +31,7 @@ class="button button_margin" appearance="icon" tuiHintDirection="top-left" - tuiHint="Повторить" + [tuiHint]="texts.redo" [tuiHintId]="redoBtn.id" [tuiDescribedBy]="redoBtn.id" [disabled]="redoDisabled" @@ -53,7 +53,7 @@ class="button" icon="tuiIconToolbarFont" tuiHintDirection="top-left" - tuiHint="Шрифт" + [tuiHint]="texts.font" [tuiHintId]="fontsBtn.id" [tuiDescribedBy]="fontsBtn.id" [pseudoPressed]="fonts.open" @@ -94,7 +94,7 @@ appearance="icon" class="button" tuiHintDirection="top-left" - tuiHint="Стиль шрифта" + [tuiHint]="texts.fontStyle" [tuiHintId]="formatBtn.id" [tuiDescribedBy]="formatBtn.id" [pseudoPressed]="format.open || bold || italic || underline || strikeThrough" @@ -109,10 +109,10 @@ tuiIconButton type="button" size="s" - tuiHint="Полужирный" icon="tuiIconToolbarBold" appearance="icon" class="button button_margin" + [tuiHint]="texts.bold" [pseudoPressed]="bold" (click)="toggleBold()" > @@ -121,10 +121,10 @@ tuiIconButton type="button" size="s" - tuiHint="Курсив" icon="tuiIconToolbarItalic" appearance="icon" class="button button_margin" + [tuiHint]="texts.italic" [pseudoPressed]="italic" (click)="toggleItalic()" > @@ -133,10 +133,10 @@ tuiIconButton type="button" size="s" - tuiHint="Подчеркнутый" icon="tuiIconToolbarUnderline" appearance="icon" class="button button_margin" + [tuiHint]="texts.underline" [pseudoPressed]="underline" (click)="toggleUnderline()" > @@ -145,10 +145,10 @@ tuiIconButton type="button" size="s" - tuiHint="Зачеркнутый" icon="tuiIconToolbarStrikeThrough" appearance="icon" class="button button_margin" + [tuiHint]="texts.strikeThrough" [pseudoPressed]="strikeThrough" (click)="toggleStrikeThrough()" > @@ -172,7 +172,7 @@ appearance="icon" class="button" tuiHintDirection="top-left" - tuiHint="Выравнивание" + [tuiHint]="texts.justify" [tuiHintId]="alignBtn.id" [tuiDescribedBy]="alignBtn.id" [pseudoPressed]="align.open" @@ -186,40 +186,40 @@ tuiIconButton type="button" size="s" - tuiHint="Выровнять текст по левому краю" icon="tuiIconToolbarJustifyLeft" class="button button_margin" appearance="icon" + [tuiHint]="texts.justifyLeft" (click)="onAlign('justifyLeft')" > @@ -242,7 +242,7 @@ class="button" appearance="icon" tuiHintDirection="top-left" - tuiHint="Списки" + [tuiHint]="texts.list" [tuiHintId]="listBtn.id" [tuiDescribedBy]="listBtn.id" [pseudoPressed]="list.open || unorderedList || orderedList" @@ -256,10 +256,10 @@ tuiIconButton type="button" size="s" - tuiHint="Маркированный список" icon="tuiIconToolbarUL" appearance="icon" class="button button_margin" + [tuiHint]="texts.unorderedList" [pseudoPressed]="unorderedList" (click)="toggleUnorderedList()" > @@ -267,10 +267,10 @@ tuiIconButton type="button" size="s" - tuiHint="Нумерованный список" icon="tuiIconToolbarOL" appearance="icon" class="button button_margin" + [tuiHint]="texts.orderedList" [pseudoPressed]="orderedList" (click)="toggleOrderedList()" > @@ -278,10 +278,10 @@ tuiIconButton type="button" size="s" - tuiHint="Уменьшить отступ" icon="tuiIconToolbarIndent" class="button button_margin" appearance="icon" + [tuiHint]="texts.indent" [disabled]="!unorderedList && !orderedList" (click)="indent()" > @@ -289,10 +289,10 @@ tuiIconButton type="button" size="s" - tuiHint="Увеличить отступ" icon="tuiIconToolbarOutdent" class="button button_margin" appearance="icon" + [tuiHint]="texts.outdent" [disabled]="!unorderedList && !orderedList" (click)="outdent()" > @@ -310,7 +310,7 @@ appearance="icon" class="button button_margin" tuiHintDirection="top-left" - tuiHint="Цитата" + [tuiHint]="texts.quote" [tuiHintId]="quoteBtn.id" [tuiDescribedBy]="quoteBtn.id" [pseudoPressed]="blockquote" @@ -337,7 +337,7 @@ appearance="icon" class="button" tuiHintDirection="top-left" - tuiHint="Ссылка" + [tuiHint]="texts.link" [tuiHintId]="linkBtn.id" [tuiDescribedBy]="linkBtn.id" [pseudoPressed]="link.open || a" @@ -365,7 +365,7 @@ class="button button_margin" appearance="icon" tuiHintDirection="top-left" - tuiHint="Вставить файл" + [tuiHint]="texts.attach" [tuiHintId]="attachBtn.id" [tuiDescribedBy]="attachBtn.id" [focusable]="false" @@ -389,7 +389,7 @@ appearance="icon" class="button button_margin" tuiHintDirection="top-left" - tuiHint="Подстрочный" + [tuiHint]="texts.subscript" [tuiHintId]="subBtn.id" [tuiDescribedBy]="subBtn.id" [pseudoPressed]="subscript" @@ -409,7 +409,7 @@ appearance="icon" class="button button_margin" tuiHintDirection="top-left" - tuiHint="Надстрочный" + [tuiHint]="texts.superscript" [tuiHintId]="supBtn.id" [tuiDescribedBy]="supBtn.id" [pseudoPressed]="superscript" @@ -423,6 +423,7 @@ *ngIf="enabled(TuiEditorTool.Color) || enabled(TuiEditorTool.Hilite)" class="block" > + ( + `tui-color-selector i18n`, + { + factory: () => ['Solid color', 'Gradient'], + }, +); + +export type EditorToolbarTexts = + | TuiEditorTool + | 'redo' + | 'font' + | 'fontStyle' + | 'justifyLeft' + | 'justifyCenter' + | 'justifyRight' + | 'justifyFull' + | 'unorderedList' + | 'orderedList' + | 'indent' + | 'outdent' + | 'backColor'; + +export const TUI_EDITOR_TOOLBAR_TEXTS = new InjectionToken< + Record +>(`tui-color-selector i18n`, { + factory: () => ({ + undo: 'Undo', + redo: 'Redo', + font: 'Font', + fontStyle: 'Font style', + fontSize: 'fontSize', + bold: 'Bold', + italic: 'Italic', + underline: 'Underline', + strikeThrough: 'Strike Through', + justify: 'Justify', + justifyLeft: 'Justify left', + justifyCenter: 'Justify center', + justifyRight: 'Justify right', + justifyFull: 'Justify full', + list: 'List', + indent: 'Indent', + outdent: 'Outdent', + unorderedList: 'Unordered list', + orderedList: 'Ordered list', + quote: 'Quote', + foreColor: 'Color', + backColor: 'Background color', + hiliteColor: 'hiliteColor', + clear: 'Clear', + link: 'Link', + attach: 'Attach file', + tex: 'Insert TeX', + code: 'Code', + image: 'Insert image', + insertHorizontalRule: 'Insert horizontal rule', + superscript: 'Superscript', + subscript: 'Subscript', + }), +}); diff --git a/projects/addon-editor/tokens/index.ts b/projects/addon-editor/tokens/index.ts index 6f4736ac8c28..fa33b072125e 100644 --- a/projects/addon-editor/tokens/index.ts +++ b/projects/addon-editor/tokens/index.ts @@ -1,2 +1,3 @@ +export * from './i18n'; export * from './image-loader'; export * from './editor-styles'; diff --git a/projects/addon-table/components/reorder/reorder.component.ts b/projects/addon-table/components/reorder/reorder.component.ts index 6e5de1140294..aec119e32b8f 100644 --- a/projects/addon-table/components/reorder/reorder.component.ts +++ b/projects/addon-table/components/reorder/reorder.component.ts @@ -1,5 +1,6 @@ import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop'; -import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {Component, EventEmitter, Inject, Input, Output} from '@angular/core'; +import {TUI_TABLE_SHOW_HIDE_MESSAGE} from '@taiga-ui/addon-table/tokens'; import {tuiDefaultProp} from '@taiga-ui/cdk'; @Component({ @@ -22,6 +23,8 @@ export class TuiReorderComponent { @Output() readonly enabledChange = new EventEmitter>(); + constructor(@Inject(TUI_TABLE_SHOW_HIDE_MESSAGE) readonly showHideText: string) {} + isEnabled(item: T): boolean { return this.enabled.indexOf(item) !== -1; } diff --git a/projects/addon-table/components/reorder/reorder.template.html b/projects/addon-table/components/reorder/reorder.template.html index 129f3e1befe8..19bcba54d43d 100644 --- a/projects/addon-table/components/reorder/reorder.template.html +++ b/projects/addon-table/components/reorder/reorder.template.html @@ -2,14 +2,13 @@
{{item}} - diff --git a/projects/addon-table/components/table-pagination/table-pagination.component.ts b/projects/addon-table/components/table-pagination/table-pagination.component.ts index 0b99bb1f35cc..52313b8b4b10 100644 --- a/projects/addon-table/components/table-pagination/table-pagination.component.ts +++ b/projects/addon-table/components/table-pagination/table-pagination.component.ts @@ -1,6 +1,9 @@ -import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {Component, EventEmitter, Inject, Input, Output} from '@angular/core'; +import {TUI_TABLE_PAGINATION_TEXTS} from '@taiga-ui/addon-table/tokens'; import {tuiDefaultProp} from '@taiga-ui/cdk'; +import {TUI_SPIN_TEXTS} from '@taiga-ui/core'; +// @dynamic @Component({ selector: 'tui-table-pagination', templateUrl: './table-pagination.template.html', @@ -31,6 +34,12 @@ export class TuiTablePaginationComponent { open = false; + constructor( + @Inject(TUI_SPIN_TEXTS) readonly spinTexts: [string, string], + @Inject(TUI_TABLE_PAGINATION_TEXTS) + readonly texts: Record<'pages' | 'linesPerPage' | 'of', string>, + ) {} + get pages(): number { return Math.ceil(this.total / this.size); } diff --git a/projects/addon-table/components/table-pagination/table-pagination.template.html b/projects/addon-table/components/table-pagination/table-pagination.template.html index 60e0b1b869ca..9556bdce37b9 100644 --- a/projects/addon-table/components/table-pagination/table-pagination.template.html +++ b/projects/addon-table/components/table-pagination/table-pagination.template.html @@ -1,7 +1,8 @@ - -Страниц: {{pages}} +{{texts.pages}} {{pages}} - Строк на страницу + {{texts.linesPerPage}} diff --git a/projects/addon-table/index.ts b/projects/addon-table/index.ts index d255ad2c24e2..04360124fcda 100644 --- a/projects/addon-table/index.ts +++ b/projects/addon-table/index.ts @@ -1 +1,2 @@ export * from '@taiga-ui/addon-table/components'; +export * from '@taiga-ui/addon-table/tokens'; diff --git a/projects/addon-table/tokens/i18n.ts b/projects/addon-table/tokens/i18n.ts new file mode 100644 index 000000000000..b52db802f069 --- /dev/null +++ b/projects/addon-table/tokens/i18n.ts @@ -0,0 +1,18 @@ +import {InjectionToken} from '@angular/core'; + +export const TUI_TABLE_SHOW_HIDE_MESSAGE = new InjectionToken( + `tui-reorder i18n button`, + { + factory: () => 'Show/hide', + }, +); + +export const TUI_TABLE_PAGINATION_TEXTS = new InjectionToken< + Record<'pages' | 'linesPerPage' | 'of', string> +>('tui-table-pagination i18n texts', { + factory: () => ({ + pages: 'Pages', + linesPerPage: 'Lines per page', + of: 'of', + }), +}); diff --git a/projects/addon-table/tokens/index.ts b/projects/addon-table/tokens/index.ts new file mode 100644 index 000000000000..e82230f1bf13 --- /dev/null +++ b/projects/addon-table/tokens/index.ts @@ -0,0 +1 @@ +export * from './i18n'; diff --git a/projects/addon-table/tokens/package.json b/projects/addon-table/tokens/package.json new file mode 100644 index 000000000000..289d2d373a50 --- /dev/null +++ b/projects/addon-table/tokens/package.json @@ -0,0 +1,7 @@ +{ + "ngPackage": { + "lib": { + "entryFile": "index.ts" + } + } +} diff --git a/projects/addon-tablebars/components/table-bars-host/table-bars-host.component.ts b/projects/addon-tablebars/components/table-bars-host/table-bars-host.component.ts index 548ae892a42d..c645c46befac 100644 --- a/projects/addon-tablebars/components/table-bars-host/table-bars-host.component.ts +++ b/projects/addon-tablebars/components/table-bars-host/table-bars-host.component.ts @@ -1,6 +1,6 @@ import {ChangeDetectionStrategy, Component, Inject} from '@angular/core'; import {TuiContextWithImplicit} from '@taiga-ui/cdk'; -import {TuiBrightness, tuiSlideInTop} from '@taiga-ui/core'; +import {TUI_CLOSE_WORD, TuiBrightness, tuiSlideInTop} from '@taiga-ui/core'; import {BehaviorSubject, Subscription} from 'rxjs'; import {TableBar} from '../../classes/table-bar'; import {TuiTableBarsService} from '../../services/table-bars.service'; @@ -19,7 +19,10 @@ export class TuiTableBarsHostComponent { private readonly subscription: Subscription; - constructor(@Inject(TuiTableBarsService) service: TuiTableBarsService) { + constructor( + @Inject(TuiTableBarsService) service: TuiTableBarsService, + @Inject(TUI_CLOSE_WORD) readonly closeWord: string, + ) { this.subscription = service.open$.subscribe(item => { this.addItem(item); }); diff --git a/projects/addon-tablebars/components/table-bars-host/table-bars-host.template.html b/projects/addon-tablebars/components/table-bars-host/table-bars-host.template.html index 4b569d86bd95..3ca76e832574 100644 --- a/projects/addon-tablebars/components/table-bars-host/table-bars-host.template.html +++ b/projects/addon-tablebars/components/table-bars-host/table-bars-host.template.html @@ -17,18 +17,17 @@ [context]="getItemContext(item)" > -
diff --git a/projects/core/components/data-list/data-list.component.ts b/projects/core/components/data-list/data-list.component.ts index 30fa2453e46d..9bc785c8eb7e 100644 --- a/projects/core/components/data-list/data-list.component.ts +++ b/projects/core/components/data-list/data-list.component.ts @@ -22,7 +22,7 @@ import { tuiPure, } from '@taiga-ui/cdk'; import {TuiDataListAccessor} from '@taiga-ui/core/interfaces'; -import {TUI_DATA_LIST_ACCESSOR} from '@taiga-ui/core/tokens'; +import {TUI_DATA_LIST_ACCESSOR, TUI_NOTHING_FOUND_MESSAGE} from '@taiga-ui/core/tokens'; import {TuiDataListRole} from '@taiga-ui/core/types'; import {PolymorpheusContent} from '@tinkoff/ng-polymorpheus'; import {Observable} from 'rxjs'; @@ -50,10 +50,9 @@ export class TuiDataListComponent implements TuiDataListAccessor { @tuiDefaultProp() role: TuiDataListRole = 'listbox'; - // TODO i18n @Input() @tuiDefaultProp() - emptyContent: PolymorpheusContent = 'Ничего не найдено'; + emptyContent: PolymorpheusContent = this.defaultEmptyContent; @ContentChildren(forwardRef(() => TuiOptionComponent), {descendants: true}) private readonly options: QueryList> = EMPTY_QUERY; @@ -62,6 +61,7 @@ export class TuiDataListComponent implements TuiDataListAccessor { constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, + @Inject(TUI_NOTHING_FOUND_MESSAGE) private readonly defaultEmptyContent: string, ) {} @tuiPure diff --git a/projects/core/tokens/i18n.ts b/projects/core/tokens/i18n.ts index 6f364d8ec5c2..c903dae2fd88 100644 --- a/projects/core/tokens/i18n.ts +++ b/projects/core/tokens/i18n.ts @@ -4,6 +4,13 @@ export const TUI_CLOSE_WORD = new InjectionToken(`i18n 'close' word`, { factory: () => 'Close', }); +export const TUI_NOTHING_FOUND_MESSAGE = new InjectionToken( + `i18n 'Nothing found' message`, + { + factory: () => 'Nothing found', + }, +); + export const TUI_DEFAULT_ERROR_MESSAGE = new InjectionToken( `i18n of error message`, { diff --git a/projects/demo/src/assets/android-chrome-192x192.png b/projects/demo/src/assets/android-chrome-192x192.png index c7fdbb292a1e146b2f8c1b4c2daa25e668abb031..c9993a8b8edbf79f56b5be741fe5fd1ee261b32c 100644 GIT binary patch literal 3564 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 Q=Kuw?jpSrqX6Y0EH;hM`{Qv*} literal 2799 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 KelF{r5}E*F)=i}V literal 6066 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 diff --git a/projects/demo/src/assets/apple-touch-icon.png b/projects/demo/src/assets/apple-touch-icon.png index 1179c13e4b983841e00e4aebf634b0b9410cb2dc..dafbbae41a5bfc6bfe9b55335a8b598ebc6e486b 100644 GIT binary patch delta 1810 zcmZuvdo&b?7gl+V5ffRv+d7Drq4J2#qSRuok?|UjSnq05s*y)S7?T-~T7xx`S5}Pi zNKp|A86v4Q9);1+cqC%Xnph(DH~#(Y-t+zQo$r3%z2}}wQ4}d=1dwkzpTOIKxHdQ8 z%PRc601t9uX#rZRAlwdSCxGS$L~Ho^749+MT_0R^h1C@(jE7fGA;KPn^FTibPnZy9 z10TlVnh$KOLj@g%dm!2g{`m~K(a=>7f?2qJ2I`AoVg$&Zu>J*@DKOXxSICaAyad@1 z&`}GQe}PZakP-yrZy*j2#fiXagD5PB79sN@RA<3e7ih16tT4!pf%zGTb%VOwkRA&C z?aPDoFax(p@VXgFlc6*P5`AEr2Z_HyTQ#)ZgB20f-v&lFBnQIWB>Z^|_`^W;g{lm= z`v+8I!oz$JeuCCYNIeDDPs1n&n5nS71~c!0<`12ZpojuZr9e3elU$&9!?U{(=MKC9 zAdd|~V+jnuf(Lm(KM#v@Kyrln50DZJLoZ?AdD!DcPYDT$Z9xupHWDdPYQKt!OoY9o zt<04C4ixf-xSSjV2?@z%dz<5U5_ch=;IDifmE4%3y}#4hDKSB6cSZnGZf}70VLU#x zynMLrpzaEN`n-OM=4nC{PH>UD^4xN9_4JvwnS>{WIu0juHDs^-3%CwG{e7YPbXB7k ziM7|eO|9)vE!O?JNd3eSO;1 zI(9@Z&lxO7zH|9#(%?|clNRWndRy%YUafQsvV7*L67MpjZnfmjq_U?R$2|>`8D}rL ztUWRbm$_48}jpf4Pet zvdEzd&d$(j{f)k}!(-iQ@+JDrorQA~3Q3%1>)DaM*J?XE(4MI2w___&g6-Ce+-^0p zg2n@%ws|_SYv7?y8Wp$5r?Z%Z`|RP-b~R@^+Kr^B3%hZ(SXyu~v69O=F|1QC(cH;t zu1B!;F{#1%L~mCt<|cww;L5Ibz?e3aay$?$OR7ULnSlP2~YCu2ewN^~iOB)?76|xKp<~uz_kTcA(eE2G0ADstds=T#BoCthQ(5l%dyi zjRGY*{&`a9i1t2u`)NCCRh*VkbZ^1NkCΠQNt{aKQ>HuDx^<9{DkpPt|4i4M=6P z?D&sW?}^v!&wXfHN9awcE0$wTeY-IeDTsCXdo7$8c5BP0dhjOR|EYvWvTi}10R`Pp zp3M6aMhcEZn`{O3G#wyJ$$6>gZRNZ{T)MwJ=xw7eg6eLS9 z`d(^Jr+W8`k193dDP-5TCL$hX{89}Y;en0T`bN?+MoO<>@0GS2k?$-mG)snf5;Wzz z4BS|ciVBqHw6@65{kF;J*r0hudGR$b2HWjyeIpfFn=K|sBGu;=ahM}zv7uJKZ6vh+ z?x^rj*s)wACS%fmcA;t=UA*XQ$WA3`;6}>H< zLk6m~Qn!+ZE>USMai#`SS;RX9u6ex~H($QW&snm=xZu!^0~c$$Lqx7Evf@KcldvkP z;|NiLI=iB0W5aR43iX3o?~bDz4!-lrPHWt=S2kmGMbFYzocz-I7~9M&J_R<9+&%AY z$ZhE7SdnvIJc?Vtu7CYO+i|VhWjQuraT%Nod4mqpx{0 z$X74c7%F`%l~G6h#*wx}rPXR|O;odF!YG<>zoY+l&v~D7o%7uH^<39=pL755XiScn zh++gu!P}WzL3ds}gO`6m)K++i8g1lt7a~t})U|}A(Oh^g`?MG;-hf6=hqza+~ zfVBXebBK5r_#Az_c3LFGKq!$czW&D7;WWVixdvKz|?R!I7z|Pf^={FfY6# zagY&Y{=R3Lj-55AaP)Om)%%l4W@qSH%{3S2^48m}A7m|~nv3(pkx2uau2r5}@|tW2 z$+tK78}y#aZS67H^HXn5#q6wb@3QT#OqC4zs7=e5Hi8jc?t%f|$m0~b-$`v1#@z7S zn3a+5acu3AiGLAg1rfZ7bjP`hQ4O1w7Pd5I!(ZooZQ}bkGP!B|9_7KyK88Y7iw;sz7b;mj7mb{%n=2qHd8JDp9;NekGsEJUz%) zr`|yY4W*X0imUeX>g+;wPM59GOmLRwn1@wuP{qOfw*9omXI353a*ygFFZOFJA6dP$ z(?_*`KsJ`;QfpeEnA!5XhrZwb8gm94H&)LhhaYYyR$nhQ>-AKo4{d7AMoCgJ!VWpEBF<8^$pa*pE7NmdS7eB*MNw~CIHld83=IIqna z!KBy);bX(IlZ2f27NMMr;=)k5itVV>FMZUmO}AiVvf^d~waCi5j@#{IRjt?QubI30|kESq^57<}Y(T zH~pmo@j%^dgAmW8PuT@ceEJWYM$=`Ev*T(90t1k41I;-H&2>AM#M+RF=;^nSDt*sD z11VM8oa;=@4cIYbNNf_X`__nMaa=Wwzsbv|H{W~uj~0dk#ddzAaD_J%2an=!?K?2a z?muxV?}4si()Y$pS|y$gMSLV}L%3`~RJnIbHHu|@Oyx(q;8kVT&kJ>;ugl!seuGl~hPW|sTWwVG7HbBLWT9a9cSR-Jpjfixa*tnU zzROF~6`j)78Ilyz=(_(^9vC+*U+ojSv%+bGCw8!-KP@bHa*uhvW9J z0-*MAK;`doK?xZxP5c9;3hNeLeF}*^98@V_-yQt{M?CI8xNNw$Qei7uc_=mdsW;BM z9?zI_Ae>eX4zAhgtc<@ZX^Tbb3vzs!Xi=wRe6!8^<9bB_$io|ABY9n&35|-9Y!4yS zIlUrZ9M`<4dcx!Otu_llK6);2Ty56R=IL89mQ6ZeE$sMeB_|(8 zL<>^F7O;-pNLS$^{`)8(@Z)e*Zx$v#lBmJpX%OpK{+T|vr)twNh|Jc zd?l;uNn;(VXPD~y`~{gL0S5VE)jCJT!q>XLjgY=IB0WAfo$bCam94ul&J<^ggOihk rvn$id&7GY diff --git a/projects/demo/src/assets/browserconfig.xml b/projects/demo/src/assets/browserconfig.xml index 5cd27e3f179e..5aecc916b9ee 100644 --- a/projects/demo/src/assets/browserconfig.xml +++ b/projects/demo/src/assets/browserconfig.xml @@ -3,7 +3,7 @@ - #603cba + #00aba9 diff --git a/projects/demo/src/assets/favicon-16x16.png b/projects/demo/src/assets/favicon-16x16.png index 12fcc5fc3563e82cd98eb93429eca1cac6e23246..e093555a3300533879bbec637c06838aebd4478d 100644 GIT binary patch delta 544 zcmbQi_JDOlLjAM=pAc6D28RCy&I5t!aohU;|FXq`(Lkpelmz(&Gcd4*N}a9#r~6=* z+k5`)FOz@$&Xv2cjj{Q;wegd~b{q@7Cq#c*&Nc1e{sWuzc(^&ki*rPPdKr_v-CYcC z-j*!_a@b2eeO=j~@GuK-%hXPvt`8KdU*YNE7$R}mw>MkdDL};Ky$8RGVC*U7Q_4sF z{ExrxtN;1wnOoWGEuDNCmpPtc(h-{>{NnV|zMUJQ)`!=#-jGmAm4U&#aPPS& Z8glbfGSe#I8bmR4%;);7IC&*gJ^<=C?cD$X delta 557 zcmaFBI)iOOLjCFhpAc6D28REk_W#2i{(E}<548iKG-I%c?f*~*s7R>o|1i7%AwXFh zs7N@F0aO5150bV0?+erg;oALAfN2bO0ttrM!!!aJcK;)+!A8}?RKu+aaQGkS3{nvc zH{Bkj6lgb4@c(})ljvTcd(BIN{DK)=UD$75XDup}`1oFQ#&qMqfAn`h+Z7Vb^=QjI zj_Pm9->c-l)_s`sf6K+WXJ+s5nPrm|%x;$MRLnJPj_Fv~~3J`E{eq@|Nk488)_Xf;I}SL+q`q9Lm!vhwC<%vs=*;Aqh`J4-E`ASG`Gvj-fVZ& zmtXgj9HPW5|G0kexb`?@Poo#F{mpv7L&!HTXy=y6{7h2fhPph*rdD+Fui3O>8`9!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;%9(Qh%1o(U*P;d-|2q= z5IK(&^#8xb)r{#t&j*$S`2_=M2DUi4OHD>k*cbYI655;fTj?rOm&FUt6(L{$i5@BX zYo&ghk$K`VN&7b+{rz~>PiKw(eogh%kEE)V3j%fT-<|n0-Szz%!L1LCOa3&>n%(Gr zOe_;NbEZ2nPJAu+Eo-U3d7N@5MUoAUqAkw|9 zEH&-elO>vy>*qQZ{_qE^{7@#FWqQx@!_td24`Umq3A}yH z;jmoYWqtL_hJzj|61)|n2}Y;cHotUb(Ft=(-1?xh;p{n{vfGzAEatd0UjBH5VfySj z56d2IJn(q0#GZNWLO=dI;i{8=$IRroONi^DyFr0?V}Xn1qM|Dv65AOsN@({Vzp1hD zg)fVcXV?N!S6yvSwRJomOCt-^xKoVZ*v>t)RAKt^sE5)*bzD=P6h9Xd@y-d}spPq0 zilnyaLFQGatFB0Yl3NhCd`noU(uCZgg;(1&!aFjyueflgiM8a$oo9LL^`(F9T{m;? zN@e$&1cN8yHc}_r4t9Kg$T0tsPx3kSV6(#|ho){cF-6VJ&J5s#U9UO^{(&RX+; zwp(j-+n@q?UEvxW)DR@QgL9HKHUXu_V8f};Gi%$!t(lFEWqh0KDIWCn(cIgdZ_a1@4V zXq@stea7=?5CgL^w_Y;0u(GiCWD#az1(ybs!zs+ln?n>%-?(z($eANDN7zp{cr5VJ YV|XPlSn|oq6l4X1r>mdKI;Vst01{fn-~a#s delta 853 zcmZ3$v6o{)d_ALhfKP}k0|UeVP>26vw*MU*{)gIwQ7DKTV)sAP@_#6hwEG|6@IM47 zW&1za8Y&VBV}#j(q&z*L;%UYp6M))*WmhE_dg71l->V&pacj3`L_Rk zf!cs7fVP6=5@4D^N^PK0Km`#%Tftg@#sLilx-Zz~e*@4^ur81tKnBoy2m@#Q$rvGC+GJDScke9(+j}j8^aa8ZClKZOlS!z*x$3jkX zrZXqv*2k_|{jl|k@beaxA3na{73;z#(!G~wnfr9KMp1!W^Pq-xo^vt)!Tulb*k@s|Q46!)9cGC5zLk=P>;?*pz z8cF&dApuu3zO`|5HHkW&s{H@m;HIbFsp(JLo~M1EKU1Z8-x`7cYi|V9m)O}DS&2nT zsL$#+HPv%bh0-De*S2McKc}41Sz)}eHFA4HuU3%b<(Z;Z*PghNs zZ`daoaAK18>_p`tJ@x4!m*!_jSCmw-$Izxkr<|4<^& z)7UQT(7z*d=g;%>x1D}GR5d1M7guh0#S5tt=3S+qB+@RwU&H)z#*Uol-$n1+pK6dd z>0bR{*5^}FbKKu|w9WHbXKW{)`mnXPZBO6XaI25T#njE}zeJ;%)4LdF*M3a@%Ou5EnRDpBq2gqJW+`z)T_e*FLo+KAGb>Y5 zZ39Cq0|O(|*Iy?$FiY8Bk#o)n_5_BzWQl7;NpOBzNqJ&XDnogBxn5>oc5!lIL8@MU PQTpt6Hd2!}GUo#Te$I*J diff --git a/projects/demo/src/assets/favicon.ico b/projects/demo/src/assets/favicon.ico index 6790c25d0c3532d618849e6f75818eae01e7bda7..0a8fa66fa4028aaaab432457cc4b91b3398f3911 100644 GIT binary patch literal 15086 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 D&ad~f literal 15086 zcmeHNO{iN%6h1N4sE8?wATG=kD;B%3P_W2*ZGyIiidAcq*McZ@qunUzQn4?^-;F=$ zLdCjJH&rWcS{D{-1fgAY;X>-7_)L8de+tqRQ9~PZ{7#ZdC-=_WJ9qBA?V>NddFRg0 zIp4W+=T1((GeiX{((2U&IYs+!Bf5)-rlv;q1x4(ErNU2Ik>oU;lysi7zhn4l3N~ZM+KgbH27_>U_Vl#D%)At^dtfQ3c=9F!&*3I%RU;jnVWgVql zH@v>iPX^~+)oV3gR&DSPDefV19i?42@a_9XgNw>vldLs(2LAU`+`~STU1`JIeVW2< zAM0b$mtIeEd=Zg3oY+UHHE{R2_9OntC> z(9!lH?)4gzjkq?vZ;v@*$Q*8uv#0v;Ym*0-EC4HEScO2)VKeLV3#@Tb}m)O7&vp3V=H8z{l2Rl6{TeJL; z%}&yG;NA?(znyR!e3Y>6LKtX+{!vF8e@*Y;n?g2HGywN`M{LIX`BV@Jztx_0)yLT9 zg8FIeYqs#!!2iY3htqg(Zd90Z4ZYKjy7RT2e5KOOQsOx@VDmA@Tu+S|2eUpy~kmT;4I#A^vNZ*8IGy* zyJ4h!T1M~VnGEmYG@jE9`FLx#in!w0to+A2`-~YSzt+v0xdi`DWN;5Zu6cql&(Bl4 z<&@mrVBISY&5n|959Z&SyMykSL(A7oyY+AdjQHgI>|9Gbru=`?lj4(r~ZLrdp|zxH|V zE;Wbd??gIH;j5zftaR3ww3lWe{S5Hn1C}}P8Ne1*dm`IZ z=~9WPBN8VeI#k9V5gO4Y68exmkyVk1 z$WEbImb#K%qKed&>=9L^-Y1&VrCd*xChk<)lx!7;b-)eUmF$#QdFNB>hka##&=r-Hx2EP&hW}dIkgcKaQCrV$+b%QD-US+?Vce#C0g< zwZxVoeArwxofEltD_@Vk-y$$|TcMaWQ66HJKMT&k%%>yvNx=&0OI?rcg0^7)OOuYN zO~wZGRULiynDKmUrq9**+J#e-F$&8dV`Dz7#i(;8^Wa3TGTpPZjh^AW0axz9IqwM$ zC@Qb{stq5{?==fHgVS`*TgK!i&%(buf9iOMS;#y20L2K5=_j}BX~ z*(Yxp_da3{b}DqNxyNnTX!p+h0V67}_lNLvBaZHr4L@DpE;=uVdHn#md#%_RFDTDu|cBNNpSNp}*oD?oJhZKZR98!eh z5L!cu&>2#?m0=MYLnsU>+DCW_p(UnJ#yrI`R5Jcxe~_5^C%s_pZVkd9hJIKdGq^_V zZ24U<@tfT88*m)=!}f=;7mQW*D<9DJg`t11>JP@{@PD`JQ&QSA8=<%xeR^CyamHEB zJEMPmcG(m+8{*>e8Dr=k(6Fs>Z!oTv7}eCK?#U!E{*Z?CE3T!ex&7Ltqqhlvj`9C# zI!d=Uvz_nM$J(xqabbeE&k)xoj@$6O$8niY+@-};-f - + diff --git a/projects/demo/src/assets/mstile-144x144.png b/projects/demo/src/assets/mstile-144x144.png deleted file mode 100644 index 136a8b5c7965fc3575a8d354d0ac94c773239817..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2097 zcmZ`(X;f3!8oe0ifFScE4M7DVK*AtMAp}SYVKRi=Ktu*5Q9@-9144ulD%B(m6#+%6 z2$U)W5sZX&C*k3`%D=~~$#P})rfDce& zAfN$0KoRe)+$wK^g66*t)|oXP=mQiqf`R}-R2YU8bbpn7=em~yyrAT-i23|e+9v?I zgA$p%&hPh7h5-9|3)OhaN&MEC*fjtIpyaQJ1bWpN$*NDFgD#(xaiGQ8*MSzQdp#CR zr4j=p70jvX6$2*3tBwLFfeYlQVq=3;{MtOuN`Z11ydpYyT}J&B6$=hQWlZ=&)mN3U zCWeEQ7KLIebM_@T`lB3bR19Qc-qh&#(R)L`Of4~CQpy|=sEMk1&W4I)wx z7|qEIE6SZeEIV{v4dFh||LRE;7(;DecnGoJ zVHYY1Y_vG!NRrkR($dfkGF=XI0Y9<rH#YYzJJuLya$Kue%ohma4yk!#YDgwD zLZ?9Ra}&A^ExIhScB%`=H23Z2oVxkb%ZNWu5k>FjieUrXLPEI5tY| zq_qG(-|l0O0j3Ex~@(6DRa=MK+w7rX9}p6_KJz`Ks#uadvf z3QOv;X{o9iWO?uMMh>QUJg9k=+|c$EqbX0ZS)QA2{qa7MGkNhk0a4c1(C!!f!&33_ zklCr$?g4e?thyB|==F%qBRAG2b*27mf^o!eg>Un1{i-#%{~O6`2-|k&M;YB=syL$b zU=%!UVK(Yp-P z5{$%2?Bu|#EEMq)2RvvCe*JzF_;D-Es=CBULV+DN&uEBsqM422UkYkg_gjX*jY154 zxOET1K&%@H=xxZHj_8C?G!o9?UZnVV=<5a>FoIrtS^P9t&l$=rEyx#aMK2c#-ea1yeul_wxDLktTY?Xe8^sL@4356$$ z9OqKgG+kIi3~hKi`9a7awL@kK|4KrI|Wp0*1OkJbxkZyNfb3JfICDc@|QlS!7QjUfn4`SO)|GwQI}fV>@^(B|GuzPD6PTLrFT-BfNPeK;CH1jo8?^ z;4H#WhX0%BrkTDHraUUf^htE;WUL{hS$wlQQEzO?lxWuCRMcS(vK+yYJcX%wYSsZJ zj0SO&s$ML6WJ|@q^Uv!s7}MFjonb3C4WG|_Q#N-&>ftUS^u!OVzej#BUqFYWB}4J> z?K7AakGju z-9M&v5$8E^R&Kz5Te3yOD?o?mLH$FTfc!>AwT0R?mf-<9wT@z$?4w`K*K$!~gL^7h zBdta%xVF8ccKUO>8intmS}b;Xa1kAT6pFC4C``?--0Ba}6(y#Pg^!k74fsNYy@89f zq*?3Nq2h-pcDyLl+q4w^VA3bP`a<%{BxcIKefvJ9d{ncT`7HGzC+!mWuiMHY#c`N> zIV|6lY!+A`cdR?s1&4ES_oCr;_4ljfUzQ8Itw%_t^Ak_3=X+!dxM_`6kX{kXH?80g*{j#4AC`U;Q6M CQ=N$b diff --git a/projects/demo/src/assets/mstile-150x150.png b/projects/demo/src/assets/mstile-150x150.png index 3cfbc25d1e7a4ceb14a8bdbd50df2d84acb5ce64..af568dc21e63f7c82465ff505ba3165584c4d034 100644 GIT binary patch delta 2013 zcmV<32O{`^5tI^;83+Ub007dsF)ooIK7RlLVoOIv0RM-N%)bBt00(qQO+^Rf3B|Ls&EbWO+z z&D6bKi{qYVhOP;jpg}sUPaW2v&~+gLv{=uJ7RPff4qX?5Q=>W*r9+LOYeQh#px2Rq zi{rI6gsu%iX`-&FFV{3NbbSa$HELIX+Eo*}Mg*eSdf4ycc&OQ-YeW#L*D;lHRP~|j zL;zZ<&XS9xQ%ghFiPUMN&Xrsml5|cZL)VIwX^VPdEsh>-30*5vrOCP(YiUT*O-&A6 zFH)mg?TNiKBx#RoL)VOyXn`IjS{#pmv>BiG+GxDFAYh$pwXdgPh0gpJ7_httUfo(w1zGnWuU6+* zX-Lum@^HDOW<7CQ98bu@<X;VM<^Oq+{b=i%~yd`q?3l>eS!wpkteFp*fIOq+`w=izdC<rfV{r@|lOr<>D|cW>Kp1Eix^k4;isoXWCrk zG7p!>E5{nkOq+{YW=-hBMoF5kI}W#&_P4QjG(GgO`}%|zx$n2wIyD8 z-5>IBS>=>z`}<>#P2+UQdYmfC!&ML!^po{h`a<9I8f&>;SdYd2aM|OOX*;OFy~Y}> zgVtk_hszqLOxsOOEgElss>1_+@^IPWkZJ3V-jPY`)onQe+&4;Pk} zS!dd=Dpq&8Ch4l>44qmQ`utQehfLc`wZ@*M)nb>0cXFMF%edJ4v=uw1p|NKfs-u>( zus>WV4w<&Q$)11c3*EJxDaU!Z3`@LE+edG-HSug)^~Q2G_J>QKL#FMt5(l2tWZgcP z+dN!mS?$yI{>xf_Xf>mK`yl(nrORrcws+d?F7poUgX|BNCWlPhCHpo$eP-Q0n9Dp| zMroVn1F;uc?liA$``}w`3w_S2ghQt7lXk$wGY{5pmNVxt50^m>`?N*0116r`zI~AW z;mXfC)7Gu^Ugo!LAAF*8Ukg!v95QVu{G`z|%({J$JY0Eysm(Ie)=xWN;u_{ywhwlx zE%f=zF^#v(wDoAazo?N4+HU#4@3L&)01(80&;`V&f@!ndr|lopVLmTv+k0#77rIN# zInazT#h>diE396(Kf|EjMXs7wN=tyhLS@T`td5JlPnV-#q zqIY)4G@96dkNkVNZ(0hM(m7vMM1yq1?mn;&kM&ioc^B!i*LjbShx1NLJnz#M^BIfN zD;c6Z*OJiZGH0AJZBfo^Z0xzm>b%#v&m?adKtCKZZBd@->qN7+=$Xga$;0{NeV?}d z8klJQf!gnNe)4d>IAz+RTuJ`bXriuotzkELI4>N3GHp>hwbH7Jm0ov!A`j<-_kG$9 ztKO=PdL8mw2YEPm4w<$nH|!tVYpQN|tb{zAD~;4&9>0(-t#hhoox`gvi;;(O5Z^jH;nI2#U`wkQuY&s$~ltY0J-g*;qx4w<%MJ=)>56Ksda+hp=^ zNolk$di>XU*6$yU8mY4$tGh@ZE)nZYTa?HCH_1`6#}**+a7j4r(^kwfI^A!Dwc6#e zLh^8NIb_%6uA zdHNkD*R)lyyq$21ww^?_`fLGumHbU*<(9o4Z|lt=<0tl0FeeJP%2{gRmcBPjyj5$} zXHr$FcZam#%7cwm{GgL7)Ix#UiGcYSKF*-0XU{Af+lM)DT(nIli literal 2177 zcma)-2~bn#7RRq5ML;Zz6hsBuu%uEXfhr|nA`rl^1Oj2P2!d=P3KG&FVRb_hfg&gh zkyKq7XEgKkRz8?>8{A1MqUXxAME!Z0?zIw| z)sI#>v)RL{BW|~<8A(5N?)tfKLc{-F-J;RS6xNNu4u!Rtof&kktkOFg*HJJ=@x7aT zp{;gnQ1rIV{{+7lXx(8CH{$8sI+zFo6*|ewMP*WbtESbu!>fsW2vSxi5gn-~hor-+ z!BiLh^NB$y3lu7+-MY&fWnHgfQ)gmg!z}#H!`(V}w0?HAWuPxJ)ZF*0WtJ=@Ux>F! zntROYWyLY*2ZvWmcjyC)|8^~oytw&R&FRk}TJBqIC+p%U9+UI+_TYq`dm`EEP!|k0 zDwF>tRrgo@2Nq-b(&SVQN)sg{%*}_o=`$|X9`BrP8MRRTeK1|v%HTFX*Up-sZ3-EU zn@@(7B%-@3jlG>Mhzrj#<%78ss{ z@fI_;l{!OjCa3#x@2OGg5ATZKRu9+Lt@lpl2zp)|>t}3dcBF=oH^-bSUkWWLKpn_= z)f_lAKD`hnn*ReUYp}c4i!@O+gH55tTk>NyF49l~{QjHhWDt1e&?G{yxc$Z3cv4sA zii63FCk9$#v)las3uqn|z!zw#Qht9Hn#bvjH!%`3>&mX4EEXL~u+=W0xd^>HaDoQO zoa>*I+8_9_s&0*KOUbBlbn>Jt10_TUmXFjE*~7zmQr8N~-0mea`w;E@g zd?oIyB7A6Uz{;wyGG^=PGEy|JE+Xzs2jik6$)!JnIf|#=wyiUR?zpLZF~ijM zOmDnVf?>RCFKwjmkz76*myZLzmZRR+ldzUA z(Utc^fo?soEN^J*u=8lv{Ez?}tK6J^SGy}C51#q8YWbn^Xm7Y8o^H~^S6zjp#ePC5 zzq)%Yx0`|>8TvJ)dl}p`#wFw+&OHMQB@a2@X(6Sdt12JShMFOWqVmpF^V=+oOeZ>p zJi=HJE?+p*j{1iGEimUiJI}Jpbd99M6PquGOPsTLB?QxIbR~Y=J|eR>LF}FLt>Bie z@Zqv7B)~R(s{cpnT5K>;M0lA)n-ayhL`eyr8dp}i!IjChPMmEiI_80t@xom;X))!Y zQ8dbV(vcy$^IFD#f1ju=?&Xc(9xgoUG`)ym0dy*Dc|zN&1myM`sdu~|#pGMt>iA%y?h`L?u! z>+_MpZp_3SDDe1=(#I6tnW>rt%0cj|gIm~_>kLc6*u$z5>X_|USWEXe7>E~3Jf8t0 zNusKaz(2h^QUMvW4~qXTUJ1HSS?1*@39f>WORDV(--ie0d~KRL&e&89@GH z|DWs88@(;I#TjaI)TaP9rMm>tBg5%YxCmMlctF+|Ym6lpYiYfkirs_z-WG?!T41m^ z3?@9Ny7@l@#}guBqf`F3KvP*8nJ17*4Wj#oCmWxjB}B&_i!!FCoQN`xJwcCvpp&eL zH=8yl2B6Ub@19Ewd6~u$&LMGNag`NI4!6XD* diff --git a/projects/demo/src/assets/mstile-310x150.png b/projects/demo/src/assets/mstile-310x150.png deleted file mode 100644 index 2cb0dce2df2b6dfda26a1d027e3d3e360318efe1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2297 zcmaJ>dpJ~iA3v?UNU@QjQ7EF;GmLvNLouUf%4NpPq`U_2pv5RnLySl)(YU-?6`O8j ztC7?@tdWqdT)J4Q9ZXTIYmqcAp^>w{GoyW;_mACq&htCJ&-eGae7|$fbFzHBcdlB2 zUI9VSD$*_j6@tF8f}mwu>MEd8^o;EZZp#ns@Y(@EqCCxo5LJLpSi7iR5X3Wwpp+jV z=rbs#yoI1xECh`PLy&VJ1nI{V-=*MyQI_u>8W9j+KNlFRbXS;;M=k~)_OeqzS2%b( zvSGNvblg(K-$lUzWW|vm4o(4DKyZa=py&n%I4v;&fd&k}GLen)0%SLswjJIM929#x z9SKF`+m<-KKnsqPa!?1M3M~VqxWOdS5)21@x*=L+GYALtuk7S&!+UWs#RK6ZQvjwS zLK&xYLvj^Ceu@==uCTX@q5-f6Dp#25j;zXYlmwtvs(?ST2NNkHT;Y8lh!!b=iegos zD&b#oR4_6~RQSViQTb1E;9;ELQoa2k%VmuXG`|)7Z`2ccMl(}r!4=%1(>JY;n1Nbv z2Un*5U^X|q;bs|e`*O)MmG2MejE{bsn%PzE z(RjVH^hVr~*cPk*<`1l*S5!_L$0rnDco!60Z=NRgye`y_jB3v7rBFpjGaues>mP2Y z^*`{oK+FEKdnX~4UkMWcP~(!kh-!nHYrnN#u5&Kk9)eVpNQ51<_*dhv<>%>s>wf(s z!q(l>bFE$k;q=e8WSvbU&X(0g(ja3n*(nSjVf!7y%M&}Z_RA;lHC(LvR5`qDtf-@? zZDgN^2eALA-?NzAX9t-#FQCd~}$p z`Wu$Fw5OtNVqeCY5!q#a#Y8)%elHp>%MgHqeTJF3u~pIX{_%=|(w;KGHFLhv#kTtIMk5}#F}uUM>}tA*m~kr} z&vEvyumn#`AK~22{`^vYtRpTVBtJhd9gv-cE;@&4CgilXqgc8%UF3sPm4G3da=bQyqOeAy(V^9uXqSVB z5kcIm&iiqEq3CyB7~h7%I_af#H-M0{zS9Mp-mlIvn)#jxi&L8W|X6iY_c^6`g@Nw_U`@$%!uEv-BvMW~xo{tHdb2TcP zs-Lc&Aea(zF6e~w)wBydwAQW60Mb$ zDw18lIpE(_9NFAQk7}W42z2s0)6SKjY?y`a#yml}P0V9zqFqwA2$~t1l}*;X_IcaF zjgjoC%>i}3vIDRF(7bO(VeyGC`!o3TN~?bv*AsIvs4#vI-RHdewJdaiTKF*~QZi`D1R0b77(!fF0waD`Bm zE?~=AWXY8+K8$vhgV?74^TD~}_+n|FkE5WuGpnNMae>;x8r*h?)E4+nRTNkhZwvgg zoWgoasKzXw{*)P%w)0M@hz@M3B`1r^lQV=OdUNVgp8d>*63ZKxz%2Q14GSz@7*8e6 z_z`l(S0`n<+RnGE8__>D5;nKcv)3Z+`_DcUR)ATr_|Ba@3)+4W*QUEs*HJzf$rmgm z*;#|#sOlglZk{uF)l9eMxc8#=yK2lQoX_bzQwqxxsJ3<_CQlwVi)5bw)Wr3~tJ4F! zB+_`mVkG}Ua?K^=J|IPt~v7;Fjzc;ncu48;JAM>n(rq&LPd;A zuD%f)0IxyBEBG-;{GxqH0sH~*o;l7KMIvuXx>544G+&B%tCT_`<3Z%A*v+z4-dj(R zOIz}VqI~fGtKpVFRzCpvC2+!1r?;oEL|DLEmxVU8sEd|4=L)C_@8Y3|iTA<1kGv5- zuOmaZ&7#ys@flq|<7dbpE*bsPckl1dQVfR<8Qd&LUb%;#1X!E6M1O8*2sg}`#R&s9 z$QEmh#n{+jY#nGej?VT@&RBa(tc^1kYZshu_YEM&kT_#&Wqx!44lkN^@kWooQZ^AA2;M6|>1xYC( diff --git a/projects/demo/src/assets/mstile-310x310.png b/projects/demo/src/assets/mstile-310x310.png deleted file mode 100644 index 0ea625219b7daedd75fe53e8d3ec84ed984d9e1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3821 zcmcImdpMMN8-826YtxBnFgev!Y>e})X`G@NqR2Q-hMdWuF(`6uD-~l{$ze;hI=P~( z(;%lxGnAq$u=YH<{ex7$+CdI+tdV>^N z3WA^wHv5T=5cHik{QgM-WXdi@PJ-L_K^Arv5LBMAZpr5d5Ucs^ceI0`*j*5G>MR5; zfYhlE5OiD@g2ucdh>!2=(TkOQk=OGpOT z2IS;@s~K2*Wn?hOH)D4=6r{1qmOzJVeJ}xI8sFixJ?6XpK4(0G{f|;y;z=f27wfpaWQVf4?c*(8miz+6* z+qCeSU(@`#^VY}c2M!8cc9qe%f?$$`b@Kqut~j9VVIzrVO)^J>PBWoUD8N3P}N{(ZZjzOXaQK6cSzThWI^ zosaWwmA^0MH+EDuhup2C3q``9yJeBHl(NW<<^1DaHbCcp_zL}Nq)F17$Zi~BC1gB^ z$*&+(3uP2ouk5`VKR!>`^pKKY?tXW$OC+84nA#ctFUFf?c2ldjoV{5{H@;rDMUP3fD zU~Q^h&+irC*S{^8akGwV_QG8Ze>g@_{Sc@2W2jIvBhEv6$$^j2^N_!rE*fgG_We_P zxovGm`%cx#IE`~-UEL{WJtBwoynqr`e1ouD;YPc8`H&!jlbx`MEA3hR_H{QnKnb6n zuo>;R-dR(0OXR?v=eHMCSP$!#4en;NH+9aMD(#DGxii2@*wp%NXAGiKSRADvKprHaRn$crp!1W zdn*MUJmE1OEQ9O9@1`D<#YKd&^Vkz{&au%4*?GHY`Hcd&RnYJGVhDgb2G+juym>}3EXoSCQ@|jFnXEm zA3rg=u)IlKO`Y2CHN8)uszp<}o*z0rR!VF5cjjv7tr3IN{gb)B<}UqcqOjrcQ1r((iVl)ch)w$YSwLGgu`Xx@>FF5>Dvncub0 zmhnbE@mX~HKthrf#mkCaJ6_OI(qF0Blvd0ziKyV{s8)Bl=@$^lf}>i)Uhm^{%xPEK zg)E(_iN&l3mw~o{NVT$Sd9FrK#LaAbg31uDp>j7Z5?O-ZGO>d-qT1>yF)dz?EKmSe zyo`OS%Ub2Z5-hCPbF2+Hi-GZb$bwG+{>)sDhL^F^MmLG9mfTFN*`GtF`KdY@G^P7# zM%t?VbCRNHKHAHXhYwYJGdy+Py(eB{*-wcq_%oovpzf&Wm%eEdiM1~$6RR?3KYoYb zXxeb6n9&C833ui+5}Hbj8MPp&oZZng5E&HXNfv~2_(5+);SodU1;Ud|^!eQaHb+RW z_~JQzbAX3Gs7UuviN8`mkRI6*0;)e_sQpV~$f#9b9=DMUyr044h<##?lLgWozW>6@ zj9!YFz?2R~@%LwrUqww<+Vk*uV6}1ltMBO3xwye1?jI>Z%sx?B9cOuR$P|oukhu~qD};w+ z&T}d`t=dyn z167!y9l{?iU>(zI1c(vWYS%Z-)8T z>5(<{W(zQL$=OOylC#45!k0co78R3^4QzNmF!k~F=~oxfHCA})l3O;TASE3`>z5h| zE$_)yUz$rrkFQITZ5(f~mAxu*3@@4yjnM7g0W`Wgb6Hl|hDV_;(ZwE&#QLo@VHK0? zt(#R7NKrTXY#Vy4ExBRLwL0|s!laT3ObrYf4mYM`UBq?QKSn)B5o*w!_oNe9 z)sN{QI-%fA_JhcN%8E5uHg!>h*6$_2Z^pT1PD|R#_L!%lUD7dRzYWtctMYjYPr;H$ zIRX?X3CbkaZdkEl4(Jc07g=Qs_VXz2a4qLo3)GhP(zqN~K?!dj(aT9lidEkQyjzN{ z7n5NLR5qi}cRs0$DOGs^eIS+3eytrPhr0tCjTokT?0O6+Sumyj5}R|PJ?$i*l)>d} zZVoH=oYSE3@L-0UV1`h6;1UPBR0J;jum(Zy&Us+JmT=o)Yw~q2W8@Zh^DvmN-8dDk zH~hQL%nN_aPn)CdgD7w<`pxPQqYmzZK#=yBCBK|omXPXuGKPpTeNhv zh-O-+9|RL@Mha|3@17-_G6klGoswbD zkc>P>T@Lpn3{qJI-2$N5Rgeq}O4gI-+?K;xUFt+J!Bd5q%Ikr_d9b%-u(uO68p|$} zj>N8yy9=?dds5NwGQjNCpp^jJEirb`CT_*EYfJHy6?0WZT0$M8&U(KP42=l72AaBh1YOa!&d_5|6G?1}d*y-)uerXK*p diff --git a/projects/demo/src/assets/mstile-70x70.png b/projects/demo/src/assets/mstile-70x70.png deleted file mode 100644 index 418b9f573546bc71b6621ad241cb82465e69cc51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1795 zcmZ`)dpMJO9Df;yHga9Y=|aemxil-wW!S_tvAr{rN=)gYp(#K@9+2deSe?J_xHZf`@F)yfK}RP6Ep-t z+J3%NCYaL|woMh+GIkM)5^AgIpmW)*19Oo$iisyk-)Cvx1=PKge5=qKNp( z1bA8k+M8xh_lY2s^z(fu?!pQ$G% z;6DF@E&P4ik4bx#hFX|~?s=t|nzHb#+@z$~b!xe4t89Jv+<`tV!G4ReZ)O$e#g+ND zEcd28{l%m7y&*Tcaj8&r;o>Lb1takf+KA2tT)bLN1KR5tmqqGnD!$FzWj2H%fC)9Aw(>k`P#!)ISX5Nf+0)e}yBF?{U(N;t^y zUMAtRe!jnuV3TLj)lS95;OSh4f^Bpud{d`p|I_X+Tx4`x(YK22ovEknC%z?&PJFz! z;$iQxQwHc5qDhWV>0eujCTWK1uC;|b)W~W5gcsrZeX3GwmDQbbZYm4&p>xqo)wfkm z8F$`s;4&l4MOs@kY+jU*CF9Ojj5t%d&Vn{V;7*Gy^&#t3-jF^yqc36zoVdv}E)?95Tj8<1(?Va!*+)?-1 z!sMuICS9Nyt)H85#E)$n%sJxbxc(Nb^dS1P%us5hA?J#iIi=$xRO>Z>C}iHQAFre~ zNxWPWsWED8H#IzN+ehrpKyz_%3u%k|buIJJQe%-|p;j^Kb4k1C-lO{VCiCRQYsKkk zDK7iWp`N4x-zvNrwnUcvJ$C+HeT+(dmxbQB(WC2H*Q zLATa6QbxrF;6~h}HT`u62_pkxllY8~#7;YdLEA@%z^kp&zt-g=+4d>`j@~Agf zw#2R<<$R3%^5k@7UH$F~FP9}+gWbD3vhmkOIHSKJ4NHv1Zlr=%#gSJ`Yi0MlvY8rb zZx*p4g!VVE;DLnBJ5qMwfp@$u{p5$ZGL6ekP8$-e=<|4j>d<{sY;`YPytEq~r^l!Z zc51GEnZ?veHLwe74<288sds$OWbVkb${Y7ai?Sa>skx1)4vV|IkFdDox)=5Q>ZFr# zWUS@Xg-0fxT^nz;QH5!?hK$Q^8|HWJSWGAJ1W)6JXtA9_{AZqk6gyEL+ns@Tp6o5G z9$s_xhw+5^?8lL_bqb~3>f$eoQ~^H%$dXSB;YUUAx#Y-1E|?%E2PX$RM@Ks+XV{TM zCX&d`D{LJc$qo*z9+C5Z1aZ8mnCM;qFIZgbBm@FZ3LL^`M(i|=Pvk|%#BxpfyW+W~ zG4cFJ2ud#M9nsQE2*%@^*R-_yy=6iua||I8V_!VQSS7FnZj&@l? iYs35ojh1v@37r598R_vyyqpU_1ms5xpkDOaxbI&p*C_V@ diff --git a/projects/demo/src/assets/safari-pinned-tab.svg b/projects/demo/src/assets/safari-pinned-tab.svg index e600f9aea4ff..72326ecf7950 100644 --- a/projects/demo/src/assets/safari-pinned-tab.svg +++ b/projects/demo/src/assets/safari-pinned-tab.svg @@ -2,34 +2,119 @@ Created by potrace 1.11, written by Peter Selinger 2001-2013 - - + diff --git a/projects/demo/src/index.html b/projects/demo/src/index.html index a197266ba54b..4858a7a3c7ec 100644 --- a/projects/demo/src/index.html +++ b/projects/demo/src/index.html @@ -30,9 +30,9 @@ - + Taiga UI diff --git a/projects/demo/src/modules/components/input-card/input-card.component.ts b/projects/demo/src/modules/components/input-card/input-card.component.ts index d83990b09e7c..91b04591eb16 100644 --- a/projects/demo/src/modules/components/input-card/input-card.component.ts +++ b/projects/demo/src/modules/components/input-card/input-card.component.ts @@ -86,7 +86,10 @@ export class ExampleTuiInputCardComponent extends AbstractExampleTuiReactiveFiel autocompleteEnabledExpire = false; control = new FormGroup({ - card: new FormControl('', [Validators.required, tuiCreateLuhnValidator()]), + card: new FormControl('', [ + Validators.required, + tuiCreateLuhnValidator('Invalid card number'), + ]), expire: new FormControl('', Validators.required), cvc: new FormControl('', Validators.required), }); diff --git a/projects/icons/ng-package.json b/projects/icons/ng-package.json index 9f89e3ce4efe..f62b94fb1f88 100644 --- a/projects/icons/ng-package.json +++ b/projects/icons/ng-package.json @@ -1,6 +1,6 @@ { "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", - "dest": "../../dist/angular-icons", + "dest": "../../dist/icons", "lib": { "entryFile": "src/public-api.ts" } diff --git a/projects/icons/scripts/copy-icons.js b/projects/icons/scripts/copy-icons.js index 5300da6e8894..30357620f94b 100644 --- a/projects/icons/scripts/copy-icons.js +++ b/projects/icons/scripts/copy-icons.js @@ -1,4 +1,4 @@ const fs = require('fs-extra'); const {resolve} = require('path'); -fs.copy(resolve(__dirname, '..', 'src/icons/src'), './dist/angular-icons/src'); +fs.copy(resolve(__dirname, '..', 'src/icons/src'), './dist/icons/src'); diff --git a/projects/kit/components/calendar-range/calendar-range.component.ts b/projects/kit/components/calendar-range/calendar-range.component.ts index 38d9c2c4d975..5baf81c2a49d 100644 --- a/projects/kit/components/calendar-range/calendar-range.component.ts +++ b/projects/kit/components/calendar-range/calendar-range.component.ts @@ -35,7 +35,7 @@ import { MAX_DAY_RANGE_LENGTH_MAPPER, maxDayAssertion, } from '@taiga-ui/kit/constants'; -import {TUI_CALENDAR_DATA_STREAM} from '@taiga-ui/kit/tokens'; +import {TUI_CALENDAR_DATA_STREAM, TUI_OTHER_DATE_TEXT} from '@taiga-ui/kit/tokens'; import {Observable} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; @@ -100,8 +100,7 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax item.range.to.daySameOrAfter(min) && (max === null || item.range.from.daySameOrBefore(max)), ), - // TODO: i18n - 'Другая дата...', + this.otherDateText, ]; constructor( @@ -110,6 +109,7 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax valueChanges: Observable | null, @Inject(ChangeDetectorRef) changeDetectorRef: ChangeDetectorRef, @Inject(TuiDestroyService) destroy$: TuiDestroyService, + @Inject(TUI_OTHER_DATE_TEXT) private readonly otherDateText: string, ) { if (!valueChanges) { return; diff --git a/projects/kit/components/calendar-range/test/range-calendar.component.spec.ts b/projects/kit/components/calendar-range/test/range-calendar.component.spec.ts index 0003ea3cc624..a5eb0245fb4e 100644 --- a/projects/kit/components/calendar-range/test/range-calendar.component.spec.ts +++ b/projects/kit/components/calendar-range/test/range-calendar.component.spec.ts @@ -114,13 +114,6 @@ describe('rangeCalendarComponent', () => { const items = getItems(); expect(items.length).toBe(7); - expect(items[0].nativeElement.textContent.trim()).toBe('За все время'); - expect(items[1].nativeElement.textContent.trim()).toBe('Сегодня'); - expect(items[2].nativeElement.textContent.trim()).toBe('Вчера'); - expect(items[3].nativeElement.textContent.trim()).toBe('Текущая неделя'); - expect(items[4].nativeElement.textContent.trim()).toBe('Текущий месяц'); - expect(items[5].nativeElement.textContent.trim()).toBe('Прошлый месяц'); - expect(items[6].nativeElement.textContent.trim()).toBe('Другая дата...'); }); it('Если значение не подходит ни под один диапазон — галочка у "Другая дата..."', () => { @@ -163,8 +156,8 @@ describe('rangeCalendarComponent', () => { const items = getItems().map(item => item.nativeElement.textContent.trim()); - expect(items.some(item => item === 'Вчера')).toBe(true); - expect(items.some(item => item === 'Сегодня')).toBe(false); + expect(items.some(item => item === 'Yesterday')).toBe(true); + expect(items.some(item => item === 'Today')).toBe(false); }); it('При переопределении интервалов в списке всегда есть "Другая дата..."', () => { @@ -181,7 +174,7 @@ describe('rangeCalendarComponent', () => { expect(items.length).toBe(2); expect(items[0].nativeElement.textContent.trim()).toBe(title); - expect(items[1].nativeElement.textContent.trim()).toBe('Другая дата...'); + expect(items[1].nativeElement.textContent.trim()).toBe('Other date...'); }); }); diff --git a/projects/kit/components/data-list-wrapper/data-list-wrapper.component.ts b/projects/kit/components/data-list-wrapper/data-list-wrapper.component.ts index 81de4ef305f2..0d7f88d6d51a 100644 --- a/projects/kit/components/data-list-wrapper/data-list-wrapper.component.ts +++ b/projects/kit/components/data-list-wrapper/data-list-wrapper.component.ts @@ -3,6 +3,7 @@ import { Component, ElementRef, forwardRef, + Inject, Input, QueryList, ViewChildren, @@ -18,6 +19,7 @@ import { } from '@taiga-ui/cdk'; import { TUI_DATA_LIST_ACCESSOR, + TUI_NOTHING_FOUND_MESSAGE, TuiDataListAccessor, TuiOptionComponent, TuiSizeL, @@ -47,10 +49,9 @@ export class TuiDataListWrapperComponent implements TuiDataListAccessor { @tuiDefaultProp() disabledItemHandler: TuiBooleanHandler = ALWAYS_FALSE_HANDLER; - // TODO i18n @Input() @tuiDefaultProp() - emptyContent: PolymorpheusContent = 'Ничего не найдено'; + emptyContent: PolymorpheusContent = this.defaultEmptyContent; @Input() @tuiDefaultProp() @@ -64,6 +65,10 @@ export class TuiDataListWrapperComponent implements TuiDataListAccessor { @ViewChildren(forwardRef(() => TuiOptionComponent)) private readonly options: QueryList> = EMPTY_QUERY; + constructor( + @Inject(TUI_NOTHING_FOUND_MESSAGE) private readonly defaultEmptyContent: string, + ) {} + getContext( $implicit: T, {nativeElement}: ElementRef, diff --git a/projects/kit/components/input-file/file/file.component.ts b/projects/kit/components/input-file/file/file.component.ts index 0b32c85be5da..2aed7710dcac 100644 --- a/projects/kit/components/input-file/file/file.component.ts +++ b/projects/kit/components/input-file/file/file.component.ts @@ -53,7 +53,8 @@ export class TuiFileComponent { constructor( @Inject(TUI_IS_MOBILE) readonly isMobile: boolean, @Inject(DomSanitizer) private readonly sanitizer: DomSanitizer, - @Inject(TUI_FILE_TEXTS) readonly fileTexts: Record, + @Inject(TUI_FILE_TEXTS) + readonly fileTexts: Record<'loadingError' | 'preview' | 'remove', string>, @Inject(TUI_DIGITAL_INFORMATION_UNITS) private readonly units: [string, string, string], ) {} diff --git a/projects/kit/components/input-file/input-file.component.ts b/projects/kit/components/input-file/input-file.component.ts index 73bf5be2fde5..2f7708f7ee97 100644 --- a/projects/kit/components/input-file/input-file.component.ts +++ b/projects/kit/components/input-file/input-file.component.ts @@ -103,7 +103,18 @@ export class TuiInputFileComponent changeDetectorRef: ChangeDetectorRef, @Inject(TUI_IS_MOBILE) isMobile: boolean, - @Inject(TUI_INPUT_FILE_TEXTS) readonly inputFileTexts: Record, + @Inject(TUI_INPUT_FILE_TEXTS) + readonly inputFileTexts: Record< + | 'defaultLabelSingle' + | 'defaultLabelMultiple' + | 'defaultLinkSingle' + | 'defaultLinkMultiple' + | 'maxSizeRejectionReason' + | 'formatRejectionReason' + | 'drop' + | 'dropMultiple', + string + >, @Inject(TUI_DIGITAL_INFORMATION_UNITS) private readonly units: [string, string, string], ) { diff --git a/projects/kit/directives/unfinished-validator/unfinished-validator.directive.ts b/projects/kit/directives/unfinished-validator/unfinished-validator.directive.ts index 04a65f4349bf..07004e871321 100644 --- a/projects/kit/directives/unfinished-validator/unfinished-validator.directive.ts +++ b/projects/kit/directives/unfinished-validator/unfinished-validator.directive.ts @@ -1,6 +1,7 @@ import {Attribute, Directive, Inject, Injector} from '@angular/core'; import {NG_VALIDATORS, Validator} from '@angular/forms'; import {TUI_FOCUSABLE_ITEM_ACCESSOR} from '@taiga-ui/cdk'; +import {TUI_UNFINISHED_TEXT} from '@taiga-ui/kit/tokens'; import {tuiCreateUnfinishedValidator} from '@taiga-ui/kit/validators'; @Directive({ @@ -16,7 +17,7 @@ import {tuiCreateUnfinishedValidator} from '@taiga-ui/kit/validators'; export class TuiUnfinishedValidatorDirective implements Validator { readonly validate = tuiCreateUnfinishedValidator( () => this.injector.get(TUI_FOCUSABLE_ITEM_ACCESSOR), - this.message || undefined, + this.message || this.defaultMessage, ); constructor( @@ -24,5 +25,6 @@ export class TuiUnfinishedValidatorDirective implements Validator { private readonly injector: Injector, @Attribute('tuiUnfinishedValidator') private readonly message: string | null, + @Inject(TUI_UNFINISHED_TEXT) private readonly defaultMessage: string, ) {} } diff --git a/projects/kit/tokens/i18n.ts b/projects/kit/tokens/i18n.ts index ad2472900146..795637eead1a 100644 --- a/projects/kit/tokens/i18n.ts +++ b/projects/kit/tokens/i18n.ts @@ -13,6 +13,17 @@ export const TUI_MORE_WORD = new InjectionToken(`i18n 'more' word`, { factory: () => 'More', }); +export const TUI_OTHER_DATE_TEXT = new InjectionToken(`i18n 'Other date' text`, { + factory: () => 'Other date...', +}); + +export const TUI_UNFINISHED_TEXT = new InjectionToken( + `i18n unfinished validator text`, + { + factory: () => 'Finish filling the field', + }, +); + /** * Works with a tuple * [@string 'choose day', @param 'choose range'] @@ -82,16 +93,15 @@ export const TUI_CALENDAR_MONTHS = new InjectionToken>( }, ); -export const TUI_FILE_TEXTS = new InjectionToken>( - 'file i18n texts', - { - factory: () => ({ - loadingError: 'Loading error', - preview: 'Preview', - remove: 'Remove', - }), - }, -); +export const TUI_FILE_TEXTS = new InjectionToken< + Record<'loadingError' | 'preview' | 'remove', string> +>('file i18n texts', { + factory: () => ({ + loadingError: 'Loading error', + preview: 'Preview', + remove: 'Remove', + }), +}); export const TUI_PAGINATION_TEXTS = new InjectionToken<[string, string]>( 'pagination i18n texts', @@ -100,18 +110,27 @@ export const TUI_PAGINATION_TEXTS = new InjectionToken<[string, string]>( }, ); -export const TUI_INPUT_FILE_TEXTS = new InjectionToken>( - 'tui-input-file i18n texts', - { - factory: () => ({ - defaultLabelSingle: 'or drag\u00A0it\u00A0here', - defaultLabelMultiple: 'or drag\u00A0them\u00A0here', - defaultLinkSingle: 'Choose a file', - defaultLinkMultiple: 'Choose files', - maxSizeRejectionReason: 'File exceeds size ', - formatRejectionReason: 'Wrong file format', - drop: 'Drop file here', - dropMultiple: 'Drop files here', - }), - }, -); +export const TUI_INPUT_FILE_TEXTS = new InjectionToken< + Record< + | 'defaultLabelSingle' + | 'defaultLabelMultiple' + | 'defaultLinkSingle' + | 'defaultLinkMultiple' + | 'maxSizeRejectionReason' + | 'formatRejectionReason' + | 'drop' + | 'dropMultiple', + string + > +>('tui-input-file i18n texts', { + factory: () => ({ + defaultLabelSingle: 'or drag\u00A0it\u00A0here', + defaultLabelMultiple: 'or drag\u00A0them\u00A0here', + defaultLinkSingle: 'Choose a file', + defaultLinkMultiple: 'Choose files', + maxSizeRejectionReason: 'File exceeds size ', + formatRejectionReason: 'Wrong file format', + drop: 'Drop file here', + dropMultiple: 'Drop files here', + }), +}); diff --git a/projects/kit/utils/miscellaneous/create-default-day-range-periods.ts b/projects/kit/utils/miscellaneous/create-default-day-range-periods.ts index c0165340169b..76cb8259f63c 100644 --- a/projects/kit/utils/miscellaneous/create-default-day-range-periods.ts +++ b/projects/kit/utils/miscellaneous/create-default-day-range-periods.ts @@ -1,7 +1,16 @@ import {TUI_FIRST_DAY, TuiDay, TuiDayRange} from '@taiga-ui/cdk'; import {TuiDayRangePeriod} from '@taiga-ui/kit/classes'; -export function tuiCreateDefaultDayRangePeriods(): ReadonlyArray { +export function tuiCreateDefaultDayRangePeriods( + periodTitles: [string, string, string, string, string, string] = [ + 'For all the time', + 'Today', + 'Yesterday', + 'Current week', + 'Current month', + 'Previous month', + ], +): ReadonlyArray { const today = TuiDay.currentLocal(); const yesterday = today.append({day: -1}); const startOfWeek = today.append({day: -today.dayOfWeek()}); @@ -10,16 +19,15 @@ export function tuiCreateDefaultDayRangePeriods(): ReadonlyArray TuiFocusableElementAccessor, - message: PolymorpheusContent = error, + message: PolymorpheusContent, ): ValidatorFn { return ({ value,