mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3550] Migration - Application List Component (#3902)
* [ADF-3538] start creating new folder for cloud components * [ADF-3538] added new package to the script and the builds * [ADF-3538] added some more changes to scripts * [ADF-3538] - starting the new package * fix package * Add a cloud component as example * Skip the scss style * remove useless codes * Add i18n example * remove useless code * Simplify the hello component Fix the wrong path * add the app-list-cloud-component add the app-details-cloud-component * Expose and use the new component * Consume the new package and component from the demoshell * Fix unit test app list cloud * Fix process service cloud path * Remove useless file * * Added documentation to the appListcloud component * Fix failing unit tests
This commit is contained in:
committed by
Eugenio Romano
parent
987c01f1f4
commit
4c9629c2d6
@@ -63,7 +63,7 @@ import { ContentModule } from '@alfresco/adf-content-services';
|
||||
import { InsightsModule } from '@alfresco/adf-insights';
|
||||
import { ProcessModule } from '@alfresco/adf-process-services';
|
||||
import { AuthBearerInterceptor } from './services';
|
||||
import { ProcessServicesCloudModule } from '@alfresco/adf-process-services-cloud';
|
||||
import { AppListCloudModule } from '@alfresco/adf-process-services-cloud';
|
||||
import { CloudComponent } from './components/cloud/cloud.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -83,7 +83,7 @@ import { CloudComponent } from './components/cloud/cloud.component';
|
||||
ThemePickerModule,
|
||||
ChartsModule,
|
||||
MonacoEditorModule.forRoot(),
|
||||
ProcessServicesCloudModule
|
||||
AppListCloudModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
@@ -44,7 +44,6 @@ import { CloudComponent } from './components/cloud/cloud.component';
|
||||
|
||||
export const appRoutes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'cloud', component: CloudComponent },
|
||||
{ path: 'logout', component: LogoutComponent },
|
||||
{
|
||||
path: 'settings',
|
||||
@@ -134,6 +133,10 @@ export const appRoutes: Routes = [
|
||||
path: 'home',
|
||||
component: HomeComponent
|
||||
},
|
||||
{
|
||||
path: 'cloud',
|
||||
component: CloudComponent
|
||||
},
|
||||
{
|
||||
path: 'node-selector',
|
||||
loadChildren: 'app/components/content-node-selector/content-node-selector.module#AppContentNodeSelectorModule'
|
||||
|
@@ -1,2 +1,2 @@
|
||||
|
||||
<adf-cloud-hello></adf-cloud-hello>
|
||||
<adf-cloud-app-list></adf-cloud-app-list>
|
||||
|
@@ -5,8 +5,6 @@
|
||||
<h2>{{ 'APP.HOME.TITLE' | translate}}</h2>
|
||||
</div>
|
||||
|
||||
<adf-cloud-hello></adf-cloud-hello>
|
||||
|
||||
<div class="adf-home-start">
|
||||
<a mat-raised-button class="adf-home-docs-button adf-primary-color" href="https://github.com/Alfresco/alfresco-ng2-components/tree/master/docs">{{ 'APP.HOME.DOCUMENTATION' | translate}}</a>
|
||||
</div>
|
||||
|
45
docs/process-services-cloud/app-list-cloud.component.md
Normal file
45
docs/process-services-cloud/app-list-cloud.component.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
Added: v3.0.0
|
||||
Status: Active
|
||||
Last reviewed: 2018-18-10
|
||||
---
|
||||
|
||||
# App List Cloud Component
|
||||
|
||||
Shows all deployed cloud application instances.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```html
|
||||
<adf-cloud-app-list
|
||||
[layoutType]="'GRID'">
|
||||
</adf-cloud-app-list>
|
||||
```
|
||||
|
||||
### [Transclusions](../user-guide/transclusion.md)
|
||||
|
||||
You can show custom content when there are no apps available by supplying an
|
||||
`<adf-empty-custom-content>` section:
|
||||
|
||||
```html
|
||||
<adf-cloud-app-list
|
||||
[layoutType]="'GRID'">
|
||||
<adf-empty-custom-content>
|
||||
No Apps present
|
||||
</adf-empty-custom-content>
|
||||
</adf-cloud-app-list>
|
||||
```
|
||||
|
||||
## Class members
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Default value | Description |
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| layoutType | `string` | | (**required**) Defines the layout of the apps. There are two possible values, "GRID" and "LIST". |
|
||||
|
||||
### Events
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| appClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ApplicationInstanceModel`](../../lib/process-services-cloud/apps-list/models/application-instance.model.ts)`>` | Emitted when an app entry is clicked. |
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TestBed, fakeAsync } from '@angular/core/testing';
|
||||
import { TestBed, fakeAsync, async } from '@angular/core/testing';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material';
|
||||
import { of } from 'rxjs';
|
||||
import {
|
||||
@@ -96,7 +96,7 @@ describe('ShareDialogComponent', () => {
|
||||
expect(fixture.nativeElement.querySelector('.mat-slide-toggle').classList).toContain('mat-checked');
|
||||
});
|
||||
|
||||
it(`should not toggle share action when file has 'sharedId' property`, () => {
|
||||
it(`should not toggle share action when file has 'sharedId' property`, async(() => {
|
||||
spyOn(sharedLinksApiService, 'createSharedLinks');
|
||||
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
@@ -108,12 +108,17 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
|
||||
expect(fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]').value).toBe('some-url/sharedId');
|
||||
expect(fixture.nativeElement.querySelector('.mat-slide-toggle').classList).toContain('mat-checked');
|
||||
});
|
||||
|
||||
it(`should copy shared link and notify on button event`, (done) => {
|
||||
});
|
||||
}));
|
||||
|
||||
it(`should copy shared link and notify on button event`, async(() => {
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
spyOn(document, 'execCommand').and.callThrough();
|
||||
|
||||
@@ -134,9 +139,8 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
expect(document.execCommand).toHaveBeenCalledWith('copy');
|
||||
expect(notificationServiceMock.openSnackMessage).toHaveBeenCalledWith('SHARE.CLIPBOARD-MESSAGE');
|
||||
done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should open a confirmation dialog when unshare button is triggered', () => {
|
||||
spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(false) });
|
||||
|
30
lib/process-services-cloud/.npmignore
Normal file
30
lib/process-services-cloud/.npmignore
Normal file
@@ -0,0 +1,30 @@
|
||||
npm-debug.log
|
||||
.idea
|
||||
.npmrc
|
||||
|
||||
/.editorconfig
|
||||
/.travis.yml
|
||||
/*.json
|
||||
/karma-test-shim.js
|
||||
/karma.conf.js
|
||||
/gulpfile.ts
|
||||
/.npmignore
|
||||
/.happypack
|
||||
**/*.html
|
||||
**/*.js
|
||||
**/*.ts
|
||||
!**/*.d.ts
|
||||
!**/adf-process-services-cloud.js
|
||||
|
||||
**/*.scss
|
||||
**/*.css
|
||||
!**/_theming.scss
|
||||
|
||||
coverage/
|
||||
demo/
|
||||
dist/
|
||||
node_modules
|
||||
typings/
|
||||
fonts/
|
||||
i18n/
|
||||
assets/
|
44
lib/process-services-cloud/material.module.ts
Normal file
44
lib/process-services-cloud/material.module.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import {
|
||||
MAT_LABEL_GLOBAL_OPTIONS, MatAutocompleteModule, MatButtonModule, MatCardModule, MatCheckboxModule,
|
||||
MatChipsModule, MatDatepickerModule, MatDialogModule, MatGridListModule, MatIconModule,
|
||||
MatInputModule, MatListModule, MatNativeDateModule, MatOptionModule, MatProgressSpinnerModule, MatRadioModule,
|
||||
MatRippleModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule,
|
||||
MatTooltipModule, MatMenuModule
|
||||
} from '@angular/material';
|
||||
|
||||
export function modules() {
|
||||
return [
|
||||
MatAutocompleteModule, MatButtonModule, MatCardModule, MatDialogModule,
|
||||
MatCheckboxModule, MatDatepickerModule, MatGridListModule, MatIconModule, MatInputModule,
|
||||
MatListModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule, MatTableModule,
|
||||
MatTabsModule, MatProgressSpinnerModule, MatNativeDateModule, MatRippleModule, MatTooltipModule,
|
||||
MatChipsModule, MatMenuModule
|
||||
];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
{provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: { float: 'never' }}
|
||||
],
|
||||
imports: modules(),
|
||||
exports: modules()
|
||||
})
|
||||
export class MaterialModule {}
|
99
lib/process-services-cloud/process-cloud.module.ts
Normal file
99
lib/process-services-cloud/process-cloud.module.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule, TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||
|
||||
import { MaterialModule } from './material.module';
|
||||
import { HelloCloudModule } from './hello/hello.module';
|
||||
|
||||
export function providers() {
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CoreModule.forChild(),
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MaterialModule,
|
||||
HelloCloudModule
|
||||
],
|
||||
providers: [
|
||||
...providers(),
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services-cloud',
|
||||
source: 'assets/adf-process-services-cloud'
|
||||
}
|
||||
}
|
||||
],
|
||||
exports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
HelloCloudModule
|
||||
]
|
||||
})
|
||||
export class ProcessCloudModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: ProcessCloudModule,
|
||||
providers: [
|
||||
...providers(),
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services-cloud',
|
||||
source: 'assets/adf-process-services-cloud'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
static forChild(): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: ProcessCloudModuleLazy
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CoreModule.forChild(),
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MaterialModule,
|
||||
HelloCloudModule
|
||||
],
|
||||
exports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
HelloCloudModule
|
||||
]
|
||||
})
|
||||
export class ProcessCloudModuleLazy {}
|
18
lib/process-services-cloud/public-api.ts
Normal file
18
lib/process-services-cloud/public-api.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './index';
|
@@ -0,0 +1,13 @@
|
||||
import { AppListCloudModule } from './app-list-cloud.module';
|
||||
|
||||
describe('AppListCloudModule', () => {
|
||||
let appListCloudModule: AppListCloudModule;
|
||||
|
||||
beforeEach(() => {
|
||||
appListCloudModule = new AppListCloudModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(appListCloudModule).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -0,0 +1,53 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { AppDetailsCloudComponent } from './components/app-details-cloud.component';
|
||||
import { AppListCloudComponent } from './components/app-list-cloud.component';
|
||||
import { AppsProcessCloudService } from './services/apps-process-cloud.service';
|
||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||
import { TemplateModule, TranslateLoaderService } from '@alfresco/adf-core';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: TranslateLoaderService
|
||||
}
|
||||
}),
|
||||
TemplateModule,
|
||||
MaterialModule,
|
||||
FlexLayoutModule
|
||||
],
|
||||
declarations: [
|
||||
AppListCloudComponent,
|
||||
AppDetailsCloudComponent
|
||||
],
|
||||
providers: [
|
||||
AppsProcessCloudService
|
||||
],
|
||||
exports: [
|
||||
AppListCloudComponent,
|
||||
AppDetailsCloudComponent
|
||||
]
|
||||
})
|
||||
export class AppListCloudModule { }
|
@@ -0,0 +1,22 @@
|
||||
<div class="adf-app-listgrid">
|
||||
<div class="adf-app-listgrid-item">
|
||||
<mat-card tabindex="0"
|
||||
fxLayout="column"
|
||||
role="button"
|
||||
class="adf-app-listgrid-item-card"
|
||||
title="{{applicationInstance.name}}"
|
||||
[ngClass]="[applicationInstance.theme]"
|
||||
(click)="onSelectApp(applicationInstance)"
|
||||
(keyup.enter)="onSelectApp(applicationInstance)">
|
||||
<div class="adf-app-listgrid-item-card-logo">
|
||||
<mat-icon class="adf-app-listgrid-item-card-logo-icon">{{applicationInstance.icon}}</mat-icon>
|
||||
</div>
|
||||
<div mat-card-title class="adf-app-listgrid-item-card-title">
|
||||
<h1>{{applicationInstance.name}}</h1>
|
||||
</div>
|
||||
<mat-card-subtitle class="adf-app-listgrid-item-card-subtitle" fxFlex="1 0 auto">
|
||||
<div class="line-clamp">{{applicationInstance.description}}</div>
|
||||
</mat-card-subtitle>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,114 @@
|
||||
@mixin adf-cloud-app-details-theme($theme) {
|
||||
|
||||
$tile-themes: (
|
||||
theme-1: (bg: #269abc, color: #168aac),
|
||||
theme-2: (bg: #7da9b0, color: #6d99a0),
|
||||
theme-3: (bg: #7689ab, color: #66799b),
|
||||
theme-4: (bg: #c74e3e, color: #b73e2e),
|
||||
theme-5: (bg: #fab96c, color: #eaa95c),
|
||||
theme-6: (bg: #759d4c, color: #658d3c),
|
||||
theme-7: (bg: #b1b489, color: #a1a479),
|
||||
theme-8: (bg: #a17299, color: #916289),
|
||||
theme-9: (bg: #696c67, color: #595c57),
|
||||
theme-10: (bg: #cabb33, color: #baab23)
|
||||
);
|
||||
|
||||
.adf-app-listgrid {
|
||||
padding: 8px;
|
||||
|
||||
&-item {
|
||||
outline: none;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&-card {
|
||||
|
||||
@for $i from 1 through 10 {
|
||||
&.theme-#{$i} {
|
||||
$tile-theme: map-get($tile-themes, theme-#{$i});
|
||||
background-color: map-get($tile-theme, bg);
|
||||
}
|
||||
}
|
||||
|
||||
outline: none;
|
||||
transition: transform 280ms cubic-bezier(.4,0,.2,1), box-shadow 280ms cubic-bezier(.4,0,.2,1);
|
||||
min-height: 200px;
|
||||
padding: 0 !important;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .2);
|
||||
cursor: pointer;
|
||||
transform: scale(1.015);
|
||||
}
|
||||
|
||||
&-logo {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
padding: 16px;
|
||||
z-index: 9;
|
||||
|
||||
&-icon {
|
||||
font-size: 70px;
|
||||
width: 1em !important;
|
||||
height: 1em !important;
|
||||
|
||||
@for $i from 1 through 10 {
|
||||
.theme-#{$i} & {
|
||||
$tile-theme: map-get($tile-themes, theme-#{$i});
|
||||
color: map-get($tile-theme, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
padding: 16px;
|
||||
margin-bottom: 0 !important;
|
||||
z-index: 9999;
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
width: 80%;
|
||||
font-size: 24px;
|
||||
margin: 0;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&-subtitle {
|
||||
color: white;
|
||||
z-index: 9999;
|
||||
padding: 16px;
|
||||
|
||||
.line-clamp {
|
||||
@include line-clamp(1.25, 3);
|
||||
}
|
||||
}
|
||||
|
||||
&-actions {
|
||||
padding: 0 16px 16px 16px !important;
|
||||
border-top: 1px solid rgba(0,0,0,.1);
|
||||
min-height: 48px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&-icon {
|
||||
color: #e9f1f3;
|
||||
}
|
||||
|
||||
&.mat-card-actions {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
|
||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||
import { AppDetailsCloudComponent } from './app-details-cloud.component';
|
||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
||||
|
||||
describe('AppDetailsCloudComponent', () => {
|
||||
|
||||
let component: AppDetailsCloudComponent;
|
||||
let fixture: ComponentFixture<AppDetailsCloudComponent>;
|
||||
|
||||
setupTestBed({
|
||||
imports: [AppListTestingModule]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AppDetailsCloudComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.applicationInstance = fakeApplicationInstance[0];
|
||||
});
|
||||
|
||||
it('should create AppDetailsCloudComponent ', async(() => {
|
||||
expect(component instanceof AppDetailsCloudComponent).toBe(true);
|
||||
}));
|
||||
|
||||
it('should display application name', () => {
|
||||
fixture.detectChanges();
|
||||
const appName = fixture.nativeElement.querySelector('.adf-app-listgrid-item-card-title');
|
||||
expect(appName.innerText.trim()).toEqual(fakeApplicationInstance[0].name);
|
||||
});
|
||||
|
||||
it('should emit a click event when app selected', () => {
|
||||
spyOn(component.selectedApp, 'emit');
|
||||
fixture.detectChanges();
|
||||
const app = fixture.nativeElement.querySelector('.mat-card');
|
||||
app.click();
|
||||
expect(component.selectedApp.emit).toHaveBeenCalledWith(fakeApplicationInstance[0]);
|
||||
});
|
||||
});
|
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-app-details',
|
||||
templateUrl: './app-details-cloud.component.html',
|
||||
styleUrls: ['./app-details-cloud.component.scss']
|
||||
})
|
||||
|
||||
export class AppDetailsCloudComponent {
|
||||
|
||||
@Input()
|
||||
applicationInstance: ApplicationInstanceModel;
|
||||
|
||||
@Output()
|
||||
selectedApp: EventEmitter<ApplicationInstanceModel> = new EventEmitter<ApplicationInstanceModel>();
|
||||
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Pass the selected app as next
|
||||
* @param app
|
||||
*/
|
||||
public onSelectApp(app: ApplicationInstanceModel): void {
|
||||
this.selectedApp.emit(app);
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
<div class="menu-container" *ngIf="apps$ | async as appsList; else loading">
|
||||
<ng-container *ngIf="appsList.length > 0; else noApps">
|
||||
<div *ngIf="isGrid(); else appList" fxLayout="row wrap">
|
||||
<adf-cloud-app-details fxFlex="33.33333%" fxFlex.lt-md="50%" fxFlex.lt-sm="100%" *ngFor="let app of appsList"
|
||||
[applicationInstance]="app" (selectedApp)="onSelectApp($event)">
|
||||
</adf-cloud-app-details>
|
||||
</div>
|
||||
|
||||
<ng-template #appList>
|
||||
<mat-list class="adf-app-list">
|
||||
<mat-list-item class="adf-app-list-item" (click)="onSelectApp(app)" (keyup.enter)="onSelectApp(app)"
|
||||
*ngFor="let app of appsList" tabindex="0" role="button" title="{{app.name}}">
|
||||
<mat-icon matListIcon>touch_app</mat-icon>
|
||||
<span matLine>{{app.name}}</span>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</div>
|
||||
<ng-template #noApps>
|
||||
<div class="adf-app-list-empty">
|
||||
<ng-content select="adf-empty-custom-content" *ngIf="hasEmptyCustomContentTemplate; else defaultEmptyTemplate"
|
||||
class="adf-custom-empty-template">
|
||||
</ng-content>
|
||||
|
||||
<ng-template #defaultEmptyTemplate>
|
||||
<adf-empty-content icon="apps" [title]="'ADF_TASK_LIST.APPS.TITLE' | translate" [subtitle]="'ADF_TASK_LIST.APPS.SUBTITLE' | translate">
|
||||
</adf-empty-content>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #loading>
|
||||
<ng-container>
|
||||
<div class="adf-app-list-spinner">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
@@ -0,0 +1,21 @@
|
||||
@mixin adf-cloud-app-list-theme($theme) {
|
||||
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.adf-app-list-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.adf-app-list-spinner, .adf-app-list-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 85vh;
|
||||
.mat-spinner {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,207 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||
import { AppListCloudComponent } from './app-list-cloud.component';
|
||||
import { AppsProcessCloudService } from '../services/apps-process-cloud.service';
|
||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
|
||||
describe('AppListCloudComponent', () => {
|
||||
|
||||
let component: AppListCloudComponent;
|
||||
let fixture: ComponentFixture<AppListCloudComponent>;
|
||||
let service: AppsProcessCloudService;
|
||||
let getAppsSpy: jasmine.Spy;
|
||||
|
||||
setupTestBed({
|
||||
imports: [AppListTestingModule],
|
||||
providers: [AppsProcessCloudService]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AppListCloudComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
service = TestBed.get(AppsProcessCloudService);
|
||||
getAppsSpy = spyOn(service, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
|
||||
});
|
||||
|
||||
it('should create AppListCloudComponent ', async(() => {
|
||||
expect(component instanceof AppListCloudComponent).toBe(true);
|
||||
}));
|
||||
|
||||
it('should define layoutType with the default value', () => {
|
||||
component.layoutType = '';
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(true);
|
||||
});
|
||||
|
||||
it('Should fetch deployed apps', async(() => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
component.apps$.subscribe((response: ApplicationInstanceModel[]) => {
|
||||
expect(response).toBeDefined();
|
||||
expect(response.length).toEqual(2);
|
||||
expect(response[0].name).toEqual('application-new-1');
|
||||
expect(response[0].status).toEqual('Running');
|
||||
expect(response[0].icon).toEqual('favorite_border');
|
||||
expect(response[0].theme).toEqual('theme-2');
|
||||
expect(response[1].name).toEqual('application-new-2');
|
||||
expect(response[1].status).toEqual('Pending');
|
||||
expect(response[1].icon).toEqual('favorite_border');
|
||||
expect(response[1].theme).toEqual('theme-2');
|
||||
});
|
||||
expect(getAppsSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display default adf-empty-content template when response empty', () => {
|
||||
getAppsSpy.and.returnValue(of([]));
|
||||
fixture.detectChanges();
|
||||
const defaultEmptyTemplate = fixture.nativeElement.querySelector('.adf-app-list-empty');
|
||||
const emptyContent = fixture.debugElement.nativeElement.querySelector('.adf-empty-content');
|
||||
const emptyTitle = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__title');
|
||||
const emptySubtitle = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__subtitle');
|
||||
expect(defaultEmptyTemplate).toBeDefined();
|
||||
expect(defaultEmptyTemplate).not.toBeNull();
|
||||
expect(emptyContent).not.toBeNull();
|
||||
expect(emptyTitle.innerText).toBe('ADF_TASK_LIST.APPS.TITLE');
|
||||
expect(emptySubtitle.innerText).toBe('ADF_TASK_LIST.APPS.SUBTITLE');
|
||||
expect(getAppsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('Grid Layout ', () => {
|
||||
|
||||
it('should display a grid by default', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(true);
|
||||
expect(component.isList()).toBe(false);
|
||||
});
|
||||
|
||||
it('should defined adf-cloud-app-details when layout type is grid', () => {
|
||||
fixture.detectChanges();
|
||||
const adfCloudDetailsElement = fixture.nativeElement.querySelectorAll('adf-cloud-app-details');
|
||||
const appName = fixture.nativeElement.querySelector('.adf-app-listgrid-item-card-title');
|
||||
expect(adfCloudDetailsElement).toBeDefined();
|
||||
expect(adfCloudDetailsElement).not.toBeNull();
|
||||
|
||||
expect(adfCloudDetailsElement.length).toEqual(2);
|
||||
expect(component.isGrid()).toBe(true);
|
||||
expect(component.isList()).toBe(false);
|
||||
|
||||
expect(appName.innerText.trim()).toEqual(fakeApplicationInstance[0].name);
|
||||
});
|
||||
|
||||
it('should display a grid when configured to', () => {
|
||||
component.layoutType = AppListCloudComponent.LAYOUT_GRID;
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(true);
|
||||
expect(component.isList()).toBe(false);
|
||||
});
|
||||
|
||||
it('should throw an exception on init if unknown type configured', () => {
|
||||
component.layoutType = 'unknown';
|
||||
expect(component.ngOnInit).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('List Layout ', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.layoutType = AppListCloudComponent.LAYOUT_LIST;
|
||||
});
|
||||
|
||||
it('should display a LIST when configured to', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(false);
|
||||
expect(component.isList()).toBe(true);
|
||||
});
|
||||
|
||||
it('should defined mat-list when layout type is LIST', () => {
|
||||
fixture.detectChanges();
|
||||
const appListElement = fixture.nativeElement.querySelectorAll('mat-list');
|
||||
const appListItemElement = fixture.nativeElement.querySelectorAll('mat-list-item');
|
||||
const appName = fixture.nativeElement.querySelector('.mat-list-text');
|
||||
expect(appListElement).toBeDefined();
|
||||
expect(appListElement).not.toBeNull();
|
||||
|
||||
expect(appListItemElement.length).toEqual(2);
|
||||
expect(component.isGrid()).toBe(false);
|
||||
expect(component.isList()).toBe(true);
|
||||
|
||||
expect(appName.innerText.trim()).toEqual(fakeApplicationInstance[0].name);
|
||||
});
|
||||
|
||||
it('should throw an exception on init if unknown type configured', () => {
|
||||
component.layoutType = 'unknown';
|
||||
expect(component.ngOnInit).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit a click event when app selected', () => {
|
||||
spyOn(component.appClick, 'emit');
|
||||
fixture.detectChanges();
|
||||
const onAppClick = fixture.nativeElement.querySelector('.mat-card');
|
||||
onAppClick.click();
|
||||
expect(component.appClick.emit).toHaveBeenCalledWith(fakeApplicationInstance[0]);
|
||||
});
|
||||
});
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<adf-cloud-app-list>
|
||||
<adf-empty-custom-content>
|
||||
<mat-icon>apps</mat-icon>
|
||||
<p id="custom-id">No Apps Found</p>
|
||||
</adf-empty-custom-content>
|
||||
</adf-cloud-app-list>
|
||||
`
|
||||
})
|
||||
class CustomEmptyAppListCloudTemplateComponent {
|
||||
}
|
||||
|
||||
describe('Custom CustomEmptyAppListCloudTemplateComponent', () => {
|
||||
let fixture: ComponentFixture<CustomEmptyAppListCloudTemplateComponent>;
|
||||
|
||||
setupTestBed({
|
||||
imports: [AppListTestingModule],
|
||||
declarations: [CustomEmptyAppListCloudTemplateComponent],
|
||||
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CustomEmptyAppListCloudTemplateComponent);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should render the custom empty template', async(() => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
const title: any = fixture.nativeElement.querySelector('#custom-id');
|
||||
expect(title.innerText).toBe('No Apps Found');
|
||||
});
|
||||
}));
|
||||
});
|
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EmptyCustomContentDirective } from '@alfresco/adf-core';
|
||||
import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AppsProcessCloudService } from '../services/apps-process-cloud.service';
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-app-list',
|
||||
templateUrl: './app-list-cloud.component.html',
|
||||
styleUrls: ['./app-list-cloud.component.scss']
|
||||
})
|
||||
export class AppListCloudComponent implements OnInit, AfterContentInit {
|
||||
|
||||
public static LAYOUT_LIST: string = 'LIST';
|
||||
public static LAYOUT_GRID: string = 'GRID';
|
||||
public static RUNNING_STATUS: string = 'Running';
|
||||
|
||||
@ContentChild(EmptyCustomContentDirective)
|
||||
emptyCustomContent: EmptyCustomContentDirective;
|
||||
|
||||
/** (**required**) Defines the layout of the apps. There are two possible
|
||||
* values, "GRID" and "LIST".
|
||||
*/
|
||||
@Input()
|
||||
layoutType: string = AppListCloudComponent.LAYOUT_GRID;
|
||||
|
||||
/** Emitted when an app entry is clicked. */
|
||||
@Output()
|
||||
appClick: EventEmitter<ApplicationInstanceModel> = new EventEmitter<ApplicationInstanceModel>();
|
||||
|
||||
apps$: Observable<any>;
|
||||
|
||||
hasEmptyCustomContentTemplate: boolean = false;
|
||||
|
||||
constructor(private appsProcessCloudService: AppsProcessCloudService) { }
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.isValidType()) {
|
||||
this.setDefaultLayoutType();
|
||||
}
|
||||
|
||||
this.apps$ = this.appsProcessCloudService.getDeployedApplicationsByStatus(AppListCloudComponent.RUNNING_STATUS);
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.emptyCustomContent) {
|
||||
this.hasEmptyCustomContentTemplate = true;
|
||||
}
|
||||
}
|
||||
|
||||
onSelectApp(app: ApplicationInstanceModel): void {
|
||||
this.appClick.emit(app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value of the layoutType property is an allowed value
|
||||
*/
|
||||
isValidType(): boolean {
|
||||
if (this.layoutType && (this.layoutType === AppListCloudComponent.LAYOUT_LIST || this.layoutType === AppListCloudComponent.LAYOUT_GRID)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the default value to LayoutType
|
||||
*/
|
||||
setDefaultLayoutType(): void {
|
||||
this.layoutType = AppListCloudComponent.LAYOUT_GRID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the layout type is LIST
|
||||
*/
|
||||
isList(): boolean {
|
||||
return this.layoutType === AppListCloudComponent.LAYOUT_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the layout type is GRID
|
||||
*/
|
||||
isGrid(): boolean {
|
||||
|
||||
return this.layoutType === AppListCloudComponent.LAYOUT_GRID;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
export let fakeApplicationInstance = [
|
||||
new ApplicationInstanceModel(
|
||||
{ name: 'application-new-1', createdAt: '2018-09-21T12:31:39.000Z', status: 'Running', theme: 'theme-2', icon: 'favorite_border' }),
|
||||
new ApplicationInstanceModel(
|
||||
{ name: 'application-new-2', createdAt: '2018-09-21T12:31:39.000Z', status: 'Pending', theme: 'theme-2', icon: 'favorite_border' })
|
||||
];
|
@@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class ApplicationInstanceModel {
|
||||
|
||||
public static DEFAULT_THEME: string = 'theme-2';
|
||||
public static DEFAULT_ICON: string = 'favorite_border';
|
||||
|
||||
name: string;
|
||||
createdAt: any;
|
||||
status: string;
|
||||
theme?: string;
|
||||
icon?: string;
|
||||
description?: string;
|
||||
connectors?: any;
|
||||
|
||||
constructor(obj?: any) {
|
||||
if (obj) {
|
||||
this.name = obj.name ? obj.name : null;
|
||||
this.status = obj.status ? obj.status : null;
|
||||
this.createdAt = obj.createdAt ? obj.createdAt : null;
|
||||
this.theme = obj.theme ? obj.theme : ApplicationInstanceModel.DEFAULT_THEME;
|
||||
this.icon = obj.icon ? obj.icon : ApplicationInstanceModel.DEFAULT_ICON;
|
||||
this.description = obj.description ? obj.description : null;
|
||||
this.connectors = obj.connectors ? obj.connectors : null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './components/app-list-cloud.component';
|
||||
export * from './models/application-instance.model';
|
||||
export * from './apps-list-cloud.module';
|
@@ -0,0 +1,73 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { AppsProcessCloudService } from './apps-process-cloud.service';
|
||||
import { fakeApplicationInstance } from '../mock/app-model.mock';
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
import { AppListTestingModule } from '../testing/app-list.testing.module';
|
||||
|
||||
describe('AppsProcessCloudService', () => {
|
||||
|
||||
let service: AppsProcessCloudService;
|
||||
|
||||
setupTestBed({
|
||||
imports: [AppListTestingModule],
|
||||
providers: [AppsProcessCloudService]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.get(AppsProcessCloudService);
|
||||
});
|
||||
|
||||
it('should get the deployed applications ', (done) => {
|
||||
spyOn(service, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
|
||||
service.getDeployedApplicationsByStatus('fake').subscribe(
|
||||
(res: ApplicationInstanceModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res).toEqual(fakeApplicationInstance);
|
||||
expect(res[0]).toEqual(fakeApplicationInstance[0]);
|
||||
expect(res[0].name).toEqual('application-new-1');
|
||||
expect(res[1]).toEqual(fakeApplicationInstance[1]);
|
||||
expect(res[1].name).toEqual('application-new-2');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Should not fetch deployed applications if error occurred', () => {
|
||||
const errorResponse = new HttpErrorResponse({
|
||||
error: 'Mock Error',
|
||||
status: 404, statusText: 'Not Found'
|
||||
});
|
||||
|
||||
spyOn(service, 'getDeployedApplicationsByStatus').and.returnValue(throwError(errorResponse));
|
||||
service.getDeployedApplicationsByStatus('fake')
|
||||
.subscribe(
|
||||
users => fail('expected an error, not applications'),
|
||||
error => {
|
||||
expect(error.status).toEqual(404);
|
||||
expect(error.statusText).toEqual('Not Found');
|
||||
expect(error.error).toEqual('Mock Error');
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
@@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, from, throwError } from 'rxjs';
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { AppConfigService, LogService } from '@alfresco/adf-core';
|
||||
import { ApplicationInstanceModel } from '../models/application-instance.model';
|
||||
|
||||
@Injectable()
|
||||
export class AppsProcessCloudService {
|
||||
|
||||
contextRoot = '';
|
||||
|
||||
constructor(
|
||||
private apiService: AlfrescoApiService,
|
||||
private logService: LogService,
|
||||
private appConfig: AppConfigService) {
|
||||
this.contextRoot = this.appConfig.get('bpmHost', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of deployed apps for this user by status.
|
||||
* @returns The list of deployed apps
|
||||
*/
|
||||
getDeployedApplicationsByStatus(status: string): Observable<ApplicationInstanceModel[]> {
|
||||
const api: any = this.apiService.getInstance().oauth2Auth;
|
||||
api.basePath = this.contextRoot;
|
||||
const path = 'alfresco-deployment-service/v1/applications';
|
||||
const httpMethod = 'GET', pathParams = {}, queryParams = {},
|
||||
headerParams = {}, formParams = {}, bodyParam = {}, authNames = [],
|
||||
contentTypes = ['application/json'], accepts = ['application/json'];
|
||||
return from(api.callApi(
|
||||
path, httpMethod,
|
||||
pathParams, queryParams, headerParams, formParams, bodyParam,
|
||||
authNames, contentTypes, accepts, [], ''
|
||||
))
|
||||
.pipe(
|
||||
map((apps: Array<{}>) => {
|
||||
return apps.filter((app: ApplicationInstanceModel) => app.status === status)
|
||||
.map((app) => {
|
||||
return new ApplicationInstanceModel(app);
|
||||
});
|
||||
}
|
||||
),
|
||||
catchError(err => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
private handleError(error?: any) {
|
||||
this.logService.error(error);
|
||||
return throwError(error || 'Server error');
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { AppListCloudModule } from '../app-list-cloud.module';
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
AlfrescoApiServiceMock,
|
||||
AppConfigService,
|
||||
AppConfigServiceMock,
|
||||
StorageService,
|
||||
LogService,
|
||||
TranslationService,
|
||||
TranslationMock
|
||||
} from '@alfresco/adf-core';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
HttpClientModule,
|
||||
NoopAnimationsModule,
|
||||
AppListCloudModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
|
||||
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||
{ provide: TranslationService, useClass: TranslationMock },
|
||||
StorageService,
|
||||
LogService
|
||||
]
|
||||
})
|
||||
export class AppListTestingModule {}
|
44
lib/process-services-cloud/src/lib/material.module.ts
Normal file
44
lib/process-services-cloud/src/lib/material.module.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import {
|
||||
MAT_LABEL_GLOBAL_OPTIONS, MatAutocompleteModule, MatButtonModule, MatCardModule, MatCheckboxModule,
|
||||
MatChipsModule, MatDatepickerModule, MatDialogModule, MatGridListModule, MatIconModule,
|
||||
MatInputModule, MatListModule, MatNativeDateModule, MatOptionModule, MatProgressSpinnerModule, MatRadioModule,
|
||||
MatRippleModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule,
|
||||
MatTooltipModule, MatMenuModule
|
||||
} from '@angular/material';
|
||||
|
||||
export function modules() {
|
||||
return [
|
||||
MatAutocompleteModule, MatButtonModule, MatCardModule, MatDialogModule,
|
||||
MatCheckboxModule, MatDatepickerModule, MatGridListModule, MatIconModule, MatInputModule,
|
||||
MatListModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule, MatTableModule,
|
||||
MatTabsModule, MatProgressSpinnerModule, MatNativeDateModule, MatRippleModule, MatTooltipModule,
|
||||
MatChipsModule, MatMenuModule
|
||||
];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
{provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: { float: 'never' }}
|
||||
],
|
||||
imports: modules(),
|
||||
exports: modules()
|
||||
})
|
||||
export class MaterialModule {}
|
@@ -1,9 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { HelloModule } from './hello/hello.module';
|
||||
import { TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||
import { AppListCloudModule } from './app-list-cloud/app-list-cloud.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
HelloModule
|
||||
AppListCloudModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
@@ -16,6 +17,6 @@ import { TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||
}
|
||||
],
|
||||
declarations: [],
|
||||
exports: [HelloModule]
|
||||
exports: [AppListCloudModule]
|
||||
})
|
||||
export class ProcessServicesCloudModule { }
|
||||
|
@@ -1,2 +1,7 @@
|
||||
@import './../app-list-cloud/components/app-details-cloud.component';
|
||||
@import './../app-list-cloud/components/app-list-cloud.component';
|
||||
|
||||
@mixin adf-process-services-cloud-theme($theme) {
|
||||
@include adf-cloud-app-list-theme($theme);
|
||||
@include adf-cloud-app-details-theme($theme);
|
||||
}
|
||||
|
@@ -16,4 +16,4 @@
|
||||
*/
|
||||
|
||||
export * from './lib/process-services-cloud.module';
|
||||
export * from './lib/hello/hello.module';
|
||||
export * from './lib/app-list-cloud/app-list-cloud.module';
|
||||
|
41
lib/process-services-cloud/test.ts
Normal file
41
lib/process-services-cloud/test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import 'core-js/es7/reflect';
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
declare const pdfjsLib: any;
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.min.js';
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
42
lib/process-services-cloud/tsconfig.json
Normal file
42
lib/process-services-cloud/tsconfig.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": false,
|
||||
"noLib": false,
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": false,
|
||||
"noImplicitUseStrict": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"removeComments": true,
|
||||
"declaration": true,
|
||||
"outDir": "../dist/process-services-cloud/",
|
||||
"baseUrl" : "./",
|
||||
"paths": {
|
||||
"@alfresco/adf-content-services": ["../content-services"],
|
||||
"@alfresco/adf-insights": ["../analytics"],
|
||||
"@alfresco/adf-core": ["../core"]
|
||||
},
|
||||
"lib": [
|
||||
"es2016",
|
||||
"dom"
|
||||
],
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noUnusedLocals": true
|
||||
},
|
||||
"exclude": [
|
||||
"demo",
|
||||
"node_modules",
|
||||
"dist"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"strictMetadataEmit": false,
|
||||
"skipTemplateCodegen": true
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user