First round of internationlization

This commit is contained in:
2023-03-09 15:51:00 +01:00
parent 0011b62a5d
commit 0f1c910919
10 changed files with 817 additions and 62 deletions

View File

@@ -9,10 +9,20 @@
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"prefix": "app", "prefix": "app",
"i18n": {
"sourceLocale": "en-US",
"locales": {
"fr": {
"translation": "src/locale/messages.fr.xlf"
}
}
},
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"localize": ["fr"],
"i18nMissingTranslation": "warning",
"outputPath": "dist/app", "outputPath": "dist/app",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
@@ -53,6 +63,9 @@
"extractLicenses": false, "extractLicenses": false,
"sourceMap": true, "sourceMap": true,
"namedChunks": true "namedChunks": true
},
"fr": {
"localize": ["fr"]
} }
}, },
"defaultConfiguration": "production" "defaultConfiguration": "production"
@@ -65,14 +78,22 @@
}, },
"development": { "development": {
"browserTarget": "app:build:development" "browserTarget": "app:build:development"
},
"fr": {
"browserTarget": "App:build:fr"
} }
}, },
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "ng-extract-i18n-merge:ng-extract-i18n-merge",
"options": { "options": {
"browserTarget": "app:build" "browserTarget": "app:build",
"format": "xlf2",
"outputPath": "src/locale",
"targetFiles": [
"messages.fr.xlf"
]
} }
}, },
"test": { "test": {

View File

@@ -43,6 +43,7 @@
"karma-coverage": "~2.2.0", "karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0", "karma-jasmine-html-reporter": "~2.0.0",
"ng-extract-i18n-merge": "^2.5.1",
"typescript": "~4.8.2" "typescript": "~4.8.2"
} }
}, },
@@ -7410,6 +7411,15 @@
"url": "https://github.com/chalk/supports-color?sponsor=1" "url": "https://github.com/chalk/supports-color?sponsor=1"
} }
}, },
"node_modules/js-levenshtein": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
"integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8740,6 +8750,24 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true "dev": true
}, },
"node_modules/ng-extract-i18n-merge": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/ng-extract-i18n-merge/-/ng-extract-i18n-merge-2.5.1.tgz",
"integrity": "sha512-wHZR58H74nhgNKr33CtcawIUXWZrfvB2oKaF2VpoLxZMK3wJuBWXqnGwUGkZ5GJcYxiy21NFPMiQnkbw8pxS/A==",
"dev": true,
"dependencies": {
"@angular-devkit/architect": "^0.1301.0 || ^0.1401.0 || ^0.1501.0",
"@angular-devkit/core": "^13.0.0 || ^14.0.0 || ^15.0.0",
"@angular-devkit/schematics": "^13.0.0 || ^14.0.0 || ^15.0.0",
"@schematics/angular": "^13.0.0 || ^14.0.0 || ^15.0.0",
"xliff-simple-merge": "~1.0.1",
"xml_normalize": "^1.0.0",
"xmldoc": "~1.1.2"
},
"peerDependencies": {
"@angular-devkit/build-angular": "^13.0.0 || ^14.0.0 || ^15.0.0"
}
},
"node_modules/ngx-bootstrap-icons": { "node_modules/ngx-bootstrap-icons": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ngx-bootstrap-icons/-/ngx-bootstrap-icons-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ngx-bootstrap-icons/-/ngx-bootstrap-icons-1.9.1.tgz",
@@ -10659,8 +10687,7 @@
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true, "dev": true
"optional": true
}, },
"node_modules/saxes": { "node_modules/saxes": {
"version": "5.0.1", "version": "5.0.1",
@@ -12455,6 +12482,51 @@
} }
} }
}, },
"node_modules/xliff-simple-merge": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/xliff-simple-merge/-/xliff-simple-merge-1.0.2.tgz",
"integrity": "sha512-9Dtw/l91o0DeLkNFJrlh5nxJSS8OD+IHeq5rjA6hkVtv6SWf7rJyr4YNSQc/6opDssRI8JgAWcQlj2ZfcvW11Q==",
"dev": true,
"dependencies": {
"commander": "~8.3.0",
"js-levenshtein": "~1.1.6",
"xmldoc": "~1.1.2"
},
"bin": {
"xliff-simple-merge": "dist/src/index.js"
}
},
"node_modules/xliff-simple-merge/node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"dev": true,
"engines": {
"node": ">= 12"
}
},
"node_modules/xml_normalize": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/xml_normalize/-/xml_normalize-1.0.0.tgz",
"integrity": "sha512-VzDbw9DW849WoLor6CP1eIPiVWwbq8CV3dlSrfVfsMqBqvp3VVkmLxA8J55WyLf6CnAf2sV29TQO77BKM/cxBw==",
"dev": true,
"dependencies": {
"commander": "~7.1.0",
"xmldoc": "~1.1.2"
},
"bin": {
"xml_normalize": "dist/src/index.js"
}
},
"node_modules/xml_normalize/node_modules/commander": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz",
"integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==",
"dev": true,
"engines": {
"node": ">= 10"
}
},
"node_modules/xml-name-validator": { "node_modules/xml-name-validator": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
@@ -12470,6 +12542,15 @@
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"optional": true "optional": true
}, },
"node_modules/xmldoc": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.4.tgz",
"integrity": "sha512-rQshsBGR5s7pUNENTEncpI2LTCuzicri0DyE4SCV5XmS0q81JS8j1iPijP0Q5c4WLGbKh3W92hlOwY6N9ssW1w==",
"dev": true,
"dependencies": {
"sax": "^1.2.4"
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@@ -45,6 +45,7 @@
"karma-coverage": "~2.2.0", "karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0", "karma-jasmine-html-reporter": "~2.0.0",
"ng-extract-i18n-merge": "^2.5.1",
"typescript": "~4.8.2" "typescript": "~4.8.2"
} }
} }

View File

@@ -10,23 +10,22 @@ import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
<button *ngIf="!isAuthenticated" <button *ngIf="!isAuthenticated"
class="nav-link px-3 w-100" class="nav-link px-3 w-100"
(click)="openLoginModal()" (click)="openLoginModal()"
><i-bs name="key-fill"/><span class="ms-1 d-none d-sm-inline">Login</span></button> ><i-bs name="key-fill"/><span class="ms-1 d-none d-sm-inline" i18n>Login</span></button>
<ng-template #loginModal let-modal> <ng-template #loginModal let-modal>
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Login</h4> <h4 class="modal-title" id="modal-basic-title" i18n>Login</h4>
<button type="button" class="btn-close" aria-label="Close" <button type="button" class="btn-close" aria-label="Close"
(click)="modal.dismiss('Cross click')"></button> (click)="modal.dismiss('Cross click')"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form [formGroup]="form"> <form [formGroup]="form">
<fieldset> <fieldset>
<legend>Login</legend>
<div class="form-field"> <div class="form-field">
<label>Username:</label> <label i18n>Username:</label>
<input class="form-control" name="username" formControlName="username"> <input class="form-control" name="username" formControlName="username">
</div> </div>
<div class="form-field"> <div class="form-field">
<label>Password:</label> <label i18n>Password:</label>
<input class="form-control" name="password" formControlName="password" <input class="form-control" name="password" formControlName="password"
type="password"> type="password">
</div> </div>
@@ -36,11 +35,11 @@ import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
<div class="modal-footer"> <div class="modal-footer">
<div class="form-buttons"> <div class="form-buttons">
<button class="btn btn-primary" <button class="btn btn-primary"
(click)="this.login()">Login</button> (click)="this.login()" i18n>Login</button>
</div> </div>
<div class="form-buttons"> <div class="form-buttons">
<button class="btn btn-danger" <button class="btn btn-danger"
(click)="modal.dismiss('Cancel click')">Cancel</button> (click)="modal.dismiss('Cancel click')" i18n>Cancel</button>
</div> </div>
</div> </div>
</ng-template> </ng-template>
@@ -102,7 +101,7 @@ export class LoginComponent {
<button *ngIf="isAuthenticated" <button *ngIf="isAuthenticated"
class="nav-link px-3 w-100" class="nav-link px-3 w-100"
(click)="logout()" (click)="logout()"
><i-bs name="door-open-fill"/><span class="ms-1 d-none d-sm-inline">Logout</span></button> ><i-bs name="door-open-fill"/><span class="ms-1 d-none d-sm-inline" i18n>Logout</span></button>
` `
}) })
export class LogoutComponent { export class LogoutComponent {

View File

@@ -11,32 +11,32 @@ import { AuthService } from "../auth/auth.service";
export class SidenavComponent { export class SidenavComponent {
Menu = [ Menu = [
{ {
title: "Dashboard", title: $localize`Dashboard`,
link: "/dashboard", link: "/dashboard",
icon: IconNamesEnum.HouseFill icon: IconNamesEnum.HouseFill
}, },
{ {
title: "Entities", title: $localize`Entities`,
link: "/entities", link: "/entities",
icon: IconNamesEnum.PeopleFill icon: IconNamesEnum.PeopleFill
}, },
{ {
title: "Provision&nbsp;Templates", title: $localize`Provision&nbsp;Templates`,
link: "/templates/provisions", link: "/templates/provisions",
icon: IconNamesEnum.BlockquoteLeft icon: IconNamesEnum.BlockquoteLeft
}, },
{ {
title: "Contracts&nbsp;Templates", title: $localize`Contracts&nbsp;Templates`,
link: "/templates/contracts", link: "/templates/contracts",
icon: IconNamesEnum.FileCodeFill icon: IconNamesEnum.FileCodeFill
}, },
{ {
title: "Contracts&nbsp;Drafts", title: $localize`Contracts&nbsp;Drafts`,
link: "/contracts/drafts", link: "/contracts/drafts",
icon: IconNamesEnum.PencilSquare icon: IconNamesEnum.PencilSquare
}, },
{ {
title: "Contracts", title: $localize`Contracts`,
link: "/contracts", link: "/contracts",
icon: IconNamesEnum.FileEarmarkTextFill icon: IconNamesEnum.FileEarmarkTextFill
}, },

View File

@@ -1,36 +1,32 @@
<div> <div>
<form cForm [formGroup]="form" (ngSubmit)="onSubmit(model)"> <form cForm [formGroup]="form" (ngSubmit)="onSubmit(model)">
<span class="col col-form-label" *ngIf="formLoading$ || modelLoading$ | async">Loading...</span> <span class="col col-form-label" i18n *ngIf="formLoading$ || modelLoading$ | async">Loading...</span>
<formly-form [form]="form" [fields]="fields" [model]="model"></formly-form> <formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
<div class="d-grid gap-2 d-md-flex"> <div class="d-grid gap-2 d-md-flex">
<button class="btn btn-success btn-lg" type="submit" <button class="btn btn-success btn-lg" type="submit"
[disabled]="!form.valid && (formLoading$ || modelLoading$ | async)"> [disabled]="!form.valid && (formLoading$ || modelLoading$ | async)">
{{ this.isCreateForm() ? "Create" : "Update" }} {{ submitText }}
</button> </button>
<button class="btn btn-primary btn-lg" type="button" *ngIf="!this.isCreateForm()" <button class="btn btn-primary btn-lg" i18n type="button" *ngIf="!this.isCreateForm()"
[disabled]="!form.valid && (formLoading$ || modelLoading$ | async)" [disabled]="!form.valid && (formLoading$ || modelLoading$ | async)"
(click)="open(duplicationModal)"> (click)="open(duplicationModal)">Duplicate</button>
Duplicate <button class="btn btn-danger btn-lg" i18n type="button" *ngIf="!this.isCreateForm()"
</button>
<button class="btn btn-danger btn-lg" type="button" *ngIf="!this.isCreateForm()"
[disabled]="formLoading$ || modelLoading$ | async" [disabled]="formLoading$ || modelLoading$ | async"
(click)="open(confirmDeleteModal)"> (click)="open(confirmDeleteModal)">Delete</button>
Delete
</button>
<ng-template #confirmDeleteModal let-modal> <ng-template #confirmDeleteModal let-modal>
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title">Are you sure you want to delete this {{ this.schema }}?</h4> <h4 class="modal-title" i18n>Are you sure you want to delete this {{ this.schema }}?</h4>
<button type="button" class="btn-close" aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')"></button> <button type="button" class="btn-close" i18n-aria-label aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')"></button>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-light" aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')">Cancel</button> <button type="button" class="btn btn-light" i18n i18n-aria-label aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')">Cancel</button>
<button type="button" class="btn btn-danger" (click)="modal.close('Save click')">Delete</button> <button type="button" class="btn btn-danger" i18n (click)="modal.close('Save click')">Delete</button>
</div> </div>
</ng-template> </ng-template>
<ng-template #duplicationModal let-modal> <ng-template #duplicationModal let-modal>
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title">Duplicate {{ this.schema }}</h4> <h4 class="modal-title" i18n>Duplicate {{ this.schema }}</h4>
<button type="button" class="btn-close" aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')"></button> <button type="button" class="btn-close" i18n-aria-label aria-label="Cancel" (click)="modal.dismiss('Cancel Deletion')"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<crud-card [resource]="this.resource" <crud-card [resource]="this.resource"

View File

@@ -55,6 +55,10 @@ export class CardComponent implements OnInit {
return this._modelLoading$.asObservable(); return this._modelLoading$.asObservable();
} }
get submitText() {
return this.isCreateForm() ? $localize`Create` : $localize`Update`
}
constructor(private crudService: CrudService, constructor(private crudService: CrudService,
private formlyJsonschema: CrudFormlyJsonschemaService, private formlyJsonschema: CrudFormlyJsonschemaService,
private router: Router, private router: Router,

View File

@@ -1,10 +1,9 @@
<form> <form>
<button class="btn btn-success btn-lg float-end" type="button" i18n (click)="onCreate()">
<button class="btn btn-success btn-lg float-end" type="button" (click)="onCreate()">
Create {{ this.schema }} Create {{ this.schema }}
</button> </button>
<div class="mb-3 row"> <div class="mb-3 row">
<label for="table-complete-search" class="col-xs-3 col-sm-auto col-form-label">Full text search:</label> <label for="table-complete-search" i18n class="col-xs-3 col-sm-auto col-form-label">Full text search:</label>
<div class="col-xs-3 col-sm-auto"> <div class="col-xs-3 col-sm-auto">
<input <input
id="table-complete-search" id="table-complete-search"
@@ -14,7 +13,7 @@
[(ngModel)]="searchTerm" [(ngModel)]="searchTerm"
/> />
</div> </div>
<span class="col col-form-label" *ngIf="loading$ | async">Loading...</span> <span class="col col-form-label" i18n *ngIf="loading$ | async">Loading...</span>
</div> </div>
<div class="table-responsive-md"> <div class="table-responsive-md">
<table class="table table-striped"> <table class="table table-striped">
@@ -38,11 +37,11 @@
</ngb-pagination> </ngb-pagination>
<select class="form-select" style="width: auto" name="pageSize" [(ngModel)]="pageSize"> <select class="form-select" style="width: auto" name="pageSize" [(ngModel)]="pageSize">
<option [ngValue]="10">10 items per page</option> <option i18n [ngValue]="10">10 items per page</option>
<option [ngValue]="15">15 items per page</option> <option i18n [ngValue]="15">15 items per page</option>
<option [ngValue]="25">25 items per page</option> <option i18n [ngValue]="25">25 items per page</option>
<option [ngValue]="50">50 items per page</option> <option i18n [ngValue]="50">50 items per page</option>
<option [ngValue]="100">100 items per page</option> <option i18n [ngValue]="100">100 items per page</option>
</select> </select>
</div> </div>
</form> </form>

View File

@@ -0,0 +1,358 @@
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en-US" trgLang="fr">
<file original="ng.template" id="ngi18n">
<unit id="ngb.alert.close">
<segment state="initial">
<source>Close</source>
<target>Fermer</target>
</segment>
</unit>
<unit id="ngb.timepicker.HH">
<segment state="initial">
<source>HH</source>
<target>HH</target>
</segment>
</unit>
<unit id="ngb.toast.close-aria">
<segment state="initial">
<source>Close</source>
<target>Fermer</target>
</segment>
</unit>
<unit id="ngb.pagination.first">
<segment state="initial">
<source>««</source>
<target>««</target>
</segment>
</unit>
<unit id="ngb.datepicker.select-month">
<segment state="initial">
<source>Select month</source>
<target>Selectionner un mois</target>
</segment>
</unit>
<unit id="ngb.datepicker.previous-month">
<segment state="initial">
<source>Previous month</source>
<target>Mois précédent</target>
</segment>
</unit>
<unit id="ngb.progressbar.value">
<segment state="initial">
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
<target>
<ph id="0" equiv="INTERPOLATION"/>
</target>
</segment>
</unit>
<unit id="ngb.carousel.slide-number">
<segment state="initial">
<source> Slide <ph id="0" equiv="INTERPOLATION"/> of <ph id="1" equiv="INTERPOLATION_1"/> </source>
<target> Slide <ph id="0" equiv="INTERPOLATION"/> of <ph id="1" equiv="INTERPOLATION_1"/> </target>
</segment>
</unit>
<unit id="ngb.timepicker.hours">
<segment state="initial">
<source>Hours</source>
<target>Heures</target>
</segment>
</unit>
<unit id="ngb.pagination.previous">
<segment state="initial">
<source>«</source>
<target>«</target>
</segment>
</unit>
<unit id="ngb.carousel.previous">
<segment state="initial">
<source>Previous</source>
<target>Précédent</target>
</segment>
</unit>
<unit id="ngb.timepicker.MM">
<segment state="initial">
<source>MM</source>
<target>MM</target>
</segment>
</unit>
<unit id="ngb.pagination.next">
<segment state="initial">
<source>»</source>
<target>»</target>
</segment>
</unit>
<unit id="ngb.datepicker.select-year">
<segment state="initial">
<source>Select year</source>
<target>Sélectionner une année</target>
</segment>
</unit>
<unit id="ngb.datepicker.next-month">
<segment state="initial">
<source>Next month</source>
<target>Mois suivant</target>
</segment>
</unit>
<unit id="ngb.carousel.next">
<segment state="initial">
<source>Next</source>
<target>Suivant</target>
</segment>
</unit>
<unit id="ngb.timepicker.minutes">
<segment state="initial">
<source>Minutes</source>
<target>Minutes</target>
</segment>
</unit>
<unit id="ngb.pagination.last">
<segment state="initial">
<source>»»</source>
<target>»»</target>
</segment>
</unit>
<unit id="ngb.timepicker.increment-hours">
<segment state="initial">
<source>Increment hours</source>
<target>Incrémenter les heures</target>
</segment>
</unit>
<unit id="ngb.pagination.first-aria">
<segment state="initial">
<source>First</source>
<target>Premier</target>
</segment>
</unit>
<unit id="ngb.pagination.previous-aria">
<segment state="initial">
<source>Previous</source>
<target>Précédent</target>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-hours">
<segment state="initial">
<source>Decrement hours</source>
<target>Décrémenter les heures</target>
</segment>
</unit>
<unit id="ngb.pagination.next-aria">
<segment state="initial">
<source>Next</source>
<target>Suivant</target>
</segment>
</unit>
<unit id="ngb.timepicker.increment-minutes">
<segment state="initial">
<source>Increment minutes</source>
<target>Incrémenter les minutes</target>
</segment>
</unit>
<unit id="ngb.pagination.last-aria">
<segment state="initial">
<source>Last</source>
<target>Dernier</target>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-minutes">
<segment state="initial">
<source>Decrement minutes</source>
<target>Décrémenter les minutes</target>
</segment>
</unit>
<unit id="ngb.timepicker.SS">
<segment state="initial">
<source>SS</source>
<target>SS</target>
</segment>
</unit>
<unit id="ngb.timepicker.seconds">
<segment state="initial">
<source>Seconds</source>
<target>Secondes</target>
</segment>
</unit>
<unit id="ngb.timepicker.increment-seconds">
<segment state="initial">
<source>Increment seconds</source>
<target>Incrémenter les secondes</target>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-seconds">
<segment state="initial">
<source>Decrement seconds</source>
<target>Décrémenter les secondes</target>
</segment>
</unit>
<unit id="ngb.timepicker.PM">
<segment state="initial">
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
<target>
<ph id="0" equiv="INTERPOLATION"/>
</target>
</segment>
</unit>
<unit id="ngb.timepicker.AM">
<segment state="initial">
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
<target>
<ph id="0" equiv="INTERPOLATION"/>
</target>
</segment>
</unit>
<unit id="6570363013146073520">
<segment state="initial">
<source>Dashboard</source>
<target>Tableau de bord</target>
</segment>
</unit>
<unit id="4800190016750145593">
<segment state="initial">
<source>Entities</source>
<target>Clients</target>
</segment>
</unit>
<unit id="3336127935693687033">
<segment state="initial">
<source>Provision&amp;nbsp;Templates</source>
<target>Templates:&amp;nbsp;Clauses</target>
</segment>
</unit>
<unit id="8996893897509995689">
<segment state="initial">
<source>Contracts&amp;nbsp;Templates</source>
<target>Templates:&amp;nbsp;Contrats</target>
</segment>
</unit>
<unit id="4480519554689195945">
<segment state="initial">
<source>Contracts&amp;nbsp;Drafts</source>
<target>Contrats: Brouillons</target>
</segment>
</unit>
<unit id="6325430461732938793">
<segment state="initial">
<source>Contracts</source>
<target>Contrats</target>
</segment>
</unit>
<unit id="3894950702316166331">
<segment state="initial">
<source>Loading...</source>
<target>Chargement...</target>
</segment>
</unit>
<unit id="6621329748219109148">
<segment state="initial">
<source>Duplicate</source>
<target>Dupliquer</target>
</segment>
</unit>
<unit id="6594772639285650443">
<segment state="initial">
<source>Are you sure you want to delete this <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/>?</source>
<target>Êtes-vous sûr de vouloir supprimer ce<ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/>?</target>
</segment>
</unit>
<unit id="2159130950882492111">
<segment state="initial">
<source>Cancel</source>
<target>Annuler</target>
</segment>
</unit>
<unit id="7022070615528435141">
<segment state="initial">
<source>Delete</source>
<target>Supprimer</target>
</segment>
</unit>
<unit id="2502514662075565663">
<segment state="initial">
<source>Duplicate <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/></source>
<target>Dupliquer <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/></target>
</segment>
</unit>
<unit id="5974043874204012120">
<segment state="initial">
<source> Create <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/> </source>
<target> Créer <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/> </target>
</segment>
</unit>
<unit id="8449969376421674433">
<segment state="initial">
<source>Full text search:</source>
<target>Rechercher:</target>
</segment>
</unit>
<unit id="7735090777677032335">
<segment state="initial">
<source>10 items per page</source>
<target>10 par page</target>
</segment>
</unit>
<unit id="2940591680142606604">
<segment state="initial">
<source>15 items per page</source>
<target>15 par page</target>
</segment>
</unit>
<unit id="9121589109350446305">
<segment state="initial">
<source>25 items per page</source>
<target>25 items per page</target>
</segment>
</unit>
<unit id="4791714722376172740">
<segment state="initial">
<source>50 items per page</source>
<target>50 par page</target>
</segment>
</unit>
<unit id="6810640416188824611">
<segment state="initial">
<source>100 items per page</source>
<target>100 par page</target>
</segment>
</unit>
<unit id="2454050363478003966">
<segment state="initial">
<source>Login</source>
<target>Connexion</target>
</segment>
</unit>
<unit id="140822705245800362">
<segment state="initial">
<source>Username:</source>
<target>Utilisateur:</target>
</segment>
</unit>
<unit id="6865009229971482891">
<segment state="initial">
<source>Password:</source>
<target>Mot de passe:</target>
</segment>
</unit>
<unit id="3797778920049399855">
<segment state="initial">
<source>Logout</source>
<target>Déconnexion</target>
</segment>
</unit>
<unit id="5674286808255988565">
<segment state="initial">
<source>Create</source>
<target>Créer</target>
</segment>
</unit>
<unit id="4021752662928002901">
<segment state="initial">
<source>Update</source>
<target>Mettre à jour</target>
</segment>
</unit>
</file>
</xliff>

View File

@@ -0,0 +1,296 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en-US">
<file id="ngi18n" original="ng.template">
<unit id="ngb.alert.close">
<segment>
<source>Close</source>
</segment>
</unit>
<unit id="ngb.timepicker.HH">
<segment>
<source>HH</source>
</segment>
</unit>
<unit id="ngb.toast.close-aria">
<segment>
<source>Close</source>
</segment>
</unit>
<unit id="ngb.pagination.first">
<segment>
<source>««</source>
</segment>
</unit>
<unit id="ngb.datepicker.select-month">
<segment>
<source>Select month</source>
</segment>
</unit>
<unit id="ngb.datepicker.previous-month">
<segment>
<source>Previous month</source>
</segment>
</unit>
<unit id="ngb.progressbar.value">
<segment>
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
</segment>
</unit>
<unit id="ngb.carousel.slide-number">
<segment>
<source> Slide <ph id="0" equiv="INTERPOLATION"/> of <ph id="1" equiv="INTERPOLATION_1"/> </source>
</segment>
</unit>
<unit id="ngb.timepicker.hours">
<segment>
<source>Hours</source>
</segment>
</unit>
<unit id="ngb.pagination.previous">
<segment>
<source>«</source>
</segment>
</unit>
<unit id="ngb.carousel.previous">
<segment>
<source>Previous</source>
</segment>
</unit>
<unit id="ngb.timepicker.MM">
<segment>
<source>MM</source>
</segment>
</unit>
<unit id="ngb.pagination.next">
<segment>
<source>»</source>
</segment>
</unit>
<unit id="ngb.datepicker.select-year">
<segment>
<source>Select year</source>
</segment>
</unit>
<unit id="ngb.datepicker.next-month">
<segment>
<source>Next month</source>
</segment>
</unit>
<unit id="ngb.carousel.next">
<segment>
<source>Next</source>
</segment>
</unit>
<unit id="ngb.timepicker.minutes">
<segment>
<source>Minutes</source>
</segment>
</unit>
<unit id="ngb.pagination.last">
<segment>
<source>»»</source>
</segment>
</unit>
<unit id="ngb.timepicker.increment-hours">
<segment>
<source>Increment hours</source>
</segment>
</unit>
<unit id="ngb.pagination.first-aria">
<segment>
<source>First</source>
</segment>
</unit>
<unit id="ngb.pagination.previous-aria">
<segment>
<source>Previous</source>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-hours">
<segment>
<source>Decrement hours</source>
</segment>
</unit>
<unit id="ngb.pagination.next-aria">
<segment>
<source>Next</source>
</segment>
</unit>
<unit id="ngb.timepicker.increment-minutes">
<segment>
<source>Increment minutes</source>
</segment>
</unit>
<unit id="ngb.pagination.last-aria">
<segment>
<source>Last</source>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-minutes">
<segment>
<source>Decrement minutes</source>
</segment>
</unit>
<unit id="ngb.timepicker.SS">
<segment>
<source>SS</source>
</segment>
</unit>
<unit id="ngb.timepicker.seconds">
<segment>
<source>Seconds</source>
</segment>
</unit>
<unit id="ngb.timepicker.increment-seconds">
<segment>
<source>Increment seconds</source>
</segment>
</unit>
<unit id="ngb.timepicker.decrement-seconds">
<segment>
<source>Decrement seconds</source>
</segment>
</unit>
<unit id="ngb.timepicker.PM">
<segment>
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
</segment>
</unit>
<unit id="ngb.timepicker.AM">
<segment>
<source>
<ph id="0" equiv="INTERPOLATION"/>
</source>
</segment>
</unit>
<unit id="2454050363478003966">
<segment>
<source>Login</source>
</segment>
</unit>
<unit id="140822705245800362">
<segment>
<source>Username:</source>
</segment>
</unit>
<unit id="6865009229971482891">
<segment>
<source>Password:</source>
</segment>
</unit>
<unit id="2159130950882492111">
<segment>
<source>Cancel</source>
</segment>
</unit>
<unit id="3797778920049399855">
<segment>
<source>Logout</source>
</segment>
</unit>
<unit id="6570363013146073520">
<segment>
<source>Dashboard</source>
</segment>
</unit>
<unit id="4800190016750145593">
<segment>
<source>Entities</source>
</segment>
</unit>
<unit id="3336127935693687033">
<segment>
<source>Provision&amp;nbsp;Templates</source>
</segment>
</unit>
<unit id="8996893897509995689">
<segment>
<source>Contracts&amp;nbsp;Templates</source>
</segment>
</unit>
<unit id="4480519554689195945">
<segment>
<source>Contracts&amp;nbsp;Drafts</source>
</segment>
</unit>
<unit id="6325430461732938793">
<segment>
<source>Contracts</source>
</segment>
</unit>
<unit id="3894950702316166331">
<segment>
<source>Loading...</source>
</segment>
</unit>
<unit id="6621329748219109148">
<segment>
<source>Duplicate</source>
</segment>
</unit>
<unit id="7022070615528435141">
<segment>
<source>Delete</source>
</segment>
</unit>
<unit id="6594772639285650443">
<segment>
<source>Are you sure you want to delete this <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/>?</source>
</segment>
</unit>
<unit id="2502514662075565663">
<segment>
<source>Duplicate <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/></source>
</segment>
</unit>
<unit id="5674286808255988565">
<segment>
<source>Create</source>
</segment>
</unit>
<unit id="4021752662928002901">
<segment>
<source>Update</source>
</segment>
</unit>
<unit id="5974043874204012120">
<segment>
<source> Create <ph id="0" equiv="INTERPOLATION" disp="{{ this.schema }}"/> </source>
</segment>
</unit>
<unit id="8449969376421674433">
<segment>
<source>Full text search:</source>
</segment>
</unit>
<unit id="7735090777677032335">
<segment>
<source>10 items per page</source>
</segment>
</unit>
<unit id="2940591680142606604">
<segment>
<source>15 items per page</source>
</segment>
</unit>
<unit id="9121589109350446305">
<segment>
<source>25 items per page</source>
</segment>
</unit>
<unit id="4791714722376172740">
<segment>
<source>50 items per page</source>
</segment>
</unit>
<unit id="6810640416188824611">
<segment>
<source>100 items per page</source>
</segment>
</unit>
</file>
</xliff>