diff --git a/.editorconfig b/.editorconfig
index 9b7352176..4a874ce23 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,3 +11,6 @@ trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false
+
+[*.yml]
+indent_size = 2
diff --git a/.travis.yml b/.travis.yml
index 9b68812ed..f9a1b2411 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
dist: trusty
-sudo: false
+sudo: required
language: node_js
node_js:
@@ -9,15 +9,24 @@ cache:
directories:
- ./node_modules
-
-before_install:
- - export CHROME_BIN=chromium-browser
- - "export DISPLAY=:99.0"
- - "sh -e /etc/init.d/xvfb start"
+services:
+ - docker
install:
- npm install
script:
- - xvfb-run -a npm run test -- --single-run --no-progress --browser=ChromeNoSandbox
- #- xvfb-run -a npm run e2e -- --no-progress --config=protractor-ci.conf.js
+ - npm run build
+ - npm run test -- --single-run --no-progress
+
+# Send coverage data to codecov
+after_success:
+ - bash <(curl -s https://codecov.io/bash) -X gcov
+ - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
+ - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
+ - export TAG=`if [ "$BRANCH" == "master" ]; then echo "latest"; else echo $BRANCH ; fi`
+ - docker build -t $DOCKER_REPO:$TAG .
+ # Publish extra image based on Travis build number
+ - docker tag $DOCKER_REPO:$TAG $DOCKER_REPO:travis-$TRAVIS_BUILD_NUMBER
+ - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"
+ - docker push $DOCKER_REPO
diff --git a/README.md b/README.md
index e1e1bdc9b..769f9c32c 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,24 @@
-# Alfresco Content App
+# Alfresco Example Content Application
+
+
+
+
+
+## Introduction
+
+The Alfresco Content Application is an example application built using
+[Alfresco Application Development Framework (ADF)](https://github.com/Alfresco/alfresco-ng2-components) components and was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.4.7.
+
+### Who is this example application for
+
+This example application demonstrates to Angular software engineers
+how to construct a content application using the Alfresco ADF.
+
+This example application represents a meaningful composition of ADF components that provide end users
+with a simple and easy to use interface for working with files stored in the Alfresco Content Services repository.
[Public documentation](https://alfresco.github.io/alfresco-content-app/)
-This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.4.7.
-
## Development server
Run `npm start` for a dev server. Navigate to `http://localhost:3000/` (opens by default).
diff --git a/alfresco.png b/alfresco.png
new file mode 100644
index 000000000..7f6326b0b
Binary files /dev/null and b/alfresco.png differ
diff --git a/docs/docker.md b/docs/docker.md
index ac19fb4fe..fcddc4aca 100644
--- a/docs/docker.md
+++ b/docs/docker.md
@@ -35,10 +35,10 @@ docker image build -t content-app .
To run the image locally, you can use the following command:
```sh
-docker container run -p 80:80 --rm content-app
+docker container run -p 8888:80 --rm content-app
```
-Navigate to "http://localhost" to access the running application.
+Navigate to "http://localhost:8888" to access the running application.
## Docker Compose file
diff --git a/karma.conf.js b/karma.conf.js
index 410aaa975..abe47fde7 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -38,11 +38,16 @@ module.exports = function (config) {
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
- browsers: ['Chrome'],
+ browsers: ['ChromeHeadless'],
customLaunchers: {
- ChromeNoSandbox: {
+ ChromeHeadless: {
base: 'Chrome',
- flags: ['--no-sandbox']
+ flags: [
+ '--no-sandbox',
+ '--headless',
+ '--disable-gpu',
+ '--remote-debugging-port=9222'
+ ]
}
},
singleRun: false,
diff --git a/package.json b/package.json
index 3e582ae2a..9f4fd5f20 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"build:prod": "npm run server-versions && ng build --prod",
"build:dev": "npm run server-versions && ng build && node postbuild-dev.js",
"build:tomcat": "npm run server-versions && ng build --base-href ./",
- "test": "ng test",
+ "test": "ng test --code-coverage",
"lint": "ng lint",
"e2e": "ng e2e",
"server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0"
diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts
index 266be3433..884ee1a83 100644
--- a/src/app/components/files/files.component.spec.ts
+++ b/src/app/components/files/files.component.spec.ts
@@ -77,7 +77,7 @@ describe('FilesComponent', () => {
}));
beforeEach(() => {
- node = { id: 'node-id' };
+ node = { id: 'node-id', isFolder: true };
page = {
list: {
entries: ['a', 'b', 'c'],
@@ -134,6 +134,17 @@ describe('FilesComponent', () => {
expect(component.onFetchError).toHaveBeenCalled();
});
+
+ it('if should navigate to parent if node is not a folder', () => {
+ node.isFolder = false;
+ node.parentId = 'parent-id';
+ spyOn(component, 'fetchNode').and.returnValue(Observable.of(node));
+ spyOn(router, 'navigate');
+
+ fixture.detectChanges();
+
+ expect(router.navigate).toHaveBeenCalledWith([ '/personal-files', 'parent-id' ]);
+ });
});
describe('refresh on events', () => {
diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts
index 8d3d7e729..96926da40 100644
--- a/src/app/components/files/files.component.ts
+++ b/src/app/components/files/files.component.ts
@@ -76,7 +76,13 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.isLoading = true;
this.fetchNode(nodeId)
- .do((node) => this.updateCurrentNode(node))
+ .do((node) => {
+ if (node.isFolder) {
+ this.updateCurrentNode(node);
+ } else {
+ this.router.navigate(['/personal-files', node.parentId]);
+ }
+ })
.flatMap((node) => this.fetchNodes(node.id))
.subscribe(
(page) => {
diff --git a/src/app/components/layout/layout.component.spec.ts b/src/app/components/layout/layout.component.spec.ts
index f4fc2930c..5bd92c25e 100644
--- a/src/app/components/layout/layout.component.spec.ts
+++ b/src/app/components/layout/layout.component.spec.ts
@@ -26,7 +26,7 @@
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
-import { CoreModule, ContentService, PeopleContentService } from '@alfresco/adf-core';
+import { CoreModule, ContentService, PeopleContentService, AppConfigService } from '@alfresco/adf-core';
import { Observable } from 'rxjs/Observable';
import { BrowsingFilesService } from '../../common/services/browsing-files.service';
@@ -43,6 +43,12 @@ describe('LayoutComponent', () => {
let browsingFilesService: BrowsingFilesService;
let contentService: ContentService;
let node;
+ const navItem = {
+ label: 'some-label',
+ route: {
+ url: '/some-url'
+ }
+ };
beforeEach(() => {
node = { id: 'node-id' };
@@ -61,6 +67,7 @@ describe('LayoutComponent', () => {
CurrentUserComponent
],
providers: [
+ AppConfigService,
{
provide: PeopleContentService,
useValue: {
@@ -75,6 +82,9 @@ describe('LayoutComponent', () => {
browsingFilesService = TestBed.get(BrowsingFilesService);
contentService = TestBed.get(ContentService);
+ const appConfig = TestBed.get(AppConfigService);
+ spyOn(appConfig, 'get').and.returnValue([navItem]);
+
fixture.detectChanges();
});
diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss
index a73705b0d..c0acf6fe9 100644
--- a/src/app/ui/overrides/_alfresco-document-list.scss
+++ b/src/app/ui/overrides/_alfresco-document-list.scss
@@ -32,6 +32,11 @@ adf-document-list {
}
}
+ td, th {
+ width: 100%;
+ text-align: left;
+ }
+
.adf-data-table__header--sorted-asc,
.adf-data-table__header--sorted-desc {
&:hover {
@@ -58,13 +63,11 @@ adf-document-list {
border: none !important;
}
-
- .adf-data-table-cell--ellipsis {
- width: 100%;
- }
-
- .adf-data-table-cell--ellipsis__name {
- width: 85%;
+ th:first-of-type, th.adf-data-table-cell--image,
+ td:first-of-type, td.adf-data-table-cell--image {
+ padding-left: 24px;
+ padding-right: 0;
+ width: 10px;
}
.adf-data-table-cell--ellipsis .cell-value,
@@ -77,11 +80,18 @@ adf-document-list {
.adf-data-table-cell--ellipsis__name .adf-datatable-cell {
white-space: nowrap;
display: block;
- position: absolute;
- max-width: calc(100% - 2em);
overflow: hidden;
text-overflow: ellipsis;
}
+
+ .adf-data-table-cell--ellipsis .adf-datatable-cell {
+ max-width: 7vw;
+ }
+
+ .adf-data-table-cell--ellipsis__name .adf-datatable-cell {
+ position: absolute;
+ max-width: calc(100% - 2em);
+ }
}
.empty-list {
diff --git a/src/app/ui/overrides/_breadcrumb.scss b/src/app/ui/overrides/_breadcrumb.scss
index 035d66e23..010468714 100644
--- a/src/app/ui/overrides/_breadcrumb.scss
+++ b/src/app/ui/overrides/_breadcrumb.scss
@@ -3,4 +3,8 @@
.adf-breadcrumb {
color: $alfresco-secondary-text-color;
width: 0;
+
+ &-item:first-child:nth-last-child(1) {
+ opacity: 1;
+ }
}