Merge pull request #339 from Alfresco/dev-wabson-302

Accessibility improvements for search
This commit is contained in:
Mario Romano 2016-07-04 10:42:38 +01:00 committed by GitHub
commit c4dba90332
7 changed files with 86 additions and 39 deletions

View File

@ -12,6 +12,19 @@
"MODIFIED_BY": "Modified by", "MODIFIED_BY": "Modified by",
"MODIFIED_AT": "Modified at" "MODIFIED_AT": "Modified at"
} }
},
"ICONS": {
"ft_ic_raster_image": "Image file",
"ft_ic_pdf": "PDF document",
"ft_ic_ms_excel": "Microsoft Excel file",
"ft_ic_ms_word": "Microsoft Word document",
"ft_ic_ms_powerpoint": "Microsoft PowerPoint file",
"ft_ic_video": "Video file",
"ft_ic_document": "Document file",
"ft_ic_website": "Web resource",
"ft_ic_archive": "Acrchive file",
"ft_ic_presentation": "Presentation file",
"ft_ic_spreadsheet": "Spreadsheet file"
} }
} }
} }

View File

@ -2,7 +2,7 @@
<tbody> <tbody>
<tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)" <tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)"
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}" > attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}" >
<td class="img-td"><img src="{{_getMimeTypeIcon(result)}}" /></td> <td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}" /></td>
<td><div class="truncate" ><b>{{result.entry.name}}</b></div><div class="truncate">{{result.entry.createdByUser.displayName}}</div></td> <td><div class="truncate" ><b>{{result.entry.name}}</b></div><div class="truncate">{{result.entry.createdByUser.displayName}}</div></td>
</tr> </tr>
</tbody> </tbody>

View File

@ -53,9 +53,9 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
@Output() @Output()
preview: EventEmitter<any> = new EventEmitter(); preview: EventEmitter<any> = new EventEmitter();
constructor(private _alfrescoSearchService: AlfrescoSearchService, constructor(private alfrescoSearchService: AlfrescoSearchService,
private translate: AlfrescoTranslationService, private translate: AlfrescoTranslationService,
private _alfrescoThumbnailService: AlfrescoThumbnailService) { private alfrescoThumbnailService: AlfrescoThumbnailService) {
if (translate) { if (translate) {
translate.addTranslationFolder('node_modules/ng2-alfresco-search'); translate.addTranslationFolder('node_modules/ng2-alfresco-search');
} }
@ -74,7 +74,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
*/ */
public displaySearchResults(searchTerm) { public displaySearchResults(searchTerm) {
if (searchTerm !== null && searchTerm !== '') { if (searchTerm !== null && searchTerm !== '') {
this._alfrescoSearchService this.alfrescoSearchService
.getLiveSearchResults(searchTerm) .getLiveSearchResults(searchTerm)
.subscribe( .subscribe(
results => { results => {
@ -94,13 +94,26 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
* @param node Node to get URL for. * @param node Node to get URL for.
* @returns {string} URL address. * @returns {string} URL address.
*/ */
_getMimeTypeIcon(node: any): string { getMimeTypeIcon(node: any): string {
if (node.entry.content && node.entry.content.mimeType) { if (node.entry.content && node.entry.content.mimeType) {
let icon = this._alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType); let icon = this.alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType);
return `${this.baseComponentPath}/img/${icon}`; return `${this.baseComponentPath}/img/${icon}`;
} }
} }
/**
* Gets thumbnail message key for the given document node, which can be used to look up alt text
* @param node Node to get URL for.
* @returns {string} URL address.
*/
getMimeTypeKey(node: any): string {
if (node.entry.content && node.entry.content.mimeType) {
return 'SEARCH.ICONS.' + this.alfrescoThumbnailService.getMimeTypeKey(node.entry.content.mimeType);
} else {
return '';
}
}
onItemClick(node, event?: Event): void { onItemClick(node, event?: Event): void {
if (event) { if (event) {
event.preventDefault(); event.preventDefault();

View File

@ -6,8 +6,8 @@
<div [class]="getTextFieldHolderClassName()"> <div [class]="getTextFieldHolderClassName()">
<input class="mdl-textfield__input" [type]="inputType" [autocomplete]="getAutoComplete()" data-automation-id="search_input" <input class="mdl-textfield__input" [type]="inputType" [autocomplete]="getAutoComplete()" data-automation-id="search_input"
#searchInput id="searchControl" [ngFormControl]="searchControl" [(ngModel)]="searchTerm" (focus)="onFocus($event)" #searchInput id="searchControl" [ngFormControl]="searchControl" [(ngModel)]="searchTerm" (focus)="onFocus($event)"
(blur)="onBlur($event)"> (blur)="onBlur($event)" aria-labelledby="searchLabel">
<label class="mdl-textfield__label" for="searchControl">{{'SEARCH.CONTROL.LABEL' | translate}}</label> <label id="searchLabel" class="mdl-textfield__label" for="searchControl">{{'SEARCH.CONTROL.LABEL' | translate}}</label>
</div> </div>
</div> </div>
</form> </form>

View File

@ -1,9 +1,9 @@
<p data-automation-id="search_result_found" *ngIf="results && results.length">{{ 'SEARCH.RESULTS.SUMMARY' | translate:{numResults: results.length, searchTerm: searchTerm} }}</p>
<p data-automation-id="search_no_result_found" *ngIf="results&& results.length == 0">{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</p> <p data-automation-id="search_no_result_found" *ngIf="results&& results.length == 0">{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</p>
<table data-automation-id="search_result_table" *ngIf="results && results.length && searchTerm" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width"> <table data-automation-id="search_result_table" *ngIf="results && results.length && searchTerm" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
<caption data-automation-id="search_result_found">{{ 'SEARCH.RESULTS.SUMMARY' | translate:{numResults: results.length, searchTerm: searchTerm} }}</caption>
<thead> <thead>
<tr> <tr>
<th class="mdl-data-table__cell--non-numeric col-mimetype-icon"></th> <td class="mdl-data-table__cell--non-numeric col-mimetype-icon"></td>
<th class="mdl-data-table__cell--non-numeric col-display-name"> <th class="mdl-data-table__cell--non-numeric col-display-name">
{{'SEARCH.RESULTS.COLUMNS.NAME' | translate}} {{'SEARCH.RESULTS.COLUMNS.NAME' | translate}}
</th> </th>
@ -18,7 +18,7 @@
<tbody> <tbody>
<tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)"> <tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)">
<td class="col-mimetype-icon"><img src="{{getMimeTypeIcon(result)}}" /></td> <td class="col-mimetype-icon"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}" /></td>
<td class="mdl-data-table__cell--non-numeric col-display-name" <td class="mdl-data-table__cell--non-numeric col-display-name"
attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td> attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td>
<td class="mdl-data-table__cell--non-numeric col-modified-by" <td class="mdl-data-table__cell--non-numeric col-modified-by"

View File

@ -27,6 +27,10 @@ declare let __moduleName: string;
moduleId: __moduleName, moduleId: __moduleName,
selector: 'alfresco-search', selector: 'alfresco-search',
styles: [` styles: [`
:host .mdl-data-table caption {
margin: 0 0 16px 0;
text-align: left;
}
:host .mdl-data-table td { :host .mdl-data-table td {
max-width: 0; max-width: 0;
white-space: nowrap; white-space: nowrap;
@ -95,6 +99,19 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
} }
} }
/**
* Gets thumbnail message key for the given document node, which can be used to look up alt text
* @param node Node to get URL for.
* @returns {string} URL address.
*/
getMimeTypeKey(node: any): string {
if (node.entry.content && node.entry.content.mimeType) {
return 'SEARCH.ICONS.' + this._alfrescoThumbnailService.getMimeTypeKey(node.entry.content.mimeType);
} else {
return '';
}
}
/** /**
* Loads and displays search results * Loads and displays search results
* @param searchTerm Search query entered by user * @param searchTerm Search query entered by user

View File

@ -26,32 +26,32 @@ declare let AlfrescoApi: any;
export class AlfrescoThumbnailService { export class AlfrescoThumbnailService {
mimeTypeIcons: any = { mimeTypeIcons: any = {
'image/png': 'ft_ic_raster_image.svg', 'image/png': 'ft_ic_raster_image',
'image/jpeg': 'ft_ic_raster_image.svg', 'image/jpeg': 'ft_ic_raster_image',
'image/gif': 'ft_ic_raster_image.svg', 'image/gif': 'ft_ic_raster_image',
'application/pdf': 'ft_ic_pdf.svg', 'application/pdf': 'ft_ic_pdf',
'application/vnd.ms-excel': 'ft_ic_ms_excel.svg', 'application/vnd.ms-excel': 'ft_ic_ms_excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'ft_ic_ms_excel.svg', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'ft_ic_ms_excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template': 'ft_ic_ms_excel.svg', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': 'ft_ic_ms_excel',
'application/msword': 'ft_ic_ms_word.svg', 'application/msword': 'ft_ic_ms_word',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'ft_ic_ms_word.svg', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'ft_ic_ms_word',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'ft_ic_ms_word.svg', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'ft_ic_ms_word',
'application/vnd.ms-powerpoint': 'ft_ic_ms_powerpoint.svg', 'application/vnd.ms-powerpoint': 'ft_ic_ms_powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'ft_ic_ms_powerpoint.svg', 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'ft_ic_ms_powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.template': 'ft_ic_ms_powerpoint.svg', 'application/vnd.openxmlformats-officedocument.presentationml.template': 'ft_ic_ms_powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow': 'ft_ic_ms_powerpoint.svg', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow': 'ft_ic_ms_powerpoint',
'video/mp4': 'ft_ic_video.svg', 'video/mp4': 'ft_ic_video',
'text/plain': 'ft_ic_document.svg', 'text/plain': 'ft_ic_document',
'application/x-javascript': 'ft_ic_document.svg', 'application/x-javascript': 'ft_ic_document',
'application/json': 'ft_ic_document.svg', 'application/json': 'ft_ic_document',
'image/svg+xml': 'ft_ic_vector_image.svg', 'image/svg+xml': 'ft_ic_vector_image',
'text/html': 'ft_ic_website.svg', 'text/html': 'ft_ic_website',
'application/x-compressed': 'ft_ic_archive.svg', 'application/x-compressed': 'ft_ic_archive',
'application/x-zip-compressed': 'ft_ic_archive.svg', 'application/x-zip-compressed': 'ft_ic_archive',
'application/zip': 'ft_ic_archive.svg', 'application/zip': 'ft_ic_archive',
'application/vnd.apple.keynote': 'ft_ic_presentation.svg', 'application/vnd.apple.keynote': 'ft_ic_presentation',
'application/vnd.apple.pages': 'ft_ic_document.svg', 'application/vnd.apple.pages': 'ft_ic_document',
'application/vnd.apple.numbers': 'ft_ic_spreadsheet.svg' 'application/vnd.apple.numbers': 'ft_ic_spreadsheet'
}; };
constructor(private contentService: AlfrescoContentService) { constructor(private contentService: AlfrescoContentService) {
@ -66,8 +66,12 @@ export class AlfrescoThumbnailService {
return this.contentService.getDocumentThumbnailUrl(document); return this.contentService.getDocumentThumbnailUrl(document);
} }
public getMimeTypeIcon(mimeType: string): string { public getMimeTypeKey(mimeType: string): string {
let icon = this.mimeTypeIcons[mimeType]; let icon = this.mimeTypeIcons[mimeType];
return icon || 'ft_ic_miscellaneous.svg'; return icon || 'ft_ic_miscellaneous';
}
public getMimeTypeIcon(mimeType: string): string {
return this.getMimeTypeKey(mimeType) + '.svg';
} }
} }