diff --git a/docs/sites-dropdown.component.md b/docs/sites-dropdown.component.md
index 93e7c7130e..93424828da 100644
--- a/docs/sites-dropdown.component.md
+++ b/docs/sites-dropdown.component.md
@@ -30,6 +30,7 @@ Displays a dropdown menu to show and interact with the sites of the current user
| --- | --- | --- | --- |
| hideMyFiles | boolean | false | Hide the "My Files" option added to the list by default |
| siteList | any[] | null | A custom list of sites to be displayed by the dropdown. If no value is given, the sites of the current user are displayed by default. A list of objects only with properties 'title' and 'guid' is enough to be able to display the dropdown. |
+| placeholder | string | 'DROPDOWN.PLACEHOLDER_LABEL' | The placeholder text/the key from translation files for the placeholder text to be shown by default|
### Events
diff --git a/lib/content-services/content-node-selector/content-node-selector.component-data.interface.ts b/lib/content-services/content-node-selector/content-node-selector.component-data.interface.ts
index fd5b888735..66aaff996a 100644
--- a/lib/content-services/content-node-selector/content-node-selector.component-data.interface.ts
+++ b/lib/content-services/content-node-selector/content-node-selector.component-data.interface.ts
@@ -20,6 +20,7 @@ import { MinimalNodeEntryEntity } from 'alfresco-js-api';
export interface ContentNodeSelectorComponentData {
title: string;
+ actionName?: string;
currentFolderId?: string;
dropdownHideMyFiles?: boolean;
dropdownSiteList?: any[];
diff --git a/lib/content-services/content-node-selector/content-node-selector.component.html b/lib/content-services/content-node-selector/content-node-selector.component.html
index 81145d2431..6b73ff9468 100644
--- a/lib/content-services/content-node-selector/content-node-selector.component.html
+++ b/lib/content-services/content-node-selector/content-node-selector.component.html
@@ -28,6 +28,7 @@
@@ -96,7 +97,7 @@
[disabled]="!chosenNode"
class="adf-content-node-selector-actions-choose"
(click)="choose()"
- data-automation-id="content-node-selector-actions-choose">{{ 'NODE_SELECTOR.CHOOSE' | translate }}
+ data-automation-id="content-node-selector-actions-choose">{{ buttonActionName | translate }}
diff --git a/lib/content-services/content-node-selector/content-node-selector.component.scss b/lib/content-services/content-node-selector/content-node-selector.component.scss
index 66cf07d50c..38e7116b02 100644
--- a/lib/content-services/content-node-selector/content-node-selector.component.scss
+++ b/lib/content-services/content-node-selector/content-node-selector.component.scss
@@ -1,6 +1,7 @@
@mixin adf-content-node-selector-theme($theme) {
$primary: map-get($theme, primary);
- $accent: map-get($theme, accent);
+ $foreground: map-get($theme, foreground);
+ $background: map-get($theme, background);
.adf-content-node-selector-dialog {
@@ -27,11 +28,11 @@
width: 100%;
&-icon {
- color: rgba(0, 0, 0, 0.38);
+ color: mat-color($foreground, disabled-button);
cursor: pointer;
&:hover {
- color: rgba(0, 0, 0, 1);
+ color: mat-color($foreground, base);
}
}
}
@@ -41,9 +42,16 @@
transition: none;
}
+ .adf-site-dropdown-container {
+ .mat-form-field {
+ display: block;
+ margin-bottom: 15px;
+ }
+ }
+
.adf-site-dropdown-list-element {
width: 100%;
- margin-bottom: 20px;
+ margin-bottom: 0;
.mat-select-trigger {
font-size: 14px;
@@ -52,16 +60,17 @@
}
.adf-toolbar .mat-toolbar {
- border: none;
+ border-bottom-width: 0;
+ font-size: 14px;
}
&-list {
height: 200px;
overflow: auto;
- border: 1px solid rgba(0, 0, 0, 0.07);
+ border: 1px solid mat-color($foreground, base, 0.07);
.adf-highlight {
- color: mat-color($accent);;
+ color: mat-color($primary);
}
.adf-data-table {
@@ -97,10 +106,14 @@
&-actions {
padding: 8px;
- background-color: rgb(250, 250, 250);
+ background-color: mat-color($background, background);
display: flex;
justify-content: flex-end;
- color: rgb(121, 121, 121);
+ color: mat-color($foreground, secondary-text);
+
+ button {
+ text-transform: uppercase;
+ }
&:last-child {
margin-bottom: 0px;
@@ -116,6 +129,10 @@
&[disabled] {
opacity: 0.6;
}
+
+ &:enabled {
+ color: mat-color($primary);
+ }
}
}
}
diff --git a/lib/content-services/content-node-selector/content-node-selector.component.spec.ts b/lib/content-services/content-node-selector/content-node-selector.component.spec.ts
index 5972bfe68a..c190625e01 100644
--- a/lib/content-services/content-node-selector/content-node-selector.component.spec.ts
+++ b/lib/content-services/content-node-selector/content-node-selector.component.spec.ts
@@ -107,6 +107,7 @@ describe('ContentNodeSelectorComponent', () => {
beforeEach(async(() => {
data = {
title: 'Move along citizen...',
+ actionName: 'move',
select: new EventEmitter(),
rowFilter: () => {},
imageResolver: () => 'piccolo',
@@ -131,6 +132,12 @@ describe('ContentNodeSelectorComponent', () => {
expect(titleElement.nativeElement.innerText).toBe('Move along citizen...');
});
+ it('should have the INJECTED actionName on the name of the choose button', () => {
+ const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton).not.toBeNull();
+ expect(actionButton.nativeElement.innerText).toBe('NODE_SELECTOR.MOVE');
+ });
+
it('should pass through the injected currentFolderId to the documentlist', () => {
let documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
expect(documentList).not.toBeNull('Document list should be shown');
@@ -595,7 +602,7 @@ describe('ContentNodeSelectorComponent', () => {
});
});
- describe('Choose button', () => {
+ describe('Action button for the chosen node', () => {
const entry: MinimalNodeEntryEntity = {};
let hasPermission;
@@ -608,8 +615,8 @@ describe('ContentNodeSelectorComponent', () => {
it('should be disabled by default', () => {
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(true);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(true);
});
it('should become enabled after loading node with the necessary permissions', () => {
@@ -618,8 +625,8 @@ describe('ContentNodeSelectorComponent', () => {
component.documentList.ready.emit();
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(false);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(false);
});
it('should remain disabled after loading node without the necessary permissions', () => {
@@ -628,8 +635,8 @@ describe('ContentNodeSelectorComponent', () => {
component.documentList.ready.emit();
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(true);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(true);
});
it('should be enabled when clicking on a node (with the right permissions) in the list (onNodeSelect)', () => {
@@ -638,8 +645,8 @@ describe('ContentNodeSelectorComponent', () => {
component.onNodeSelect({ detail: { node: { entry } } });
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(false);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(false);
});
it('should remain disabled when clicking on a node (with the WRONG permissions) in the list (onNodeSelect)', () => {
@@ -648,8 +655,8 @@ describe('ContentNodeSelectorComponent', () => {
component.onNodeSelect({ detail: { node: { entry } } });
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(true);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(true);
});
it('should become disabled when clicking on a node (with the WRONG permissions) after previously selecting a right node', () => {
@@ -661,8 +668,8 @@ describe('ContentNodeSelectorComponent', () => {
component.onNodeSelect({ detail: { node: { entry } } });
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(true);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(true);
});
it('should be disabled when resetting the chosen node', () => {
@@ -673,8 +680,8 @@ describe('ContentNodeSelectorComponent', () => {
component.resetChosenNode();
fixture.detectChanges();
- let chooseButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
- expect(chooseButton.nativeElement.disabled).toBe(true);
+ let actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
+ expect(actionButton.nativeElement.disabled).toBe(true);
});
it('should make the call to get the corresponding node entry to emit when a site node is selected as destination', () => {
diff --git a/lib/content-services/content-node-selector/content-node-selector.component.ts b/lib/content-services/content-node-selector/content-node-selector.component.ts
index 3b355e46f6..794026ecd3 100644
--- a/lib/content-services/content-node-selector/content-node-selector.component.ts
+++ b/lib/content-services/content-node-selector/content-node-selector.component.ts
@@ -46,10 +46,14 @@ export class ContentNodeSelectorComponent implements OnInit {
pagination: Pagination;
skipCount: number = 0;
infiniteScroll: boolean = false;
+ buttonActionName: string;
@Input()
title: string;
+ @Input()
+ actionName: string;
+
@Input()
currentFolderId: string | null = null;
@@ -85,6 +89,7 @@ export class ContentNodeSelectorComponent implements OnInit {
@Optional() private containingDialog?: MatDialogRef) {
if (data) {
this.title = data.title;
+ this.actionName = data.actionName;
this.select = data.select;
this.currentFolderId = data.currentFolderId;
this.dropdownHideMyFiles = data.dropdownHideMyFiles;
@@ -92,6 +97,7 @@ export class ContentNodeSelectorComponent implements OnInit {
this.rowFilter = data.rowFilter;
this.imageResolver = data.imageResolver;
}
+ this.buttonActionName = this.actionName ? `NODE_SELECTOR.${this.actionName.toUpperCase()}` : 'NODE_SELECTOR.CHOOSE';
if (this.containingDialog) {
this.inDialog = true;
diff --git a/lib/content-services/document-list/services/node-actions.service.ts b/lib/content-services/document-list/services/node-actions.service.ts
index 377d5e39ba..42ccb6e951 100644
--- a/lib/content-services/document-list/services/node-actions.service.ts
+++ b/lib/content-services/document-list/services/node-actions.service.ts
@@ -86,7 +86,8 @@ export class NodeActionsService {
if (this.contentService.hasPermission(contentEntry, permission)) {
const data: ContentNodeSelectorComponentData = {
- title: `${action} ${contentEntry.name} to ...`,
+ title: `${action} '${contentEntry.name}' to ...`,
+ actionName: action,
currentFolderId: contentEntry.parentId,
rowFilter: this.rowFilter.bind(this, contentEntry.id),
imageResolver: this.imageResolver.bind(this),
diff --git a/lib/content-services/i18n/de.json b/lib/content-services/i18n/de.json
index 295f3645d9..40e2339672 100644
--- a/lib/content-services/i18n/de.json
+++ b/lib/content-services/i18n/de.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Abbrechen",
"CHOOSE": "Auswählen",
+ "COPY": "Kopieren",
+ "MOVE": "Verschieben",
"NO_RESULTS": "Keine Ergebnisse gefunden"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/en.json b/lib/content-services/i18n/en.json
index a29c74d08c..0c242715b1 100644
--- a/lib/content-services/i18n/en.json
+++ b/lib/content-services/i18n/en.json
@@ -60,7 +60,10 @@
"NODE_SELECTOR": {
"CANCEL": "Cancel",
"CHOOSE": "Choose",
- "NO_RESULTS": "No results found"
+ "COPY": "Copy",
+ "MOVE": "Move",
+ "NO_RESULTS": "No results found",
+ "SELECT_LOCATION": "Select Location"
},
"OPERATION": {
"SUCCES": {
diff --git a/lib/content-services/i18n/es.json b/lib/content-services/i18n/es.json
index e5148546ca..fc1c4cbc42 100644
--- a/lib/content-services/i18n/es.json
+++ b/lib/content-services/i18n/es.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Cancelar",
"CHOOSE": "Elegir",
+ "COPY": "Copiar",
+ "MOVE": "Mover",
"NO_RESULTS": "Ningún resultado encontrado"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/fr.json b/lib/content-services/i18n/fr.json
index a2438515b3..ee5b4847c0 100644
--- a/lib/content-services/i18n/fr.json
+++ b/lib/content-services/i18n/fr.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Annuler",
"CHOOSE": "Choisir",
+ "COPY": "Copier",
+ "MOVE": "Déplacer",
"NO_RESULTS": "Aucun résultat trouvé"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/it.json b/lib/content-services/i18n/it.json
index 83d776f7dd..ee66c94228 100644
--- a/lib/content-services/i18n/it.json
+++ b/lib/content-services/i18n/it.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Annulla",
"CHOOSE": "Scegli",
+ "COPY": "Copia",
+ "MOVE": "Sposta",
"NO_RESULTS": "Nessun risultato trovato"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/ja.json b/lib/content-services/i18n/ja.json
index 2239a0fb43..e5d050f084 100644
--- a/lib/content-services/i18n/ja.json
+++ b/lib/content-services/i18n/ja.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "キャンセル",
"CHOOSE": "選択",
+ "COPY": "コピー",
+ "MOVE": "移動",
"NO_RESULTS": "一致するアイテムはありません"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/nb.json b/lib/content-services/i18n/nb.json
index 1848373066..040fad2225 100644
--- a/lib/content-services/i18n/nb.json
+++ b/lib/content-services/i18n/nb.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Avbryt",
"CHOOSE": "Velg",
+ "COPY": "Kopier",
+ "MOVE": "Flytt",
"NO_RESULTS": "Ingen resultater funnet"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/nl.json b/lib/content-services/i18n/nl.json
index 1e2861dd93..ab84be4e38 100644
--- a/lib/content-services/i18n/nl.json
+++ b/lib/content-services/i18n/nl.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Annuleren",
"CHOOSE": "Kiezen",
+ "COPY": "Kopiëren",
+ "MOVE": "Verplaatsen",
"NO_RESULTS": "Geen resultaten gevonden"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/pt-BR.json b/lib/content-services/i18n/pt-BR.json
index ccb2f88867..7f0a53083c 100644
--- a/lib/content-services/i18n/pt-BR.json
+++ b/lib/content-services/i18n/pt-BR.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Cancelar",
"CHOOSE": "Escolher",
+ "COPY": "Copiar",
+ "MOVE": "Mover",
"NO_RESULTS": "Nenhum resultado encontrado"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/ru.json b/lib/content-services/i18n/ru.json
index 46282d6dea..a78ca9cba3 100644
--- a/lib/content-services/i18n/ru.json
+++ b/lib/content-services/i18n/ru.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "Отмена",
"CHOOSE": "Выбрать",
+ "COPY": "Копировать",
+ "MOVE": "Переместить",
"NO_RESULTS": "Результаты не найдены"
},
"OPERATION": {
diff --git a/lib/content-services/i18n/zh-CN.json b/lib/content-services/i18n/zh-CN.json
index 3b30782fa9..af51418d22 100644
--- a/lib/content-services/i18n/zh-CN.json
+++ b/lib/content-services/i18n/zh-CN.json
@@ -60,6 +60,8 @@
"NODE_SELECTOR": {
"CANCEL": "取消",
"CHOOSE": "选择",
+ "COPY": "复制",
+ "MOVE": "移动",
"NO_RESULTS": "未找到结果"
},
"OPERATION": {
diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.html b/lib/content-services/site-dropdown/sites-dropdown.component.html
index 64978c7eae..941335de2c 100644
--- a/lib/content-services/site-dropdown/sites-dropdown.component.html
+++ b/lib/content-services/site-dropdown/sites-dropdown.component.html
@@ -3,7 +3,7 @@
{
TestBed.resetTestingModule();
});
- it('Dropdown sites should be renedered', async(() => {
+ it('Dropdown sites should be rendered', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
@@ -145,24 +145,78 @@ describe('DropdownSitesComponent', () => {
});
}));
- // todo: something wrong with the test itself
- xit('should load sites on init', async(() => {
+ it('should show the default placeholder label by default', async(() => {
+ fixture.detectChanges();
+ jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentType: 'json', responseText: sitesList });
+
+ openSelectbox();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ expect(fixture.nativeElement.innerText.trim()).toBe('DROPDOWN.PLACEHOLDER_LABEL');
+ });
+ }));
+
+ it('should show custom placeholder label when the \'placeholder\' input property is given a value', async(() => {
+ component.placeholder = 'NODE_SELECTOR.SELECT_LOCATION';
+ fixture.detectChanges();
+ jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentType: 'json', responseText: sitesList });
+
+ openSelectbox();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ expect(fixture.nativeElement.innerText.trim()).toBe('NODE_SELECTOR.SELECT_LOCATION');
+ });
+ }));
+
+ it('should load custom sites when the \'siteList\' input property is given a value', async(() => {
+ component.siteList = [{title: 'PERSONAL_FILES', guid: '-my-'}, {title: 'FILE_LIBRARIES', guid: '-mysites-'}];
+ fixture.detectChanges();
+
+ openSelectbox();
+
+ let options: any = [];
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ options = debug.queryAll(By.css('mat-option'));
+ options[0].triggerEventHandler('click', null);
+ fixture.detectChanges();
+ });
+
+ component.change.subscribe(() => {
+ expect(options[0].attributes['ng-reflect-value']).toBe('default');
+ expect(options[1].attributes['ng-reflect-value']).toBe('-my-');
+ expect(options[2].attributes['ng-reflect-value']).toBe('-mysites-');
+ });
+ }));
+
+ it('should load sites by default', (done) => {
fixture.detectChanges();
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json',
responseText: sitesList
});
+
+ openSelectbox();
+
+ let options: any = [];
fixture.whenStable().then(() => {
fixture.detectChanges();
- debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
+ options = debug.queryAll(By.css('mat-option'));
+ options[0].triggerEventHandler('click', null);
fixture.detectChanges();
- let options: any = debug.queryAll(By.css('mat-option'));
+ });
+
+ component.change.subscribe(() => {
expect(options[0].attributes['ng-reflect-value']).toBe('default');
expect(options[1].attributes['ng-reflect-value']).toBe('fake-1');
expect(options[2].attributes['ng-reflect-value']).toBe('fake-2');
+
+ done();
});
- }));
+ });
it('should raise an event when a site is selected', (done) => {
fixture.detectChanges();
diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.ts b/lib/content-services/site-dropdown/sites-dropdown.component.ts
index f9dc01e91a..10cc2e054b 100644
--- a/lib/content-services/site-dropdown/sites-dropdown.component.ts
+++ b/lib/content-services/site-dropdown/sites-dropdown.component.ts
@@ -31,6 +31,9 @@ export class DropdownSitesComponent implements OnInit {
@Input()
siteList: any[] = null;
+ @Input()
+ placeholder: string = 'DROPDOWN.PLACEHOLDER_LABEL';
+
@Output()
change: EventEmitter = new EventEmitter();