diff --git a/demo-shell/src/app/components/date/date.component.scss b/demo-shell/src/app/components/date/date.component.scss
new file mode 100644
index 0000000000..720ae78a4d
--- /dev/null
+++ b/demo-shell/src/app/components/date/date.component.scss
@@ -0,0 +1,7 @@
+.adf-date-pipes-container {
+ padding: 20px;
+}
+
+.adf-date-field {
+ margin: 20px;
+}
diff --git a/demo-shell/src/app/components/date/date.component.ts b/demo-shell/src/app/components/date/date.component.ts
new file mode 100644
index 0000000000..372621d1d6
--- /dev/null
+++ b/demo-shell/src/app/components/date/date.component.ts
@@ -0,0 +1,36 @@
+/*!
+ * @license
+ * Copyright 2019 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component } from '@angular/core';
+import { AppConfigService } from '@alfresco/adf-core';
+
+@Component({
+ selector: 'app-date-page',
+ templateUrl: './date.component.html',
+ styleUrls: ['date.component.scss']
+})
+export class DateComponent {
+
+ today = new Date();
+ locale: string;
+ format: string;
+ languages: any[];
+
+ constructor(private appConfig: AppConfigService) {
+ this.languages = this.appConfig.get('languages', []);
+ }
+}
diff --git a/demo-shell/src/app/components/date/date.module.ts b/demo-shell/src/app/components/date/date.module.ts
new file mode 100644
index 0000000000..84d757f2d4
--- /dev/null
+++ b/demo-shell/src/app/components/date/date.module.ts
@@ -0,0 +1,39 @@
+/*!
+ * @license
+ * Copyright 2019 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { DateComponent } from './date.component';
+import { CommonModule } from '@angular/common';
+import { CoreModule } from '@alfresco/adf-core';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: DateComponent
+ }
+];
+
+@NgModule({
+ imports: [
+ CommonModule,
+ CoreModule.forChild(),
+ RouterModule.forChild(routes)
+ ],
+ declarations: [DateComponent]
+})
+export class AppDateModule {}
diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html
index 450ebec68d..d7278b7d82 100644
--- a/demo-shell/src/app/components/files/files.component.html
+++ b/demo-shell/src/app/components/files/files.component.html
@@ -250,12 +250,13 @@
key="$thumbnail"
type="image"
[sortable]="false"
- class="adf-image-table-cell "
+ class="adf-image-table-cell"
[class.adf-cell-thumbnail]="thumbnails">
@@ -282,7 +283,7 @@
key="content.sizeInBytes"
title="{{'DOCUMENT_LIST.COLUMNS.SIZE' | translate}}"
type="fileSize"
- class="adf-desktop-only">
+ class="adf-desktop-only adf-ellipsis-cell">
+ class="adf-desktop-only adf-ellipsis-cell">
+
+
diff --git a/demo-shell/src/app/components/task-list-demo/task-list-demo.component.html b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.html
index dd27c62036..3603077aa5 100644
--- a/demo-shell/src/app/components/task-list-demo/task-list-demo.component.html
+++ b/demo-shell/src/app/components/task-list-demo/task-list-demo.component.html
@@ -171,12 +171,12 @@
-
diff --git a/demo-shell/src/app/components/trashcan/trashcan.component.html b/demo-shell/src/app/components/trashcan/trashcan.component.html
index ff59b2c58f..da34b5f5cc 100644
--- a/demo-shell/src/app/components/trashcan/trashcan.component.html
+++ b/demo-shell/src/app/components/trashcan/trashcan.component.html
@@ -76,7 +76,7 @@
key="archivedAt"
title="DOCUMENT_LIST.COLUMNS.DELETED_ON">
- {{ value | adfTimeAgo: currentLocale }}
diff --git a/docs/core/pipes/localized-date.pipe.md b/docs/core/pipes/localized-date.pipe.md
new file mode 100644
index 0000000000..82cd1b1f8f
--- /dev/null
+++ b/docs/core/pipes/localized-date.pipe.md
@@ -0,0 +1,28 @@
+# [Localized Date pipe](../../../lib/core/pipes/localized-date.pipe.ts "Defined in localized-date.pipe.ts")
+
+Converts a date to an given format and locale.
+
+## Basic Usage
+
+
+
+```HTML
+
+ Created date: {{ date | adfLocalizedDate }}
+
+```
+
+
+
+### Properties
+
+| Name | Type | Default value | Description |
+| ---- | ---- | ------------- | ----------- |
+| format | string | 'medium' | A format to apply to the date value. [Date Pipe Formats.](https://angular.io/api/common/DatePipe#custom-format-options) |
+| locale | string | 'en-US' | A locale id for the locale format rules to use. |
+
+## Details
+
+The pipe takes a date and formats it and localizes it so the date is displayed in the proper format for the region. It uses the [Angular Date Pipe](https://angular.io/api/common/DatePipe#custom-format-options) so all the pre-defined and custom formats can be used.
+
+When localizing a date, you will need to add the specific locale file for your region in order to use it. Read more about internationalization [here](https://angular.io/guide/i18n#i18n-pipes).
diff --git a/docs/core/pipes/time-ago.pipe.md b/docs/core/pipes/time-ago.pipe.md
index a3d9874b8a..dd1a7989ae 100644
--- a/docs/core/pipes/time-ago.pipe.md
+++ b/docs/core/pipes/time-ago.pipe.md
@@ -21,8 +21,14 @@ Converts a recent past date into a number of days ago.
+| Name | Type | Default value | Description |
+| ---- | ---- | ------------- | ----------- |
+| locale | string | 'en-US' | A locale id for the locale format rules to use. |
+
## Details
The pipe finds the difference between the input date and the current date. If it
is less than seven days then then the date will be formatted as "X days ago".
Otherwise, the usual full date format is used.
+
+By default, it localizes the date to the language that is currently in use by the app. Furthermore, a different locale id can be passed to the pipe to overwrite the locale id to set a custom one.
diff --git a/docs/user-guide/internationalization.md b/docs/user-guide/internationalization.md
index f918fcc2c1..17c786adb1 100644
--- a/docs/user-guide/internationalization.md
+++ b/docs/user-guide/internationalization.md
@@ -18,6 +18,7 @@ fairly straightforward to maintain.
- [I18n concepts](#i18n-concepts)
- [ADF support for i18n](#adf-support-for-i18n)
- [Using the translate pipe](#using-the-translate-pipe)
+- [Using the localized date pipe](#using-the-localized-date-pipe)
- [Adding and replacing messages](#adding-and-replacing-messages)
- [Interpolations](#interpolations)
- [How the display language is selected](#how-the-display-language-is-selected)
@@ -153,6 +154,30 @@ component's `.ts` file:
+## Using the localized date pipe
+
+Date values are also localized in your ADF app. By default they are localized to en-US, although you can easily change this by adding the localization files provided by Angular.
+
+If you want to use a different locale simply add the locale file for your region in your `app.module.ts`.
+
+
+
+ import { registerLocaleData } from '@angular/common';
+ import localeFr from '@angular/common/locales/fr';
+
+ registerLocaleData(localeFr);
+
+
+
+Usage of the [localized date pipe](../core/pipes/localized-date.pipe.md).
+
+
+ {{ date | adfLocalizedDate: format : locale }}
+
+
+
+Find more info about this in the [Angular sDocs](https://angular.io/guide/i18n#setting-up-the-locale-of-your-app).
+
## Adding and replacing messages
The built-in translations certainly won't cover everything you will need for
diff --git a/e2e/process-services-cloud/process-header-cloud.e2e.ts b/e2e/process-services-cloud/process-header-cloud.e2e.ts
index d6a917ea5d..05acbf3638 100644
--- a/e2e/process-services-cloud/process-header-cloud.e2e.ts
+++ b/e2e/process-services-cloud/process-header-cloud.e2e.ts
@@ -44,7 +44,7 @@ describe('Process Header cloud component', () => {
const simpleApp = resources.ACTIVITI7_APPS.SIMPLE_APP.name;
const subProcessApp = resources.ACTIVITI7_APPS.SUB_PROCESS_APP.name;
- const formatDate = 'DD-MM-YYYY';
+ const formatDate = 'MMM D YYYY';
const processHeaderCloudPage = new ProcessHeaderCloudPage();
diff --git a/e2e/process-services-cloud/task-header-cloud.e2e.ts b/e2e/process-services-cloud/task-header-cloud.e2e.ts
index ae28db3401..44ea27b283 100644
--- a/e2e/process-services-cloud/task-header-cloud.e2e.ts
+++ b/e2e/process-services-cloud/task-header-cloud.e2e.ts
@@ -39,7 +39,7 @@ describe('Task Header cloud component', () => {
const simpleApp = resources.ACTIVITI7_APPS.SIMPLE_APP.name;
const priority = 30;
const description = 'descriptionTask';
- const formatDate = 'DD-MM-YYYY';
+ const formatDate = 'MMM D YYYY';
const taskHeaderCloudPage = new TaskHeaderCloudPage();
diff --git a/lib/core/app-config/schema.json b/lib/core/app-config/schema.json
index 1cb940c240..25f30c6455 100644
--- a/lib/core/app-config/schema.json
+++ b/lib/core/app-config/schema.json
@@ -518,6 +518,29 @@
}
}
},
+ "dateValues": {
+ "description": "Configuration of date formats in the app",
+ "type": "object",
+ "required": [
+ "defaultDateFormat",
+ "defaultDateTimeFormat",
+ "defaultLocale"
+ ],
+ "properties": {
+ "defaultDateFormat": {
+ "description": "Default date format",
+ "type": "string"
+ },
+ "defaultDateTimeFormat": {
+ "description": "Default date time format",
+ "type": "string"
+ },
+ "defaultLocale": {
+ "description": "Default date locale",
+ "type": "string"
+ }
+ }
+ },
"files": {
"description": "Configuration of rules applied to file upload",
"type": "object",
diff --git a/lib/core/card-view/components/card-view-dateitem/card-view-dateitem.component.ts b/lib/core/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
index 33174b3737..cbfd3df618 100644
--- a/lib/core/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
+++ b/lib/core/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
@@ -26,6 +26,7 @@ import { CardViewUpdateService } from '../../services/card-view-update.service';
import { UserPreferencesService, UserPreferenceValues } from '../../../services/user-preferences.service';
import { MomentDateAdapter } from '../../../utils/momentDateAdapter';
import { MOMENT_DATE_FORMATS } from '../../../utils/moment-date-formats.model';
+import { AppConfigService } from '../../../app-config/app-config.service';
@Component({
providers: [
@@ -40,8 +41,6 @@ import { MOMENT_DATE_FORMATS } from '../../../utils/moment-date-formats.model';
})
export class CardViewDateItemComponent implements OnInit {
- public SHOW_FORMAT: string = 'MMM DD YY';
-
@Input()
property: CardViewDateItemModel;
@@ -55,10 +54,13 @@ export class CardViewDateItemComponent implements OnInit {
public datepicker: MatDatetimepicker;
valueDate: Moment;
+ dateFormat: string;
constructor(private cardViewUpdateService: CardViewUpdateService,
private dateAdapter: DateAdapter,
- private userPreferencesService: UserPreferencesService) {
+ private userPreferencesService: UserPreferencesService,
+ private appConfig: AppConfigService) {
+ this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
}
ngOnInit() {
@@ -66,10 +68,10 @@ export class CardViewDateItemComponent implements OnInit {
this.dateAdapter.setLocale(locale);
});
- ( this.dateAdapter).overrideDisplayFormat = this.SHOW_FORMAT;
+ ( this.dateAdapter).overrideDisplayFormat = this.dateFormat;
if (this.property.value) {
- this.valueDate = moment(this.property.value, this.SHOW_FORMAT);
+ this.valueDate = moment(this.property.value, this.dateFormat);
}
}
@@ -87,7 +89,7 @@ export class CardViewDateItemComponent implements OnInit {
onDateChanged(newDateValue) {
if (newDateValue) {
- const momentDate = moment(newDateValue.value, this.SHOW_FORMAT, true);
+ const momentDate = moment(newDateValue.value, this.dateFormat, true);
if (momentDate.isValid()) {
this.valueDate = momentDate;
this.cardViewUpdateService.update(this.property, momentDate.toDate());
diff --git a/lib/core/core.module.ts b/lib/core/core.module.ts
index d724a1bf14..e56dc395ad 100644
--- a/lib/core/core.module.ts
+++ b/lib/core/core.module.ts
@@ -57,6 +57,41 @@ import { ExtensionsModule } from '@alfresco/adf-extensions';
import { directionalityConfigFactory } from './services/directionality-config-factory';
import { DirectionalityConfigService } from './services/directionality-config.service';
+import { registerLocaleData } from '@angular/common';
+import localeFr from '@angular/common/locales/fr';
+import localeDe from '@angular/common/locales/de';
+import localeIt from '@angular/common/locales/it';
+import localeEs from '@angular/common/locales/es';
+import localeJa from '@angular/common/locales/ja';
+import localeNl from '@angular/common/locales/nl';
+import localePt from '@angular/common/locales/pt';
+import localeNb from '@angular/common/locales/nb';
+import localeRu from '@angular/common/locales/ru';
+import localeCh from '@angular/common/locales/zh';
+import localeAr from '@angular/common/locales/ar';
+import localeCs from '@angular/common/locales/cs';
+import localePl from '@angular/common/locales/pl';
+import localeFi from '@angular/common/locales/fi';
+import localeDa from '@angular/common/locales/da';
+import localeSv from '@angular/common/locales/sv';
+
+registerLocaleData(localeFr);
+registerLocaleData(localeDe);
+registerLocaleData(localeIt);
+registerLocaleData(localeEs);
+registerLocaleData(localeJa);
+registerLocaleData(localeNl);
+registerLocaleData(localePt);
+registerLocaleData(localeNb);
+registerLocaleData(localeRu);
+registerLocaleData(localeCh);
+registerLocaleData(localeAr);
+registerLocaleData(localeCs);
+registerLocaleData(localePl);
+registerLocaleData(localeFi);
+registerLocaleData(localeDa);
+registerLocaleData(localeSv);
+
@NgModule({
imports: [
TranslateModule,
diff --git a/lib/core/datatable/components/datatable/datatable-cell.component.spec.ts b/lib/core/datatable/components/datatable/datatable-cell.component.spec.ts
index 31a00170a6..0ad003740d 100644
--- a/lib/core/datatable/components/datatable/datatable-cell.component.spec.ts
+++ b/lib/core/datatable/components/datatable/datatable-cell.component.spec.ts
@@ -28,14 +28,14 @@ describe('DataTableCellComponent', () => {
});
it('should use medium format by default', () => {
- const component = new DateCellComponent(null, null);
+ const component = new DateCellComponent(null, null, new AppConfigService(null));
expect(component.format).toBe('medium');
});
it('should use column format', () => {
const component = new DateCellComponent(null, {
nodeUpdated: new Subject()
- });
+ }, new AppConfigService(null));
component.column = {
key: 'created',
type: 'date',
@@ -49,7 +49,8 @@ describe('DataTableCellComponent', () => {
it('should update cell data on alfrescoApiService.nodeUpdated event', () => {
const component = new DateCellComponent(
null,
- alfrescoApiService
+ alfrescoApiService,
+ new AppConfigService(null)
);
component.column = {
@@ -83,7 +84,8 @@ describe('DataTableCellComponent', () => {
it('not should update cell data if ids don`t match', () => {
const component = new DateCellComponent(
null,
- alfrescoApiService
+ alfrescoApiService,
+ new AppConfigService(null)
);
component.column = {
diff --git a/lib/core/datatable/components/datatable/datatable.component.html b/lib/core/datatable/components/datatable/datatable.component.html
index abb42066bd..d5f667fe4b 100644
--- a/lib/core/datatable/components/datatable/datatable.component.html
+++ b/lib/core/datatable/components/datatable/datatable.component.html
@@ -121,8 +121,8 @@
{{ data.getValue(row, col) }}