[ADF-1555] add animation on show and hide of results (#2343)

* add animation on show and hide of results
make the style similar to the other material 2 menu
fix issue popup always stays on the screen
fix Search does not collapse if its input is focused

* minor code style issues

* minors fix and test fix

* fix app.config.json error in test

* update beta10 mat-menu-base method

* karma configuration all
This commit is contained in:
Eugenio Romano 2017-09-18 11:06:45 +01:00 committed by Popovics András
parent 7157d60ed0
commit cd46a589e1
46 changed files with 351 additions and 181 deletions

View File

@ -19,7 +19,7 @@ install:
if ([ "$TRAVIS_BRANCH" = "master" ]); then if ([ "$TRAVIS_BRANCH" = "master" ]); then
(./scripts/npm-build-all.sh || exit 1;); (./scripts/npm-build-all.sh || exit 1;);
else else
(./scripts/npm-build-all.sh -gitjsapi development || exit 1;); (./scripts/npm-build-all.sh -vjsapi alpha || exit 1;);
fi fi
fi fi
@ -34,7 +34,7 @@ script:
if ([ "$TRAVIS_BRANCH" = "master" ]); then if ([ "$TRAVIS_BRANCH" = "master" ]); then
(./scripts/start.sh -t -ss || exit 1;); (./scripts/start.sh -t -ss || exit 1;);
else else
(./scripts/start.sh -dev -t -ss -gitjsapi development || exit 1;); (./scripts/start.sh -dev -t -ss -vjsapi alpha || exit 1;);
fi fi
fi fi

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -36,7 +36,8 @@ module.exports = function (config) {
{pattern: config.component + '/karma-test-shim.js', watched: false}, {pattern: config.component + '/karma-test-shim.js', watched: false},
{pattern: './ng2-**/src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './ng2-**/src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './ng2-**/src/**/*.ts', included: false, served: true, watched: false} {pattern: './ng2-**/src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: webpackCoverage(config), webpack: webpackCoverage(config),
@ -50,6 +51,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -23,7 +23,9 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -34,6 +36,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -23,7 +23,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -34,6 +35,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -18,7 +18,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -29,6 +30,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -1,42 +1,42 @@
<table data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm" <table class="full-width adf-search-result"
class="full-width adf-search-result"> [@transformAutocomplete]="panelAnimationState"
<tbody #resultsTableBody> (@transformAutocomplete.done)="onAnimationDone($event)">
<tbody #resultsTableBody data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm">
<tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" tabindex="0" <tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" tabindex="0"
(blur)="onRowBlur($event)" (focus)="onRowFocus($event)" (blur)="onRowBlur($event)" (focus)="onRowFocus($event)"
(click)="onItemClick(result)" (click)="onItemClick(result)"
(keyup.enter)="onRowEnter(result)" (keyup.enter)="onRowEnter(result)"
(keyup.arrowdown)="onRowArrowDown($event)" (keyup.arrowdown)="onRowArrowDown($event)"
(keyup.arrowup)="onRowArrowUp($event)" (keyup.arrowup)="onRowArrowUp($event)"
(keyup.escape)="onRowEscape($event)" (keyup.escape)="onRowEscape($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)}}" alt="{{result.entry.name}}"/></td> <td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{result.entry.name}}"/></td>
<td> <td>
<div id="result_name_{{idx}}" *ngIf="highlight; else elseBlock" class="truncate" [innerHtml]="result.entry.name | highlight: searchTerm"></div> <div id="result_name_{{idx}}" *ngIf="highlight; else elseBlock" class="truncate"
[innerHtml]="result.entry.name | highlight: searchTerm"></div>
<ng-template #elseBlock> <ng-template #elseBlock>
<div id="result_name_{{idx}}" class="truncate" [innerHtml]="result.entry.name"></div> <div id="result_name_{{idx}}" class="truncate" [innerHtml]="result.entry.name"></div>
</ng-template> </ng-template>
<div id="result_user_{{idx}}" class="truncate">{{result.entry.createdByUser.displayName}}</div> <div id="result_user_{{idx}}" class="truncate">{{result.entry.createdByUser.displayName}}</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table>
<table id="search_no_result" data-automation-id="search_no_result_found" *ngIf="results && results.length === 0" <tbody id="search_no_result" data-automation-id="search_no_result_found" *ngIf="results && results.length === 0"
class="full-width adf-search-result"> class="full-width adf-search-result">
<tbody>
<tr> <tr>
<td> <td>
<div class="truncate"><b> {{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</b></div> <div class="truncate"><b> {{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</b></div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table>
<table data-automation-id="autocomplete_error_message" *ngIf="errorMessage" <tbody data-automation-id="autocomplete_error_message" *ngIf="errorMessage"
class="full-width adf-search-result"> class="full-width adf-search-result">
<tbody>
<tr> <tr>
<td>{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}</td> <td>{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,20 +1,28 @@
@import '~@angular/material/theming';
@mixin mat-search-autocomplete-theme($theme) { @mixin mat-search-autocomplete-theme($theme) {
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$accent: map-get($theme, accent); $accent: map-get($theme, accent);
$warn: map-get($theme, warn); $warn: map-get($theme, warn);
$foreground: map-get($theme, foreground); $foreground: map-get($theme, foreground);
$background: map-get($theme, background); $background: map-get($theme, background);
$mat-menu-border-radius: 2px !default;
.adf { .adf {
&--search-result-container{
z-index: 5;
}
&-search-result { &-search-result {
@include mat-menu-base(2);
transform-origin: top left;
position: absolute; position: absolute;
z-index: 5; z-index: 5;
display: none;
color: mat-color($foreground, text); color: mat-color($foreground, text);
background-color: mat-color($background, card); background-color: mat-color($background, card);
margin: -21px 0px 0px 0px; margin: -21px 0 0 0;
border: 1px solid mat-color($primary); border-radius: $mat-menu-border-radius;
border-collapse: collapse; border-collapse: collapse;
white-space: nowrap; white-space: nowrap;
font-size: 14px; font-size: 14px;
@ -48,11 +56,11 @@
color: mat-color($primary, 900); color: mat-color($primary, 900);
} }
.img-td{ .img-td {
width: 30px; width: 30px;
} }
.truncate{ .truncate {
width: 240px; width: 240px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@ -63,16 +71,10 @@
:host { :host {
right: 0; right: 0;
} }
.truncate{ .truncate {
width: 200px; width: 200px;
} }
} }
} }
&-valid-search {
.adf-search-result {
display: block;
}
}
} }
} }

View File

@ -84,7 +84,7 @@ describe('SearchAutocompleteComponent', () => {
component.searchTerm = 'searchTerm2'; component.searchTerm = 'searchTerm2';
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm2', previousValue: 'searchTerm'} }); component.ngOnChanges({searchTerm: { currentValue: 'searchTerm2', previousValue: 'searchTerm'} });
fixture.detectChanges(); fixture.detectChanges();
expect(element.querySelectorAll('table[data-automation-id="autocomplete_results"] tbody tr').length).toBe(0); expect(element.querySelectorAll('tbody[data-automation-id="autocomplete_results"] tr').length).toBe(0);
}); });
})); }));
@ -110,7 +110,7 @@ describe('SearchAutocompleteComponent', () => {
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
let el: any = element.querySelectorAll('table[data-automation-id="autocomplete_results"] tbody tr')[1].children[1].children[0]; let el: any = element.querySelectorAll('tbody[data-automation-id="autocomplete_results"] tr')[1].children[1].children[0];
expect(el.innerText).toEqual('MyDoc'); expect(el.innerText).toEqual('MyDoc');
let spanHighlight = el.children[0]; let spanHighlight = el.children[0];
expect(spanHighlight.classList[0]).toEqual('highlight'); expect(spanHighlight.classList[0]).toEqual('highlight');
@ -129,7 +129,7 @@ describe('SearchAutocompleteComponent', () => {
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(element.querySelectorAll('table[data-automation-id="autocomplete_results"] tbody tr').length).toBe(2); expect(element.querySelectorAll('tbody[data-automation-id="autocomplete_results"] tr').length).toBe(2);
done(); done();
}); });

View File

@ -15,6 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';
import { Component, ElementRef, EventEmitter, Input, OnChanges, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { Component, ElementRef, EventEmitter, Input, OnChanges, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { SearchOptions, SearchService } from 'ng2-alfresco-core'; import { SearchOptions, SearchService } from 'ng2-alfresco-core';
@ -24,6 +25,24 @@ import { ThumbnailService } from 'ng2-alfresco-core';
selector: 'adf-search-autocomplete, alfresco-search-autocomplete', selector: 'adf-search-autocomplete, alfresco-search-autocomplete',
templateUrl: './search-autocomplete.component.html', templateUrl: './search-autocomplete.component.html',
styleUrls: ['./search-autocomplete.component.scss'], styleUrls: ['./search-autocomplete.component.scss'],
animations: [
trigger('transformAutocomplete', [
state('void', style({
opacity: 0,
transform: 'scale(0.01, 0.01)'
})),
state('enter-start', style({
opacity: 1,
transform: 'scale(1, 0.5)'
})),
state('enter', style({
transform: 'scale(1, 1)'
})),
transition('void => enter-start', animate('100ms linear')),
transition('enter-start => enter', animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
transition('* => void', animate('150ms 50ms linear', style({opacity: 0})))
])
],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class SearchAutocompleteComponent implements OnChanges { export class SearchAutocompleteComponent implements OnChanges {
@ -33,7 +52,7 @@ export class SearchAutocompleteComponent implements OnChanges {
results: any = null; results: any = null;
errorMessage; errorMessage: string = null;
@Input() @Input()
ngClass: any; ngClass: any;
@ -70,6 +89,8 @@ export class SearchAutocompleteComponent implements OnChanges {
@ViewChild('resultsTableBody', {}) resultsTableBody: ElementRef; @ViewChild('resultsTableBody', {}) resultsTableBody: ElementRef;
panelAnimationState: 'void' | 'enter-start' | 'enter' = 'void';
constructor(private searchService: SearchService, constructor(private searchService: SearchService,
private thumbnailService: ThumbnailService) { private thumbnailService: ThumbnailService) {
} }
@ -101,6 +122,11 @@ export class SearchAutocompleteComponent implements OnChanges {
.subscribe( .subscribe(
results => { results => {
this.results = results.list.entries.slice(0, this.maxResults); this.results = results.list.entries.slice(0, this.maxResults);
if (results && results.list && results.list.entries.length > 0) {
this.startAnimation();
}
this.errorMessage = null; this.errorMessage = null;
this.resultsLoad.emit(this.results); this.resultsLoad.emit(this.results);
}, },
@ -136,6 +162,14 @@ export class SearchAutocompleteComponent implements OnChanges {
firstResult.focus(); firstResult.focus();
} }
private getNextElementSibling(node: Element): Element {
return node.nextElementSibling;
}
private getPreviousElementSibling(node: Element): Element {
return node.previousElementSibling;
}
onItemClick(node: MinimalNodeEntity): void { onItemClick(node: MinimalNodeEntity): void {
if (node && node.entry) { if (node && node.entry) {
this.fileSelect.emit(node); this.fileSelect.emit(node);
@ -158,14 +192,6 @@ export class SearchAutocompleteComponent implements OnChanges {
} }
} }
private getNextElementSibling(node: Element): Element {
return node.nextElementSibling;
}
private getPreviousElementSibling(node: Element): Element {
return node.previousElementSibling;
}
onRowArrowDown($event: KeyboardEvent): void { onRowArrowDown($event: KeyboardEvent): void {
let nextElement: any = this.getNextElementSibling(<Element> $event.target); let nextElement: any = this.getNextElementSibling(<Element> $event.target);
if (nextElement) { if (nextElement) {
@ -186,4 +212,18 @@ export class SearchAutocompleteComponent implements OnChanges {
this.cancel.emit($event); this.cancel.emit($event);
} }
startAnimation() {
this.panelAnimationState = 'enter-start';
}
resetAnimation() {
this.panelAnimationState = 'void';
}
onAnimationDone(event: AnimationEvent) {
if (event.toState === 'enter-start') {
this.panelAnimationState = 'enter';
}
}
} }

View File

@ -1,6 +1,6 @@
<form #f="ngForm" (ngSubmit)="onSearch(f.value)" class="adf-search-form"> <form #f="ngForm" (ngSubmit)="onSearch(f.value)" class="adf-search-form">
<div class="adf-search-container" <div class="adf-search-container"
[@transitionMessages]="_subscriptAnimationState"> [@transitionMessages]="subscriptAnimationState">
<button md-button <button md-button
(click)="onClickSearch()" (click)="onClickSearch()"
*ngIf="expandable" *ngIf="expandable"
@ -35,8 +35,6 @@
[resultSort]="liveSearchResultSort" [resultSort]="liveSearchResultSort"
[maxResults]="liveSearchMaxResults" [maxResults]="liveSearchMaxResults"
[highlight]="highlight" [highlight]="highlight"
[class.adf-active-search]="searchActive"
[class.adf-valid-search]="searchValid"
(fileSelect)="onFileClicked($event)" (fileSelect)="onFileClicked($event)"
(searchFocus)="onAutoCompleteFocus($event)" (searchFocus)="onAutoCompleteFocus($event)"
(scrollBack)="onAutoCompleteReturn($event)" (scrollBack)="onAutoCompleteReturn($event)"

View File

@ -46,9 +46,7 @@
overflow: hidden; overflow: hidden;
} }
&-active-search,
&-valid-search { &-valid-search {
display: block;
} }
} }
} }

View File

@ -18,7 +18,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ThumbnailService } from 'ng2-alfresco-core'; import { ThumbnailService } from 'ng2-alfresco-core';
import { AlfrescoTranslationService, CoreModule, SearchService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService, CoreModule, SearchService } from 'ng2-alfresco-core';
import { result } from './../assets/search.component.mock'; import { results } from './../assets/search.component.mock';
import { TranslationMock } from './../assets/translation.service.mock'; import { TranslationMock } from './../assets/translation.service.mock';
import { SearchAutocompleteComponent } from './search-autocomplete.component'; import { SearchAutocompleteComponent } from './search-autocomplete.component';
import { SearchControlComponent } from './search-control.component'; import { SearchControlComponent } from './search-control.component';
@ -27,14 +27,12 @@ describe('SearchControlComponent', () => {
let fixture: ComponentFixture<SearchControlComponent>; let fixture: ComponentFixture<SearchControlComponent>;
let component: SearchControlComponent, element: HTMLElement; let component: SearchControlComponent, element: HTMLElement;
let componentHandler; let searchService: SearchService;
beforeEach(async(() => { beforeEach(async(() => {
componentHandler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered', 'upgradeElement']);
window['componentHandler'] = componentHandler;
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot() CoreModule
], ],
declarations: [ declarations: [
SearchControlComponent, SearchControlComponent,
@ -47,6 +45,7 @@ describe('SearchControlComponent', () => {
] ]
}).compileComponents().then(() => { }).compileComponents().then(() => {
fixture = TestBed.createComponent(SearchControlComponent); fixture = TestBed.createComponent(SearchControlComponent);
searchService = TestBed.get(SearchService);
component = fixture.componentInstance; component = fixture.componentInstance;
element = fixture.nativeElement; element = fixture.nativeElement;
}); });
@ -130,7 +129,7 @@ describe('SearchControlComponent', () => {
}); });
}); });
describe('Find as you type', () => { describe('Autocomplete list', () => {
let inputEl: HTMLInputElement; let inputEl: HTMLInputElement;
@ -138,90 +137,86 @@ describe('SearchControlComponent', () => {
inputEl = element.querySelector('input'); inputEl = element.querySelector('input');
}); });
it('should display a find-as-you-type control by default', () => { it('should display a autocomplete list control by default', () => {
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); let autocomplete: Element = element.querySelector('adf-search-autocomplete');
expect(autocomplete).not.toBeNull(); expect(autocomplete).not.toBeNull();
}); });
it('should make find-as-you-type control hidden initially', () => { it('should make autocomplete list control hidden initially', () => {
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); expect(component.liveSearchComponent.panelAnimationState).toBe('void');
expect(autocomplete.classList.contains('active')).toBe(false);
}); });
it('should make find-as-you-type control visible when search box has focus', (done) => { it('should make autocomplete list control visible when search box has focus and there is a search result', (done) => {
spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(results));
component.liveSearchTerm = 'test';
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new FocusEvent('focus')); inputEl.dispatchEvent(new FocusEvent('focus'));
window.setTimeout(() => { // wait for debounce() to complete window.setTimeout(() => {
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); expect(component.liveSearchComponent.panelAnimationState).not.toBe('void');
expect(autocomplete.classList.contains('adf-active-search')).toBe(true);
done(); done();
}, 100); }, 100);
}); });
it('should hide find-as-you-type results when the search box loses focus', (done) => { it('should hide autocomplete list results when the search box loses focus', (done) => {
spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(results));
component.liveSearchTerm = 'test';
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new FocusEvent('focus')); inputEl.dispatchEvent(new FocusEvent('focus'));
inputEl.dispatchEvent(new FocusEvent('blur')); inputEl.dispatchEvent(new FocusEvent('blur'));
window.setTimeout(() => { window.setTimeout(() => {
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); expect(component.liveSearchComponent.panelAnimationState).toBe('void');
expect(autocomplete.classList.contains('active')).toBe(false);
done(); done();
}, 100); }, 100);
}); });
it('should keep find-as-you-type control visible when user tabs into results', (done) => { it('should keep autocomplete list control visible when user tabs into results', (done) => {
let searchService = TestBed.get(SearchService);
spyOn(searchService, 'getQueryNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(results));
component.liveSearchTerm = 'test';
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new FocusEvent('focus')); inputEl.dispatchEvent(new FocusEvent('focus'));
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new FocusEvent('blur'));
component.onAutoCompleteFocus(new FocusEvent('focus')); component.onAutoCompleteFocus(new FocusEvent('focus'));
window.setTimeout(() => { // wait for debounce() to complete window.setTimeout(() => {
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); expect(component.liveSearchComponent.panelAnimationState).not.toBe('void');
expect(autocomplete.classList.contains('adf-active-search')).toBe(true);
done(); done();
}, 100); }, 100);
}); });
it('should hide find-as-you-type results when escape key pressed', () => { it('should hide autocomplete list results when escape key pressed', () => {
spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(results));
component.liveSearchTerm = 'test';
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new Event('focus'));
inputEl.dispatchEvent(new KeyboardEvent('keyup', { inputEl.dispatchEvent(new KeyboardEvent('keyup', {
key: 'Escape' key: 'Escape'
})); }));
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); expect(component.liveSearchComponent.panelAnimationState).toBe('void');
expect(autocomplete.classList.contains('active')).toBe(false);
}); });
it('should make find-as-you-type control visible again when down arrow is pressed', () => { it('should select the first result in autocomplete list when down arrow is pressed and autocomplete list is visible', (done) => {
fixture.detectChanges();
inputEl.dispatchEvent(new Event('focus'));
inputEl.dispatchEvent(new KeyboardEvent('keyup', {
key: 'Escape'
}));
inputEl.dispatchEvent(new KeyboardEvent('keyup', {
key: 'ArrowDown'
}));
fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete');
expect(autocomplete.classList.contains('adf-active-search')).toBe(true);
});
it('should select the first result in find-as-you-type when down arrow is pressed and FAYT is visible', (done) => {
fixture.detectChanges(); fixture.detectChanges();
spyOn(component.liveSearchComponent, 'focusResult'); spyOn(component.liveSearchComponent, 'focusResult');
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new Event('focus'));
window.setTimeout(() => { // wait for debounce() to complete window.setTimeout(() => {
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new KeyboardEvent('keyup', { inputEl.dispatchEvent(new KeyboardEvent('keyup', {
key: 'ArrowDown' key: 'ArrowDown'
@ -232,27 +227,23 @@ describe('SearchControlComponent', () => {
}, 100); }, 100);
}); });
it('should focus input element when find-as-you-type returns control', () => { it('should focus input element when autocomplete list returns control', () => {
fixture.detectChanges(); fixture.detectChanges();
spyOn(inputEl, 'focus'); spyOn(inputEl, 'focus');
fixture.detectChanges(); fixture.detectChanges();
component.onAutoCompleteReturn(new KeyboardEvent('keyup', { component.onAutoCompleteReturn();
key: 'ArrowUp'
}));
expect(inputEl.focus).toHaveBeenCalled(); expect(inputEl.focus).toHaveBeenCalled();
}); });
it('should focus input element when find-as-you-type is cancelled', () => { it('should focus input element when autocomplete list is cancelled', () => {
fixture.detectChanges(); fixture.detectChanges();
spyOn(inputEl, 'focus'); spyOn(inputEl, 'focus');
fixture.detectChanges(); fixture.detectChanges();
component.onAutoCompleteCancel(new KeyboardEvent('keyup', { component.onAutoCompleteCancel();
key: 'ArrowUp'
}));
expect(inputEl.focus).toHaveBeenCalled(); expect(inputEl.focus).toHaveBeenCalled();
}); });
it('should NOT display a find-as-you-type control when configured not to', () => { it('should NOT display a autocomplete list control when configured not to', () => {
fixture.componentInstance.liveSearchEnabled = false; fixture.componentInstance.liveSearchEnabled = false;
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('adf-search-autocomplete'); let autocomplete: Element = element.querySelector('adf-search-autocomplete');
@ -348,12 +339,12 @@ describe('SearchControlComponent', () => {
}); });
it('should set deactivate the search after file/folder is clicked', () => { it('should set deactivate the search after file/folder is clicked', () => {
component.searchActive = true; component.subscriptAnimationState = 'active';
component.onFileClicked({ component.onFileClicked({
value: 'node12345' value: 'node12345'
}); });
expect(component.searchActive).toBe(false); expect(component.subscriptAnimationState).toBe('inactive');
}); });
it('should NOT reset the search term after file/folder is clicked', () => { it('should NOT reset the search term after file/folder is clicked', () => {

View File

@ -28,8 +28,8 @@ import { SearchAutocompleteComponent } from './search-autocomplete.component';
styleUrls: ['./search-control.component.scss'], styleUrls: ['./search-control.component.scss'],
animations: [ animations: [
trigger('transitionMessages', [ trigger('transitionMessages', [
state('active', style({ transform: 'translateX(0%)'})), state('active', style({transform: 'translateX(0%)'})),
state('inactive', style({ transform: 'translateX(89%)'})), state('inactive', style({transform: 'translateX(89%)'})),
transition('void => active, inactive => active', transition('void => active, inactive => active',
animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')), animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')),
transition('active => inactive, void => inactive', transition('active => inactive, void => inactive',
@ -37,7 +37,6 @@ import { SearchAutocompleteComponent } from './search-autocomplete.component';
]) ])
], ],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class SearchControlComponent implements OnInit, OnDestroy { export class SearchControlComponent implements OnInit, OnDestroy {
@ -47,8 +46,6 @@ export class SearchControlComponent implements OnInit, OnDestroy {
@Input() @Input()
inputType = 'text'; inputType = 'text';
// style({ transform: 'translateX(0%)'}) style({ transform: 'translateX(89%)'}),
@Input() @Input()
autocomplete: boolean = false; autocomplete: boolean = false;
@ -81,7 +78,6 @@ export class SearchControlComponent implements OnInit, OnDestroy {
@Input() @Input()
liveSearchEnabled: boolean = true; liveSearchEnabled: boolean = true;
@Input()
liveSearchTerm: string = ''; liveSearchTerm: string = '';
@Input() @Input()
@ -96,13 +92,11 @@ export class SearchControlComponent implements OnInit, OnDestroy {
@Input() @Input()
liveSearchMaxResults: number = 5; liveSearchMaxResults: number = 5;
searchActive = false;
searchValid = false; searchValid = false;
private focusSubject = new Subject<FocusEvent>(); private focusSubject = new Subject<FocusEvent>();
_subscriptAnimationState: string = 'inactive'; subscriptAnimationState: string = 'inactive';
constructor() { constructor() {
this.searchControl = new FormControl( this.searchControl = new FormControl(
@ -114,9 +108,9 @@ export class SearchControlComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.searchControl.valueChanges.debounceTime(400).distinctUntilChanged() this.searchControl.valueChanges.debounceTime(400).distinctUntilChanged()
.subscribe((value: string) => { .subscribe((value: string) => {
this.onSearchTermChange(value); this.onSearchTermChange(value);
} }
); );
this.setupFocusEventHandlers(); this.setupFocusEventHandlers();
} }
@ -137,15 +131,11 @@ export class SearchControlComponent implements OnInit, OnDestroy {
private setupFocusEventHandlers() { private setupFocusEventHandlers() {
let focusEvents: Observable<FocusEvent> = this.focusSubject.asObservable().debounceTime(50); let focusEvents: Observable<FocusEvent> = this.focusSubject.asObservable().debounceTime(50);
focusEvents.filter(($event: FocusEvent) => {
return $event.type === 'focusin' || $event.type === 'focus';
}).subscribe(($event) => {
this.onSearchFocus($event);
});
focusEvents.filter(($event: any) => { focusEvents.filter(($event: any) => {
return $event.type === 'focusout' || $event.type === 'blur'; return $event.type === 'focusout' || $event.type === 'blur';
}).subscribe(($event) => { }).subscribe(() => {
this.onSearchBlur($event); this.onSearchBlur();
}); });
} }
@ -158,7 +148,7 @@ export class SearchControlComponent implements OnInit, OnDestroy {
* *
* @param event Submit event that was fired * @param event Submit event that was fired
*/ */
onSearch(event): void { onSearch(): void {
this.searchControl.setValue(this.searchTerm); this.searchControl.setValue(this.searchTerm);
if (this.searchControl.valid) { if (this.searchControl.valid) {
this.searchSubmit.emit({ this.searchSubmit.emit({
@ -168,25 +158,22 @@ export class SearchControlComponent implements OnInit, OnDestroy {
} }
} }
isAutoCompleteDisplayed(): boolean { hideAutocomplete(): void {
return this.searchActive; if (this.liveSearchComponent) {
} this.liveSearchComponent.resetAnimation();
}
setAutoCompleteDisplayed(display: boolean): void {
this.searchActive = display;
} }
onFileClicked(event): void { onFileClicked(event): void {
this.setAutoCompleteDisplayed(false); this.hideAutocomplete();
this.toggleSearchBar();
this.fileSelect.emit(event); this.fileSelect.emit(event);
this.searchTerm = '';
} }
onSearchFocus($event): void { onSearchBlur(): void {
this.setAutoCompleteDisplayed(true); this.hideAutocomplete();
} this.toggleSearchBar();
onSearchBlur($event): void {
this.setAutoCompleteDisplayed(false);
} }
onFocus($event): void { onFocus($event): void {
@ -208,37 +195,37 @@ export class SearchControlComponent implements OnInit, OnDestroy {
} }
onEscape(): void { onEscape(): void {
this.setAutoCompleteDisplayed(false); this.hideAutocomplete();
this.toggleSearchBar();
this.searchTerm = '';
} }
onArrowDown(): void { onArrowDown(): void {
if (this.isAutoCompleteDisplayed()) { this.liveSearchComponent.focusResult();
this.liveSearchComponent.focusResult();
} else {
this.setAutoCompleteDisplayed(true);
}
} }
onAutoCompleteFocus($event): void { onAutoCompleteFocus($event): void {
this.focusSubject.next($event); this.focusSubject.next($event);
} }
onAutoCompleteReturn($event): void { onAutoCompleteReturn(): void {
if (this.searchInput) { if (this.searchInput) {
(<any> this.searchInput.nativeElement).focus(); (<any> this.searchInput.nativeElement).focus();
} }
} }
onAutoCompleteCancel($event): void { onAutoCompleteCancel(): void {
if (this.searchInput) { if (this.searchInput) {
(<any> this.searchInput.nativeElement).focus(); (<any> this.searchInput.nativeElement).focus();
} }
this.setAutoCompleteDisplayed(false); this.hideAutocomplete();
} }
onClickSearch() { onClickSearch() {
this.searchActive = !this.searchActive; this.subscriptAnimationState = 'active';
this._subscriptAnimationState = this.searchActive ? 'active' : 'inactive';
} }
toggleSearchBar() {
this.subscriptAnimationState = this.subscriptAnimationState === 'inactive' ? 'active' : 'inactive';
}
} }

View File

@ -19,30 +19,29 @@
</div> </div>
</ng-template> </ng-template>
</empty-folder-content> </empty-folder-content>
<data-columns>
<content-columns> <data-column key="$thumbnail" type="image"></data-column>
<content-column key="$thumbnail" type="image"></content-column> <data-column
<content-column
title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}" title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}"
key="name" key="name"
sortable="true" sortable="true"
class="full-width ellipsis-cell"> class="full-width ellipsis-cell">
</content-column> </data-column>
<content-column <data-column
title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.CREATED_BY' | translate}}" title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.CREATED_BY' | translate}}"
key="createdByUser.displayName" key="createdByUser.displayName"
sortable="true" sortable="true"
class="desktop-only"> class="desktop-only">
</content-column> </data-column>
<content-column <data-column
title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.CREATED_ON' | translate}}" title="{{'SEARCH.DOCUMENT_LIST.COLUMNS.CREATED_ON' | translate}}"
key="createdAt" key="createdAt"
type="date" type="date"
format="medium" format="medium"
sortable="true" sortable="true"
class="desktop-only"> class="desktop-only">
</content-column> </data-column>
</content-columns> </data-columns>
<content-actions> <content-actions>
<!-- folder actions --> <!-- folder actions -->

View File

@ -116,10 +116,10 @@ describe('SearchComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CoreModule.forRoot(), CoreModule,
DocumentListModule.forRoot() DocumentListModule
], ],
declarations: [SearchComponent], // declare the test component declarations: [SearchComponent],
providers: [ providers: [
SearchService, SearchService,
{provide: AlfrescoTranslationService, useClass: TranslationMock}, {provide: AlfrescoTranslationService, useClass: TranslationMock},

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output, SimpleChanges } from '@angular/core'; import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { NodePaging, Pagination } from 'alfresco-js-api'; import { NodePaging, Pagination } from 'alfresco-js-api';
import { AlfrescoTranslationService, NotificationService, SearchOptions, SearchService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService, NotificationService, SearchOptions, SearchService } from 'ng2-alfresco-core';
@ -26,7 +26,8 @@ declare var require: any;
@Component({ @Component({
selector: 'adf-search, alfresco-search', selector: 'adf-search, alfresco-search',
styleUrls: ['./search.component.scss'], styleUrls: ['./search.component.scss'],
templateUrl: './search.component.html' templateUrl: './search.component.html',
encapsulation: ViewEncapsulation.None
}) })
export class SearchComponent implements OnChanges, OnInit { export class SearchComponent implements OnChanges, OnInit {

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -19,7 +19,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -30,6 +31,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -16,7 +16,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -27,6 +28,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -20,7 +20,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -31,6 +32,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -21,7 +21,8 @@ module.exports = function (config) {
{pattern: './node_modules/pdfjs-dist/web/pdf_viewer.js', included: true, watched: false}, {pattern: './node_modules/pdfjs-dist/web/pdf_viewer.js', included: true, watched: false},
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
@ -33,6 +34,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,

View File

@ -0,0 +1,4 @@
{
"ecmHost": "http://{hostname}:{port}/ecm",
"bpmHost": "http://{hostname}:{port}/bpm"
}

View File

@ -23,7 +23,8 @@ module.exports = function (config) {
{pattern: 'karma-test-shim.js', watched: false}, {pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/assets/**/*.*', included: false, served: true, watched: false}, {pattern: './src/assets/**/*.*', included: false, served: true, watched: false},
{pattern: './src/i18n/**/*.*', included: false, served: true, watched: false}, {pattern: './src/i18n/**/*.*', included: false, served: true, watched: false},
{pattern: './src/**/*.ts', included: false, served: true, watched: false} {pattern: './src/**/*.ts', included: false, served: true, watched: false},
{pattern: './config/app.config.json', included: false, served: true, watched: false}
], ],
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'), webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
@ -34,6 +35,10 @@ module.exports = function (config) {
port: 9876, port: 9876,
proxies: {
'/app.config.json': '/base/config/app.config.json'
},
// level of logging // level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,