diff --git a/package.json b/package.json
index 44cf74c1b4..f9d93a56c6 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"test": "run-s test-frontend:* --continue-on-error",
"test-frontend:core": "ng test core --code-coverage --watch=false",
"test-frontend:store": "ng test store --code-coverage --watch=false",
+ "test-frontend:cloud-foundry": "ng test cloud-foundry --code-coverage --watch=false",
"posttest": "istanbul report json && node build/combine-coverage.js",
"codecov": "codecov -f coverage/coverage-final.json",
"lint": "ng lint --format stylish",
diff --git a/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts
new file mode 100644
index 0000000000..e8429cf42d
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/cloud-foundry.module.ts
@@ -0,0 +1,28 @@
+import { NgModule } from '@angular/core';
+
+import { StratosExtension } from '../../core/src/core/extension/extension-service';
+import { EndpointTypeConfig } from '../../core/src/core/extension/extension-types';
+import { urlValidationExpression } from '../../core/src/core/utils.service';
+import { CfEndpointDetailsComponent } from './shared/components/cf-endpoint-details/cf-endpoint-details.component';
+import { CloudFoundryComponentsModule } from './shared/components/components.module';
+
+const cloudFoundryEndpointTypes: EndpointTypeConfig[] = [{
+ value: 'cf',
+ label: 'Cloud Foundry',
+ urlValidation: urlValidationExpression,
+ icon: 'cloud_foundry',
+ iconFont: 'stratos-icons',
+ imagePath: '/core/assets/endpoint-icons/cloudfoundry.png',
+ homeLink: (guid) => ['/cloud-foundry', guid],
+ listDetailsComponent: CfEndpointDetailsComponent
+}];
+
+@StratosExtension({
+ endpointTypes: cloudFoundryEndpointTypes,
+})
+@NgModule({
+ imports: [
+ CloudFoundryComponentsModule
+ ],
+})
+export class CloudFoundryModule { }
diff --git a/src/frontend/packages/cloud-foundry/src/public_api.ts b/src/frontend/packages/cloud-foundry/src/public_api.ts
index ef11c82c31..eef53f2d79 100644
--- a/src/frontend/packages/cloud-foundry/src/public_api.ts
+++ b/src/frontend/packages/cloud-foundry/src/public_api.ts
@@ -2,6 +2,6 @@
* Public API Surface of cloud-foundry
*/
-export * from './lib/cloud-foundry.service';
+// export * from './lib/cloud-foundry.service';
export * from './lib/cloud-foundry.component';
export * from './lib/cloud-foundry.module';
diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html
new file mode 100644
index 0000000000..52465960a6
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.html
@@ -0,0 +1,9 @@
+
+
+
+ person
+
+ {{ user.name}} (Administrator)
+
+
+-
\ No newline at end of file
diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss
new file mode 100644
index 0000000000..5b7707aa0e
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.scss
@@ -0,0 +1,16 @@
+.cf-details {
+ display: flex;
+ flex-direction: column;
+
+ &__line {
+ align-items: center;
+ display: flex;
+ }
+
+ &__icon {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ width: 32px;
+ }
+}
diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts
new file mode 100644
index 0000000000..c6cf04c3a1
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.spec.ts
@@ -0,0 +1,31 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CoreModule } from '../../../../../core/src/core/core.module';
+import { SharedModule } from '../../../../../core/src/shared/shared.module';
+import { CfEndpointDetailsComponent } from './cf-endpoint-details.component';
+
+describe('CfEndpointDetailsComponent', () => {
+ let component: CfEndpointDetailsComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [CfEndpointDetailsComponent],
+ imports: [
+ CoreModule,
+ SharedModule
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CfEndpointDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts
new file mode 100644
index 0000000000..0012fef5d0
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/shared/components/cf-endpoint-details/cf-endpoint-details.component.ts
@@ -0,0 +1,13 @@
+import { Component } from '@angular/core';
+
+import {
+ EndpointListDetailsComponent,
+} from '../../../../../core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers';
+
+
+@Component({
+ selector: 'lib-cf-endpoint-details',
+ templateUrl: './cf-endpoint-details.component.html',
+ styleUrls: ['./cf-endpoint-details.component.scss']
+})
+export class CfEndpointDetailsComponent extends EndpointListDetailsComponent { }
diff --git a/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts b/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts
new file mode 100644
index 0000000000..3ec2e28d4e
--- /dev/null
+++ b/src/frontend/packages/cloud-foundry/src/shared/components/components.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+
+import { CoreModule } from '../../../../core/src/core/core.module';
+import { CfEndpointDetailsComponent } from './cf-endpoint-details/cf-endpoint-details.component';
+
+@NgModule({
+ imports: [
+ CoreModule
+ ],
+ declarations: [
+ CfEndpointDetailsComponent
+ ],
+ exports: [
+ CfEndpointDetailsComponent
+ ],
+ entryComponents: [
+ CfEndpointDetailsComponent
+ ]
+})
+export class CloudFoundryComponentsModule { }
diff --git a/src/frontend/packages/cloud-foundry/src/test.ts b/src/frontend/packages/cloud-foundry/src/test.ts
index d0b441ad3d..18653a67a2 100644
--- a/src/frontend/packages/cloud-foundry/src/test.ts
+++ b/src/frontend/packages/cloud-foundry/src/test.ts
@@ -1,10 +1,7 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-import 'zone.js/dist/long-stack-trace-zone';
-import 'zone.js/dist/proxy';
-import 'zone.js/dist/sync-test';
-import 'zone.js/dist/jasmine-patch';
-import 'zone.js/dist/async-test';
-import 'zone.js/dist/fake-async-test';
+import 'core-js/es7/reflect';
+import 'zone.js/dist/zone';
+import 'zone.js/dist/zone-testing';
import { APP_BASE_HREF } from '@angular/common';
import { getTestBed } from '@angular/core/testing';
diff --git a/src/frontend/packages/cloud-foundry/tsconfig.spec.json b/src/frontend/packages/cloud-foundry/tsconfig.spec.json
index 1fe1c34b80..cb4a7be918 100644
--- a/src/frontend/packages/cloud-foundry/tsconfig.spec.json
+++ b/src/frontend/packages/cloud-foundry/tsconfig.spec.json
@@ -2,6 +2,10 @@
"extends": "../../../tsconfig.spec.json",
"compilerOptions": {
"outDir": "../../../../out-tsc/spec",
+ "types": [
+ "jasmine",
+ "node"
+ ]
},
"files": [
"src/test.ts"
@@ -9,8 +13,5 @@
"include": [
"**/*.spec.ts",
"**/*.d.ts"
- ],
- "exclude": [
- "**/node_modules/**"
]
}
diff --git a/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png b/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png
new file mode 100644
index 0000000000..cc022705d5
Binary files /dev/null and b/src/frontend/packages/core/assets/endpoint-icons/cloudfoundry.png differ
diff --git a/src/frontend/packages/core/assets/endpoint-icons/metrics.svg b/src/frontend/packages/core/assets/endpoint-icons/metrics.svg
new file mode 100644
index 0000000000..5c51f66d90
--- /dev/null
+++ b/src/frontend/packages/core/assets/endpoint-icons/metrics.svg
@@ -0,0 +1,50 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/app.module.ts b/src/frontend/packages/core/src/app.module.ts
index e69c22a32e..b2ddb80e3b 100644
--- a/src/frontend/packages/core/src/app.module.ts
+++ b/src/frontend/packages/core/src/app.module.ts
@@ -6,6 +6,7 @@ import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router
import { Store } from '@ngrx/store';
import { debounceTime, withLatestFrom } from 'rxjs/operators';
+import { CloudFoundryModule } from '../../cloud-foundry/src/cloud-foundry.module';
import { GetAllEndpoints } from '../../store/src/actions/endpoint.actions';
import { GetOrganization } from '../../store/src/actions/organization.actions';
import { SetRecentlyVisitedEntityAction } from '../../store/src/actions/recently-visited.actions';
@@ -38,6 +39,7 @@ import { CurrentUserPermissionsService } from './core/current-user-permissions.s
import { DynamicExtensionRoutes } from './core/extension/dynamic-extension-routes';
import { ExtensionService } from './core/extension/extension-service';
import { getGitHubAPIURL, GITHUB_API_URL } from './core/github.helpers';
+import { LoggerService } from './core/logger.service';
import { UserFavoriteManager } from './core/user-favorite-manager';
import { CustomImportModule } from './custom-import.module';
import { AboutModule } from './features/about/about.module';
@@ -56,7 +58,6 @@ import { ApplicationStateService } from './shared/components/application-state/a
import { favoritesConfigMapper } from './shared/components/favorites-meta-card/favorite-config-mapper';
import { SharedModule } from './shared/shared.module';
import { XSRFModule } from './xsrf.module';
-import { LoggerService } from './core/logger.service';
// Create action for router navigation. See
// - https://github.com/ngrx/platform/issues/68
@@ -113,6 +114,7 @@ export class CustomRouterStateSerializer
AboutModule,
CustomImportModule,
XSRFModule,
+ CloudFoundryModule
],
providers: [
LoggedInService,
@@ -138,7 +140,7 @@ export class AppModule {
initEndpointExtensions(ext);
// Once the CF modules become an extension point, these should be moved to a CF specific module
this.registerCfFavoriteMappers();
- this.userFavoriteManager = new UserFavoriteManager(store, logger);
+ this.userFavoriteManager = new UserFavoriteManager(store, logger);
const allFavs$ = this.userFavoriteManager.getAllFavorites();
const recents$ = this.store.select(recentlyVisitedSelector);
const debouncedApiRequestData$ = this.store.select(getAPIRequestDataState).pipe(debounceTime(2000));
diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts
index 63958dc505..0a3757a28d 100644
--- a/src/frontend/packages/core/src/core/core.module.ts
+++ b/src/frontend/packages/core/src/core/core.module.ts
@@ -10,6 +10,7 @@ import { BytesToHumanSize, MegaBytesToHumanSize } from './byte-formatters.pipe';
import { ClickStopPropagationDirective } from './click-stop-propagation.directive';
import { CurrentUserPermissionsService } from './current-user-permissions.service';
import { Customizations } from './customizations.types';
+import { DisableRouterLinkDirective } from './disable-router-link.directive';
import { DotContentComponent } from './dot-content/dot-content.component';
import { EndpointsService } from './endpoints.service';
import { EntityFavoriteStarComponent } from './entity-favorite-star/entity-favorite-star.component';
@@ -51,7 +52,8 @@ import { WindowRef } from './window-ref/window-ref.service';
ButtonBlurOnClickDirective,
PageNotFoundComponentComponent,
EntityFavoriteStarComponent,
- RecentEntitiesComponent
+ RecentEntitiesComponent,
+ DisableRouterLinkDirective
],
providers: [
AuthGuardService,
@@ -78,7 +80,8 @@ import { WindowRef } from './window-ref/window-ref.service';
ButtonBlurOnClickDirective,
PageNotFoundComponentComponent,
EntityFavoriteStarComponent,
- RecentEntitiesComponent
+ RecentEntitiesComponent,
+ DisableRouterLinkDirective
],
entryComponents: [
LogOutDialogComponent
diff --git a/src/frontend/packages/core/src/core/disable-router-link.directive.ts b/src/frontend/packages/core/src/core/disable-router-link.directive.ts
new file mode 100644
index 0000000000..3a24c8ecfc
--- /dev/null
+++ b/src/frontend/packages/core/src/core/disable-router-link.directive.ts
@@ -0,0 +1,32 @@
+import { Directive, Input, Optional } from '@angular/core';
+import { RouterLink, RouterLinkWithHref } from '@angular/router';
+
+@Directive({
+ selector: '[routerLink][appDisableRouterLink]'
+})
+export class DisableRouterLinkDirective {
+
+ @Input() appDisableRouterLink: boolean;
+
+ constructor(
+ // Inject routerLink
+ @Optional() routerLink: RouterLink,
+ @Optional() routerLinkWithHref: RouterLinkWithHref
+ ) {
+
+ const link = routerLink || routerLinkWithHref;
+
+ // Save original method
+ const onClick = link.onClick;
+
+ // Replace method
+ link.onClick = (...args) => {
+ if (this.appDisableRouterLink) {
+ return routerLinkWithHref ? false : true;
+ } else {
+ return onClick.apply(link, args);
+ }
+ };
+ }
+
+}
diff --git a/src/frontend/packages/core/src/core/endpoints.service.ts b/src/frontend/packages/core/src/core/endpoints.service.ts
index 9af41000bd..eae3d2ec5e 100644
--- a/src/frontend/packages/core/src/core/endpoints.service.ts
+++ b/src/frontend/packages/core/src/core/endpoints.service.ts
@@ -16,6 +16,7 @@ import { UserService } from './user.service';
import { AuthState } from '../../../store/src/reducers/auth.reducer';
import { RouterNav } from '../../../store/src/actions/router.actions';
import { endpointHealthChecks, EndpointHealthCheck } from '../../endpoints-health-checks';
+import { getEndpointTypes } from '../features/endpoints/endpoint-helpers';
@Injectable()
@@ -25,6 +26,17 @@ export class EndpointsService implements CanActivate {
haveRegistered$: Observable;
haveConnected$: Observable;
+ static getLinkForEndpoint(endpoint: EndpointModel): string {
+ if (!endpoint) {
+ return '';
+ }
+ const ext = getEndpointTypes().find(ep => ep.value === endpoint.cnsi_type);
+ if (ext && ext.homeLink) {
+ return ext.homeLink(endpoint.guid).join('/');
+ }
+ return '';
+ }
+
constructor(
private store: Store,
private userService: UserService
@@ -101,5 +113,4 @@ export class EndpointsService implements CanActivate {
);
}
-
}
diff --git a/src/frontend/packages/core/src/core/extension/extension-types.ts b/src/frontend/packages/core/src/core/extension/extension-types.ts
index 8c1edd965c..74f30c9d52 100644
--- a/src/frontend/packages/core/src/core/extension/extension-types.ts
+++ b/src/frontend/packages/core/src/core/extension/extension-types.ts
@@ -12,11 +12,20 @@ export interface EndpointTypeConfig {
allowTokenSharing?: boolean;
icon?: string;
iconFont?: string;
+ imagePath?: string;
authTypes?: string[];
- // Get the link to the home page for the given endpoint GUID
- homeLink?: (link: string) => string[];
- // Schema keys associated with this endpoint type (used when clearing pagination)
+ /**
+ * Get the link to the home page for the given endpoint GUID
+ */
+ homeLink?: (s) => string[];
+ /**
+ * Schema keys associated with this endpoint type (used when clearing pagination)
+ */
entitySchemaKeys?: string[];
+ /**
+ * Show custom content in the endpoints list. Should be Type
+ */
+ listDetailsComponent?: any;
}
export interface EndpointAuthTypeConfig {
diff --git a/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts b/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts
index da0a0d0416..5ac649661b 100644
--- a/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts
+++ b/src/frontend/packages/core/src/features/cloud-foundry/cloud-foundry.module.ts
@@ -8,6 +8,7 @@ import { CustomImportModule } from '../../custom-import.module';
import {
CFEndpointsListConfigService,
} from '../../shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service';
+import { EndpointListHelper } from '../../shared/components/list/list-types/endpoint/endpoint-list.helpers';
import { EndpointsListConfigService } from '../../shared/components/list/list-types/endpoint/endpoints-list-config.service';
import { SharedModule } from '../../shared/shared.module';
import { AddOrganizationComponent } from './add-organization/add-organization.component';
@@ -162,6 +163,7 @@ import { UsersRolesComponent } from './users/manage-users/manage-users.component
CfAdminAddUserWarningComponent,
],
providers: [
+ EndpointListHelper,
CFEndpointsListConfigService,
EndpointsListConfigService,
{
@@ -176,7 +178,7 @@ import { UsersRolesComponent } from './users/manage-users/manage-users.component
CloudFoundryEndpointService,
CfRolesService,
CloudFoundryCellService,
- UserInviteService,
+ UserInviteService
],
entryComponents: [
UserInviteConfigurationDialogComponent
diff --git a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts
index d7e8b5c54d..35f6f9a867 100644
--- a/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts
+++ b/src/frontend/packages/core/src/features/endpoints/endpoint-helpers.ts
@@ -1,19 +1,19 @@
+import { Type } from '@angular/core';
+import { Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { first, map } from 'rxjs/operators';
-import { Validators } from '@angular/forms';
-
-import { urlValidationExpression } from '../../core/utils.service';
-import { EndpointModel } from '../../../../store/src/types/endpoint.types';
-import { EndpointTypeConfig, EndpointAuthTypeConfig, EndpointType } from '../../core/extension/extension-types';
import { AppState } from '../../../../store/src/app-state';
-import { selectEntities } from '../../../../store/src/selectors/api.selectors';
import { endpointSchemaKey } from '../../../../store/src/helpers/entity-factory';
+import { selectEntities } from '../../../../store/src/selectors/api.selectors';
+import { EndpointModel } from '../../../../store/src/types/endpoint.types';
import { ExtensionService } from '../../core/extension/extension-service';
+import { EndpointAuthTypeConfig, EndpointType, EndpointTypeConfig } from '../../core/extension/extension-types';
+import { EndpointListDetailsComponent } from '../../shared/components/list/list-types/endpoint/endpoint-list.helpers';
import { CredentialsAuthFormComponent } from './connect-endpoint-dialog/auth-forms/credentials-auth-form.component';
-import { SSOAuthFormComponent } from './connect-endpoint-dialog/auth-forms/sso-auth-form.component';
import { NoneAuthFormComponent } from './connect-endpoint-dialog/auth-forms/none-auth-form.component';
+import { SSOAuthFormComponent } from './connect-endpoint-dialog/auth-forms/sso-auth-form.component';
export function getFullEndpointApiUrl(endpoint: EndpointModel) {
return endpoint && endpoint.api_endpoint ? `${endpoint.api_endpoint.Scheme}://${endpoint.api_endpoint.Host}` : 'Unknown';
@@ -31,18 +31,11 @@ export interface EndpointIcon {
}
const endpointTypes: EndpointTypeConfig[] = [
- {
- value: 'cf',
- label: 'Cloud Foundry',
- urlValidation: urlValidationExpression,
- icon: 'cloud_foundry',
- iconFont: 'stratos-icons',
- homeLink: (guid) => ['/cloud-foundry', guid]
- },
{
value: 'metrics',
label: 'Metrics',
allowTokenSharing: true,
+ imagePath: '/core/assets/endpoint-icons/metrics.svg',
homeLink: (guid) => ['/endpoints/metrics', guid]
},
];
@@ -76,6 +69,9 @@ let endpointAuthTypes: EndpointAuthTypeConfig[] = [
const endpointTypesMap = {};
+// Any initial endpointTypes listDetailsComponent should be added here
+export const coreEndpointListDetailsComponents: Type[] = [];
+
export function initEndpointTypes(epTypes: EndpointTypeConfig[]) {
epTypes.forEach(epType => {
endpointTypes.push(epType);
@@ -114,6 +110,10 @@ export function getEndpointTypes() {
return endpointTypes;
}
+export function getEndpointType(type: string): EndpointTypeConfig {
+ return getEndpointTypes().find(ep => ep.value === type);
+}
+
export function getIconForEndpoint(type: string): EndpointIcon {
const icon = {
name: 'settings_ethernet',
diff --git a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts
index b10e7be3eb..e3084deb45 100644
--- a/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts
+++ b/src/frontend/packages/core/src/features/endpoints/endpoints-page/endpoints-page.component.ts
@@ -17,6 +17,7 @@ import {
EndpointsListConfigService,
} from '../../../shared/components/list/list-types/endpoint/endpoints-list-config.service';
import { ListConfig } from '../../../shared/components/list/list.component.types';
+import { EndpointListHelper } from '../../../shared/components/list/list-types/endpoint/endpoint-list.helpers';
@Component({
selector: 'app-endpoints-page',
@@ -25,7 +26,7 @@ import { ListConfig } from '../../../shared/components/list/list.component.types
providers: [{
provide: ListConfig,
useClass: EndpointsListConfigService,
- }]
+ }, EndpointListHelper]
})
export class EndpointsPageComponent implements OnDestroy, OnInit {
diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts
index 3ae80571ff..de0f98d1ab 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-cards/card/card.component.ts
@@ -12,26 +12,26 @@ import {
} from '@angular/core';
import { IListDataSource } from '../../data-sources-controllers/list-data-source-types';
-
-import { CardCell } from '../../list.types';
+import {
+ AppServiceBindingCardComponent,
+} from '../../list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component';
import { CardAppComponent } from '../../list-types/app/card/card-app.component';
-import { EndpointCardComponent } from '../../list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component';
-import { CfOrgCardComponent } from '../../list-types/cf-orgs/cf-org-card/cf-org-card.component';
-import { CfSpaceCardComponent } from '../../list-types/cf-spaces/cf-space-card/cf-space-card.component';
import { CfBuildpackCardComponent } from '../../list-types/cf-buildpacks/cf-buildpack-card/cf-buildpack-card.component';
+import { CfOrgCardComponent } from '../../list-types/cf-orgs/cf-org-card/cf-org-card.component';
import {
- CfSecurityGroupsCardComponent
+ CfSecurityGroupsCardComponent,
} from '../../list-types/cf-security-groups/cf-security-groups-card/cf-security-groups-card.component';
-import { CfStacksCardComponent } from '../../list-types/cf-stacks/cf-stacks-card/cf-stacks-card.component';
import { CfServiceCardComponent } from '../../list-types/cf-services/cf-service-card/cf-service-card.component';
+import { CfSpaceCardComponent } from '../../list-types/cf-spaces/cf-space-card/cf-space-card.component';
+import { CfStacksCardComponent } from '../../list-types/cf-stacks/cf-stacks-card/cf-stacks-card.component';
+import { EndpointCardComponent } from '../../list-types/endpoint/endpoint-card/endpoint-card.component';
import {
- AppServiceBindingCardComponent
-} from '../../list-types/app-sevice-bindings/app-service-binding-card/app-service-binding-card.component';
-import { ServiceInstanceCardComponent } from '../../list-types/services-wall/service-instance-card/service-instance-card.component';
+ ServiceInstanceCardComponent,
+} from '../../list-types/services-wall/service-instance-card/service-instance-card.component';
+import { CardCell } from '../../list.types';
export const listCards = [
CardAppComponent,
- EndpointCardComponent,
CfOrgCardComponent,
CfSpaceCardComponent,
CfBuildpackCardComponent,
@@ -39,7 +39,8 @@ export const listCards = [
CfStacksCardComponent,
CfServiceCardComponent,
AppServiceBindingCardComponent,
- ServiceInstanceCardComponent
+ ServiceInstanceCardComponent,
+ EndpointCardComponent
];
@Component({
selector: 'app-card',
diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.html b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.html
index 716f13842f..85d8279293 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.html
+++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.html
@@ -9,4 +9,4 @@
-
+
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts
index 94688ab4b0..ec19984bbe 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-cards/meta-card/meta-card-item/meta-card-item.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, Component, ContentChild, OnInit, TemplateRef, ViewChild, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, ContentChild, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { MetaCardKeyComponent } from '../meta-card-key/meta-card-key.component';
import { MetaCardValueComponent } from '../meta-card-value/meta-card-value.component';
@@ -29,9 +29,6 @@ export class MetaCardItemComponent implements OnInit {
@Input() customStyle = 'row';
- constructor() {
- }
-
ngOnInit() {
this.itemStyle = this.styles[this.customStyle];
}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts
index 0442b8d66a..2e0a6232bb 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-table/table-cell/table-cell.component.ts
@@ -13,6 +13,7 @@ import {
ViewEncapsulation,
} from '@angular/core';
+import { coreEndpointListDetailsComponents } from '../../../../../features/endpoints/endpoint-helpers';
import { IListDataSource } from '../../data-sources-controllers/list-data-source-types';
import {
TableCellEventActionComponent,
@@ -84,8 +85,8 @@ import {
CfSpacePermissionCellComponent,
} from '../../list-types/cf-users/cf-space-permission-cell/cf-space-permission-cell.component';
import {
- TableCellEndpointIsAdminComponent,
-} from '../../list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component';
+ TableCellEndpointDetailsComponent,
+} from '../../list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component';
import {
TableCellEndpointNameComponent,
} from '../../list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component';
@@ -118,7 +119,6 @@ import { TableCellSelectComponent } from '../table-cell-select/table-cell-select
import { TableHeaderSelectComponent } from '../table-header-select/table-header-select.component';
import { ICellDefinition } from '../table.types';
-
/* tslint:enable:max-line-length */
export const listTableCells = [
TableCellDefaultComponent,
@@ -160,11 +160,12 @@ export const listTableCells = [
TableCellSpaceNameComponent,
TableCellAppCfOrgSpaceHeaderComponent,
TableCellAppCfOrgSpaceComponent,
- TableCellEndpointIsAdminComponent,
TableCellAServicePlanPublicComponent,
TableCellAServicePlanPriceComponent,
TableCellAServicePlanExtrasComponent,
- TableCellFavoriteComponent
+ TableCellFavoriteComponent,
+ TableCellEndpointDetailsComponent,
+ ...coreEndpointListDetailsComponents
];
@Component({
diff --git a/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts b/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts
index 7c3d49c504..9b67e6d6e6 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-table/table.types.ts
@@ -57,5 +57,5 @@ export const listTableComponents = [
TableRowComponent,
TableCellDefaultComponent,
...listTableCells,
- TableCellStatusDirective,
+ TableCellStatusDirective
];
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts
index c6827dcb8f..3925a7cd75 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/base-endpoints-data-source.ts
@@ -1,12 +1,13 @@
import { Store } from '@ngrx/store';
-import { AppState } from '../../../../../../../store/src/app-state';
+
import { GetAllEndpoints } from '../../../../../../../store/src/actions/endpoint.actions';
import { CreatePagination } from '../../../../../../../store/src/actions/pagination.actions';
-import { ListDataSource } from '../../data-sources-controllers/list-data-source';
+import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions';
+import { AppState } from '../../../../../../../store/src/app-state';
+import { endpointSchemaKey, entityFactory } from '../../../../../../../store/src/helpers/entity-factory';
import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types';
+import { ListDataSource } from '../../data-sources-controllers/list-data-source';
import { IListConfig } from '../../list.component.types';
-import { entityFactory, endpointSchemaKey } from '../../../../../../../store/src/helpers/entity-factory';
-import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions';
function syncPaginationSection(
@@ -22,6 +23,7 @@ function syncPaginationSection(
}
export class BaseEndpointsDataSource extends ListDataSource {
store: Store;
+ endpointType: string;
constructor(
store: Store,
@@ -54,5 +56,6 @@ export class BaseEndpointsDataSource extends ListDataSource {
listConfig,
refresh: () => this.store.dispatch(new GetSystemInfo(false, action))
});
+ this.endpointType = endpointType;
}
}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html
deleted file mode 100644
index 6b87693173..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {{ row.name }}
-
- Address
- {{ getEndpointUrl(row) }}
-
-
- Account Username
- {{ row.user.name }}
-
-
- Administrator
-
-
-
-
-
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss
deleted file mode 100644
index ce7d1d2449..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.endpoint-card {
- cursor: pointer;
- &:focus {
- outline: 0;
- }
-}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts
deleted file mode 100644
index 3b7851addf..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.spec.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
-
-import { SharedModule } from '../../../../../shared.module';
-import { EntityMonitorFactory } from '../../../../../monitors/entity-monitor.factory.service';
-import { createBasicStoreModule } from '../../../../../../../test-framework/store-test-helper';
-import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper';
-import { ServiceActionHelperService } from '../../../../../data-services/service-action-helper.service';
-import { EndpointCardComponent } from './endpoint-card.component';
-
-describe('EndpointCardComponent', () => {
- let component: EndpointCardComponent;
- let fixture: ComponentFixture;
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [
- createBasicStoreModule(),
- SharedModule,
- RouterTestingModule,
- BaseTestModules,
- ],
- providers: [
- EntityMonitorFactory,
- ServiceActionHelperService
- ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(EndpointCardComponent);
- component = fixture.componentInstance;
- component.row = {
- name: 'test',
- user: {
- admin: false,
- name: '',
- guid: '',
- },
- metricsAvailable: false,
- system_shared_token: false,
- sso_allowed: false,
- };
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts
deleted file mode 100644
index cd4a1714dc..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
-import { ReplaySubject } from 'rxjs';
-
-import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
-import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types';
-import { getFavoriteFromEndpointEntity } from '../../../../../../core/user-favorite-helpers';
-import { getEndpointTypes, getFullEndpointApiUrl } from '../../../../../../features/endpoints/endpoint-helpers';
-import { CardStatus } from '../../../../../shared.types';
-import { CardCell } from '../../../list.types';
-
-
-@Component({
- selector: 'app-endpoint-card',
- templateUrl: './endpoint-card.component.html',
- styleUrls: ['./endpoint-card.component.scss']
-})
-export class EndpointCardComponent extends CardCell implements OnInit, OnChanges {
-
- static columns = 2;
-
- public status$ = new ReplaySubject();
-
- @Input()
- public row: EndpointModel;
- public favorite: UserFavoriteEndpoint;
-
- constructor() {
- super();
- }
-
- ngOnInit() {
- this.favorite = getFavoriteFromEndpointEntity(this.row);
- this.status$.next(this.mapStatus(this.row));
- }
-
- ngOnChanges(changes: SimpleChanges) {
- const row = changes.row.currentValue;
- this.status$.next(this.mapStatus(row));
- }
-
- public getEndpointUrl(row: EndpointModel) {
- return getFullEndpointApiUrl(row);
- }
-
- public getRouterPath(row: EndpointModel) {
- const ext = getEndpointTypes().find(ep => ep.value === row.cnsi_type);
- if (ext && ext.homeLink) {
- return ext.homeLink(row.guid);
- }
- return '';
- }
-
- private mapStatus(endpoint: EndpointModel) {
- const connectionStatus = endpoint ? endpoint.connectionStatus : '';
- switch (connectionStatus) {
- case 'connected':
- return CardStatus.OK;
- case 'disconnected':
- return CardStatus.INCOMPLETE;
- default:
- return CardStatus.TENTATIVE;
- }
- }
-
-}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts
index 71caa96f1b..3289f66c4c 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-endpoints/cf-endpoints-list-config.service.ts
@@ -1,18 +1,14 @@
-
-import { pairwise } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
+import { AppState } from '../../../../../../../store/src/app-state';
+import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types';
import { ITableColumn } from '../../list-table/table.types';
import { IListConfig, ListViewTypes } from '../../list.component.types';
+import { EndpointCardComponent } from '../endpoint/endpoint-card/endpoint-card.component';
import { endpointColumns } from '../endpoint/endpoints-list-config.service';
-import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types';
-import { selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors';
-import { AppState } from '../../../../../../../store/src/app-state';
-import {
- BaseEndpointsDataSource
-} from './base-endpoints-data-source';
-import { EndpointCardComponent } from './cf-endpoint-card/endpoint-card.component';
+import { BaseEndpointsDataSource } from './base-endpoints-data-source';
+
@Injectable()
export class CFEndpointsListConfigService implements IListConfig {
@@ -29,21 +25,6 @@ export class CFEndpointsListConfigService implements IListConfig
enableTextFilter = true;
tableFixedRowHeight = true;
- private handleAction(item, effectKey, handleChange) {
- const disSub = this.store.select(selectUpdateInfo(
- endpointStoreNames.type,
- item.guid,
- effectKey,
- )).pipe(
- pairwise())
- .subscribe(([oldVal, newVal]) => {
- if (!newVal.error && (oldVal.busy && !newVal.busy)) {
- handleChange([oldVal, newVal]);
- disSub.unsubscribe();
- }
- });
- }
-
constructor(
private store: Store
) {
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/cf-stacks/cf-stacks-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/cf-stacks/cf-stacks-list-config.service.ts
index 0120d6cba0..15acc02ddf 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/cf-stacks/cf-stacks-list-config.service.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/cf-stacks/cf-stacks-list-config.service.ts
@@ -36,7 +36,7 @@ export class CfStacksListConfigService extends BaseCfListConfig {
},
}];
- constructor(private store: Store, private activeRouteCfOrgSpace: ActiveRouteCfOrgSpace) {
+ constructor(private store: Store, activeRouteCfOrgSpace: ActiveRouteCfOrgSpace) {
super();
this.dataSource = new CfStacksDataSource(this.store, activeRouteCfOrgSpace.cfGuid, this);
}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html
new file mode 100644
index 0000000000..fba8e0bb1e
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
{{ row?.name }}
+
{{endpointConfig.label}}
+
+
+
+
+ Status
+
+
+
+
+
+ Address
+ {{ address }}
+
+
+ Details
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss
new file mode 100644
index 0000000000..d9f81e670f
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.scss
@@ -0,0 +1,31 @@
+.endpoint-card {
+ cursor: pointer;
+ &.no-link {
+ cursor: default;
+ }
+ &:focus {
+ outline: 0;
+ }
+
+ &__image {
+ height: 48px;
+ margin-right: 10px;
+
+ &--img {
+ height: 100%;
+ width: auto;
+ }
+ }
+
+ &__title {
+ display: flex;
+ &__text {
+ display: flex;
+ flex-direction: column;
+ &--subtext {
+ font-size: 13px;
+ opacity: .6;
+ }
+ }
+ }
+}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts
new file mode 100644
index 0000000000..4fd4b60e59
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.spec.ts
@@ -0,0 +1,33 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper';
+import { EndpointListHelper } from '../endpoint-list.helpers';
+import { EndpointCardComponent } from './endpoint-card.component';
+
+describe('EndpointCardComponent', () => {
+ let component: EndpointCardComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [],
+ imports: [...BaseTestModules],
+ providers: [EndpointListHelper]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EndpointCardComponent);
+ component = fixture.componentInstance;
+ component.row = {
+ cnsi_type: 'metrics',
+ } as EndpointModel;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts
new file mode 100644
index 0000000000..44961170ae
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component.ts
@@ -0,0 +1,125 @@
+import {
+ Component,
+ ComponentFactoryResolver,
+ ComponentRef,
+ Input,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewContainerRef,
+} from '@angular/core';
+import { ReplaySubject } from 'rxjs';
+
+import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { UserFavoriteEndpoint } from '../../../../../../../../store/src/types/user-favorites.types';
+import { EndpointsService } from '../../../../../../core/endpoints.service';
+import { EndpointTypeConfig } from '../../../../../../core/extension/extension-types';
+import { getFavoriteFromEndpointEntity } from '../../../../../../core/user-favorite-helpers';
+import {
+ coreEndpointListDetailsComponents,
+ getEndpointType,
+ getFullEndpointApiUrl,
+} from '../../../../../../features/endpoints/endpoint-helpers';
+import { MetaCardMenuItem } from '../../../list-cards/meta-card/meta-card-base/meta-card.component';
+import { CardCell } from '../../../list.types';
+import { BaseEndpointsDataSource } from '../../cf-endpoints/base-endpoints-data-source';
+import { EndpointListDetailsComponent, EndpointListHelper } from '../endpoint-list.helpers';
+
+@Component({
+ selector: 'app-endpoint-card',
+ templateUrl: './endpoint-card.component.html',
+ styleUrls: ['./endpoint-card.component.scss'],
+ entryComponents: [...coreEndpointListDetailsComponents]
+})
+export class EndpointCardComponent extends CardCell implements OnInit, OnDestroy {
+
+ public rowObs = new ReplaySubject();
+ public favorite: UserFavoriteEndpoint;
+ public address: string;
+ public cardMenu: MetaCardMenuItem[];
+ public endpointConfig: EndpointTypeConfig;
+ public hasDetails = true;
+ public endpointLink: string = null;
+
+ private componentRef: ComponentRef;
+
+ @Input() component: EndpointListDetailsComponent;
+ private endpointDetails: ViewContainerRef;
+ @ViewChild('endpointDetails', { read: ViewContainerRef }) set content(content: ViewContainerRef) {
+ this.endpointDetails = content;
+ this.updateDetails();
+ }
+
+ private pRow: EndpointModel;
+ @Input('row')
+ set row(row: EndpointModel) {
+ if (!row) {
+ return;
+ }
+ this.pRow = row;
+ this.endpointConfig = getEndpointType(row.cnsi_type);
+ this.address = getFullEndpointApiUrl(row);
+ this.rowObs.next(row);
+ this.endpointLink = row.connectionStatus === 'connected' ? EndpointsService.getLinkForEndpoint(row) : null;
+ this.updateDetails();
+
+ }
+ get row(): EndpointModel {
+ return this.pRow;
+ }
+
+ @Input('dataSource')
+ set dataSource(ds: BaseEndpointsDataSource) {
+ if (ds && ds.endpointType !== 'cf' && !this.cardMenu) {
+ this.cardMenu = this.endpointListHelper.endpointActions().map(endpointAction => ({
+ label: endpointAction.label,
+ action: () => endpointAction.action(this.pRow),
+ can: endpointAction.createVisible(this.rowObs)
+ }));
+ }
+ }
+
+ constructor(
+ private endpointListHelper: EndpointListHelper,
+ private componentFactoryResolver: ComponentFactoryResolver
+ ) {
+ super();
+ }
+
+ ngOnInit() {
+ this.favorite = this.pRow.cnsi_type === 'cf' ? getFavoriteFromEndpointEntity(this.row) : null;
+ const e = getEndpointType(this.pRow.cnsi_type);
+ this.hasDetails = !!e.listDetailsComponent;
+ }
+
+ ngOnDestroy(): void {
+ this.endpointListHelper.destroyEndpointDetails({
+ componentRef: this.componentRef,
+ component: this.component,
+ endpointDetails: this.endpointDetails
+ });
+ }
+
+ updateDetails() {
+ if (!this.endpointDetails || !this.pRow) {
+ return;
+ }
+ const e = getEndpointType(this.pRow.cnsi_type);
+ if (!e.listDetailsComponent) {
+ return;
+ }
+
+ if (!this.component) {
+ const res =
+ this.endpointListHelper.createEndpointDetails(e.listDetailsComponent, this.endpointDetails, this.componentFactoryResolver);
+ this.componentRef = res.componentRef;
+ this.component = res.component;
+ }
+
+ if (this.component) {
+ this.component.row = this.pRow;
+ this.component.isTable = false;
+ }
+ }
+
+}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts
new file mode 100644
index 0000000000..a2e5ce482f
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoint-list.helpers.ts
@@ -0,0 +1,172 @@
+import { ComponentFactoryResolver, ComponentRef, Injectable, ViewContainerRef } from '@angular/core';
+import { MatDialog } from '@angular/material';
+import { Store } from '@ngrx/store';
+import { combineLatest, Observable } from 'rxjs';
+import { map, pairwise } from 'rxjs/operators';
+
+import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.actions';
+import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions';
+import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions';
+import { AppState } from '../../../../../../../store/src/app-state';
+import { EndpointsEffect } from '../../../../../../../store/src/effects/endpoint.effects';
+import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors';
+import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types';
+import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config';
+import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service';
+import { LoggerService } from '../../../../../core/logger.service';
+import {
+ ConnectEndpointDialogComponent,
+} from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component';
+import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config';
+import { ConfirmationDialogService } from '../../../confirmation-dialog.service';
+import { IListAction } from '../../list.component.types';
+import { TableCellCustom } from '../../list.types';
+
+interface EndpointDetailsContainerRefs {
+ componentRef: ComponentRef;
+ component: EndpointListDetailsComponent;
+ endpointDetails: ViewContainerRef;
+}
+
+export abstract class EndpointListDetailsComponent extends TableCellCustom {
+ isEndpointListDetailsComponent = true;
+ isTable = true;
+}
+
+function isEndpointListDetailsComponent(obj: any): EndpointListDetailsComponent {
+ return obj ? obj.isEndpointListDetailsComponent ? obj as EndpointListDetailsComponent : null : null;
+}
+
+@Injectable()
+export class EndpointListHelper {
+
+ constructor(
+ private store: Store,
+ private dialog: MatDialog,
+ private currentUserPermissionsService: CurrentUserPermissionsService,
+ private confirmDialog: ConfirmationDialogService,
+ private log: LoggerService) {
+
+ }
+
+ endpointActions(): IListAction[] {
+ return [
+ {
+ action: (item) => {
+ const confirmation = new ConfirmationDialogConfig(
+ 'Disconnect Endpoint',
+ `Are you sure you want to disconnect endpoint '${item.name}'?`,
+ 'Disconnect',
+ false
+ );
+ this.confirmDialog.open(confirmation, () => {
+ this.store.dispatch(new DisconnectEndpoint(item.guid, item.cnsi_type));
+ this.handleUpdateAction(item, EndpointsEffect.disconnectingKey, ([oldVal, newVal]) => {
+ this.store.dispatch(new ShowSnackBar(`Disconnected endpoint '${item.name}'`));
+ this.store.dispatch(new GetSystemInfo());
+ });
+ });
+ },
+ label: 'Disconnect',
+ description: ``, // Description depends on console user permission
+ createVisible: (row$: Observable) => combineLatest(
+ this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER),
+ row$
+ ).pipe(
+ map(([isAdmin, row]) => {
+ const isConnected = row.connectionStatus === 'connected';
+ return isConnected && (!row.system_shared_token || row.system_shared_token && isAdmin);
+ })
+ )
+ },
+ {
+ action: (item) => {
+ this.dialog.open(ConnectEndpointDialogComponent, {
+ data: {
+ name: item.name,
+ guid: item.guid,
+ type: item.cnsi_type,
+ ssoAllowed: item.sso_allowed
+ },
+ disableClose: true
+ });
+ },
+ label: 'Connect',
+ description: '',
+ createVisible: (row$: Observable) => row$.pipe(map(row => row.connectionStatus === 'disconnected'))
+ },
+ {
+ action: (item) => {
+ const confirmation = new ConfirmationDialogConfig(
+ 'Unregister Endpoint',
+ `Are you sure you want to unregister endpoint '${item.name}'?`,
+ 'Unregister',
+ true
+ );
+ this.confirmDialog.open(confirmation, () => {
+ this.store.dispatch(new UnregisterEndpoint(item.guid, item.cnsi_type));
+ this.handleDeleteAction(item, ([oldVal, newVal]) => {
+ this.store.dispatch(new ShowSnackBar(`Unregistered ${item.name}`));
+ });
+ });
+ },
+ label: 'Unregister',
+ description: 'Remove the endpoint',
+ createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER)
+ }
+ ];
+ }
+
+ private handleUpdateAction(item, effectKey, handleChange) {
+ this.handleAction(selectUpdateInfo(
+ endpointStoreNames.type,
+ item.guid,
+ effectKey,
+ ), handleChange);
+ }
+
+ private handleDeleteAction(item, handleChange) {
+ this.handleAction(selectDeletionInfo(
+ endpointStoreNames.type,
+ item.guid,
+ ), handleChange);
+ }
+
+ private handleAction(storeSelect, handleChange) {
+ const disSub = this.store.select(storeSelect).pipe(
+ pairwise())
+ .subscribe(([oldVal, newVal]) => {
+ // https://github.com/SUSE/stratos/issues/29 Generic way to handle errors ('Failed to disconnect X')
+ if (!newVal.error && (oldVal.busy && !newVal.busy)) {
+ handleChange([oldVal, newVal]);
+ disSub.unsubscribe();
+ }
+ });
+ }
+
+ createEndpointDetails(listDetailsComponent: any, container: ViewContainerRef, componentFactoryResolver: ComponentFactoryResolver):
+ EndpointDetailsContainerRefs {
+ const componentFactory = componentFactoryResolver.resolveComponentFactory(listDetailsComponent);
+ const componentRef = container.createComponent(componentFactory);
+ const component = isEndpointListDetailsComponent(componentRef.instance);
+ const refs = {
+ componentRef,
+ component,
+ endpointDetails: container
+ };
+ if (!component) {
+ this.log.warn(`Attempted to create a non-endpoint list details component "${listDetailsComponent}"`);
+ this.destroyEndpointDetails(refs);
+ }
+ return refs;
+ }
+
+ destroyEndpointDetails(refs: EndpointDetailsContainerRefs) {
+ if (refs.componentRef) {
+ refs.componentRef.destroy();
+ }
+ if (refs.endpointDetails) {
+ refs.endpointDetails.clear();
+ }
+ }
+}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts
index 6c3f9e6e02..9187046806 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.spec.ts
@@ -1,22 +1,22 @@
-import { createBasicStoreModule } from '../../../../../../test-framework/store-test-helper';
-import { StoreModule } from '@ngrx/store';
import { CommonModule } from '@angular/common';
+import { inject, TestBed } from '@angular/core/testing';
+
+import { createBasicStoreModule } from '../../../../../../test-framework/store-test-helper';
import { CoreModule } from '../../../../../core/core.module';
import { SharedModule } from '../../../../shared.module';
-import { TestBed, inject } from '@angular/core/testing';
-
+import { EndpointListHelper } from './endpoint-list.helpers';
import { EndpointsListConfigService } from './endpoints-list-config.service';
describe('EndpointsListConfigService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- providers: [EndpointsListConfigService],
+ providers: [EndpointsListConfigService, EndpointListHelper],
imports: [
CommonModule,
CoreModule,
SharedModule,
createBasicStoreModule()
- ]
+ ],
});
});
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts
index d78dfb64a7..7b8b81b9ef 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/endpoints-list-config.service.ts
@@ -1,37 +1,21 @@
import { Injectable } from '@angular/core';
-import { MatDialog } from '@angular/material';
import { Store } from '@ngrx/store';
-import { combineLatest, Observable } from 'rxjs';
-import { map, pairwise } from 'rxjs/operators';
-import { DisconnectEndpoint, UnregisterEndpoint } from '../../../../../../../store/src/actions/endpoint.actions';
-import { ShowSnackBar } from '../../../../../../../store/src/actions/snackBar.actions';
-import { GetSystemInfo } from '../../../../../../../store/src/actions/system.actions';
+import { ListView } from '../../../../../../../store/src/actions/list.actions';
import { AppState } from '../../../../../../../store/src/app-state';
-import { EndpointsEffect } from '../../../../../../../store/src/effects/endpoint.effects';
-import { selectDeletionInfo, selectUpdateInfo } from '../../../../../../../store/src/selectors/api.selectors';
-import { EndpointModel, endpointStoreNames } from '../../../../../../../store/src/types/endpoint.types';
+import { EndpointModel } from '../../../../../../../store/src/types/endpoint.types';
import { UserFavoriteEndpoint } from '../../../../../../../store/src/types/user-favorites.types';
-import { CurrentUserPermissions } from '../../../../../core/current-user-permissions.config';
-import { CurrentUserPermissionsService } from '../../../../../core/current-user-permissions.service';
-import {
- ConnectEndpointDialogComponent,
-} from '../../../../../features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component';
-import {
- getEndpointUsername,
- getFullEndpointApiUrl,
- getNameForEndpointType,
-} from '../../../../../features/endpoints/endpoint-helpers';
+import { getFullEndpointApiUrl, getNameForEndpointType } from '../../../../../features/endpoints/endpoint-helpers';
import { EntityMonitorFactory } from '../../../../monitors/entity-monitor.factory.service';
import { InternalEventMonitorFactory } from '../../../../monitors/internal-event-monitor.factory';
import { PaginationMonitorFactory } from '../../../../monitors/pagination-monitor.factory';
-import { ConfirmationDialogConfig } from '../../../confirmation-dialog.config';
-import { ConfirmationDialogService } from '../../../confirmation-dialog.service';
import { createTableColumnFavorite } from '../../list-table/table-cell-favorite/table-cell-favorite.component';
import { ITableColumn } from '../../list-table/table.types';
import { IListAction, IListConfig, ListViewTypes } from '../../list.component.types';
+import { EndpointCardComponent } from './endpoint-card/endpoint-card.component';
+import { EndpointListHelper } from './endpoint-list.helpers';
import { EndpointsDataSource } from './endpoints-data-source';
-import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component';
+import { TableCellEndpointDetailsComponent } from './table-cell-endpoint-details/table-cell-endpoint-details.component';
import { TableCellEndpointNameComponent } from './table-cell-endpoint-name/table-cell-endpoint-name.component';
import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status/table-cell-endpoint-status.component';
@@ -75,30 +59,6 @@ export const endpointColumns: ITableColumn[] = [
},
cellFlex: '2'
},
- {
- columnId: 'username',
- headerCell: () => 'Username',
- cellDefinition: {
- getValue: getEndpointUsername
- },
- sort: {
- type: 'sort',
- orderKey: 'username',
- field: 'user.name'
- },
- cellFlex: '2'
- },
- {
- columnId: 'user-type',
- headerCell: () => 'Admin',
- cellComponent: TableCellEndpointIsAdminComponent,
- sort: {
- type: 'sort',
- orderKey: 'user-type',
- field: 'user.admin'
- },
- cellFlex: '2'
- },
{
columnId: 'address',
headerCell: () => 'Address',
@@ -112,81 +72,19 @@ export const endpointColumns: ITableColumn[] = [
},
cellFlex: '5'
},
+ {
+ columnId: 'details',
+ headerCell: () => 'Details',
+ cellComponent: TableCellEndpointDetailsComponent,
+ cellFlex: '4'
+ }
];
@Injectable()
export class EndpointsListConfigService implements IListConfig {
- private listActionDelete: IListAction = {
- action: (item) => {
- const confirmation = new ConfirmationDialogConfig(
- 'Unregister Endpoint',
- `Are you sure you want to unregister endpoint '${item.name}'?`,
- 'Unregister',
- true
- );
- this.confirmDialog.open(confirmation, () => {
- this.store.dispatch(new UnregisterEndpoint(item.guid, item.cnsi_type));
- this.handleDeleteAction(item, ([oldVal, newVal]) => {
- this.store.dispatch(new ShowSnackBar(`Unregistered ${item.name}`));
- });
- });
- },
- label: 'Unregister',
- description: 'Remove the endpoint',
- createVisible: () => this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER)
- };
-
- private listActionDisconnect: IListAction = {
- action: (item) => {
- const confirmation = new ConfirmationDialogConfig(
- 'Disconnect Endpoint',
- `Are you sure you want to disconnect endpoint '${item.name}'?`,
- 'Disconnect',
- false
- );
- this.confirmDialog.open(confirmation, () => {
- this.store.dispatch(new DisconnectEndpoint(item.guid, item.cnsi_type));
- this.handleUpdateAction(item, EndpointsEffect.disconnectingKey, ([oldVal, newVal]) => {
- this.store.dispatch(new ShowSnackBar(`Disconnected endpoint '${item.name}'`));
- this.store.dispatch(new GetSystemInfo());
- });
- });
- },
- label: 'Disconnect',
- description: ``, // Description depends on console user permission
- createVisible: (row$: Observable) => combineLatest(
- this.currentUserPermissionsService.can(CurrentUserPermissions.ENDPOINT_REGISTER),
- row$
- ).pipe(
- map(([isAdmin, row]) => {
- const isConnected = row.connectionStatus === 'connected';
- return isConnected && (!row.system_shared_token || row.system_shared_token && isAdmin);
- })
- )
- };
+ cardComponent = EndpointCardComponent;
- private listActionConnect: IListAction = {
- action: (item) => {
- this.dialog.open(ConnectEndpointDialogComponent, {
- data: {
- name: item.name,
- guid: item.guid,
- type: item.cnsi_type,
- ssoAllowed: item.sso_allowed
- },
- disableClose: true
- });
- },
- label: 'Connect',
- description: '',
- createVisible: (row$: Observable) => row$.pipe(map(row => row.connectionStatus === 'disconnected'))
- };
-
- private singleActions = [
- this.listActionDisconnect,
- this.listActionConnect,
- this.listActionDelete
- ];
+ private singleActions: IListAction[];
private globalActions = [];
@@ -195,7 +93,8 @@ export class EndpointsListConfigService implements IListConfig {
];
isLocal = true;
dataSource: EndpointsDataSource;
- viewType = ListViewTypes.TABLE_ONLY;
+ viewType = ListViewTypes.BOTH;
+ defaultView = 'cards' as ListView;
text = {
title: '',
filter: 'Filter Endpoints'
@@ -203,42 +102,14 @@ export class EndpointsListConfigService implements IListConfig {
enableTextFilter = true;
tableFixedRowHeight = true;
- private handleUpdateAction(item, effectKey, handleChange) {
- this.handleAction(selectUpdateInfo(
- endpointStoreNames.type,
- item.guid,
- effectKey,
- ), handleChange);
- }
-
- private handleDeleteAction(item, handleChange) {
- this.handleAction(selectDeletionInfo(
- endpointStoreNames.type,
- item.guid,
- ), handleChange);
- }
-
- private handleAction(storeSelect, handleChange) {
- const disSub = this.store.select(storeSelect).pipe(
- pairwise())
- .subscribe(([oldVal, newVal]) => {
- // https://github.com/SUSE/stratos/issues/29 Generic way to handle errors ('Failed to disconnect X')
- if (!newVal.error && (oldVal.busy && !newVal.busy)) {
- handleChange([oldVal, newVal]);
- disSub.unsubscribe();
- }
- });
- }
-
constructor(
private store: Store,
- private dialog: MatDialog,
paginationMonitorFactory: PaginationMonitorFactory,
entityMonitorFactory: EntityMonitorFactory,
internalEventMonitorFactory: InternalEventMonitorFactory,
- private currentUserPermissionsService: CurrentUserPermissionsService,
- private confirmDialog: ConfirmationDialogService
+ endpointListHelper: EndpointListHelper
) {
+ this.singleActions = endpointListHelper.endpointActions();
const favoriteCell = createTableColumnFavorite(
(row: EndpointModel) => new UserFavoriteEndpoint(
row.guid,
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html
new file mode 100644
index 0000000000..6e81826a58
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts
new file mode 100644
index 0000000000..338a1ce656
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.spec.ts
@@ -0,0 +1,29 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BaseTestModules } from '../../../../../../../test-framework/cloud-foundry-endpoint-service.helper';
+import { EndpointListHelper } from '../endpoint-list.helpers';
+import { TableCellEndpointDetailsComponent } from './table-cell-endpoint-details.component';
+
+fdescribe('TableCellEndpointDetailsComponent', () => {
+ let component: TableCellEndpointDetailsComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [],
+ imports: [...BaseTestModules],
+ providers: [EndpointListHelper]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TableCellEndpointDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.ts
new file mode 100644
index 0000000000..2bb2f65cb5
--- /dev/null
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-details/table-cell-endpoint-details.component.ts
@@ -0,0 +1,57 @@
+import { Component, ComponentFactoryResolver, Input, OnDestroy, Type, ViewChild, ViewContainerRef } from '@angular/core';
+
+import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { getEndpointType } from '../../../../../../features/endpoints/endpoint-helpers';
+import { TableCellCustom } from '../../../list.types';
+import { EndpointListDetailsComponent, EndpointListHelper } from '../endpoint-list.helpers';
+
+@Component({
+ selector: 'app-table-cell-endpoint-details',
+ templateUrl: './table-cell-endpoint-details.component.html',
+ styleUrls: ['./table-cell-endpoint-details.component.scss']
+})
+export class TableCellEndpointDetailsComponent extends TableCellCustom implements OnDestroy {
+
+ @Input() component: Type;
+ @ViewChild('target', { read: ViewContainerRef }) target;
+
+ cell: EndpointListDetailsComponent;
+
+ constructor(private componentFactoryResolver: ComponentFactoryResolver, private endpointListHelper: EndpointListHelper) {
+ super();
+ }
+
+ private pRow: EndpointModel;
+ @Input('row')
+ set row(row: EndpointModel) {
+ this.pRow = row;
+
+ const e = getEndpointType(row.cnsi_type);
+ if (!e.listDetailsComponent) {
+ return;
+ }
+ if (!this.cell) {
+ const res =
+ this.endpointListHelper.createEndpointDetails(e.listDetailsComponent, this.target, this.componentFactoryResolver);
+ this.target = res.componentRef;
+ this.cell = res.component;
+ }
+
+ if (this.cell) {
+ this.cell.row = this.pRow;
+ this.cell.isTable = true;
+ }
+ }
+
+ get row(): EndpointModel {
+ return this.pRow;
+ }
+
+ ngOnDestroy(): void {
+ this.endpointListHelper.destroyEndpointDetails({
+ componentRef: this.target,
+ component: this.cell,
+ endpointDetails: this.target
+ });
+ }
+}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html
deleted file mode 100644
index 6de3185e88..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
--
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss
deleted file mode 100644
index 8b13789179..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.scss
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts
deleted file mode 100644
index d9ba633383..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { CoreModule } from '../../../../../../core/core.module';
-import { BooleanIndicatorComponent } from '../../../../boolean-indicator/boolean-indicator.component';
-import { TableCellEndpointIsAdminComponent } from './table-cell-endpoint-is-admin.component';
-import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
-
-
-describe('TableCellEndpointIsAdminComponent', () => {
- let component: TableCellEndpointIsAdminComponent<{}>;
- let fixture: ComponentFixture>;
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [TableCellEndpointIsAdminComponent, BooleanIndicatorComponent],
- imports: [
- CoreModule
- ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(TableCellEndpointIsAdminComponent);
- component = fixture.componentInstance;
- component.row = {} as EndpointModel;
- fixture.detectChanges();
- });
-
- it('should be created', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts
deleted file mode 100644
index 0624a37b3d..0000000000
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-is-admin/table-cell-endpoint-is-admin.component.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Component } from '@angular/core';
-
-import { TableCellCustom } from '../../../list.types';
-
-/* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/
-@Component({
- selector: 'app-table-cell-endpoint-is-admin',
- templateUrl: './table-cell-endpoint-is-admin.component.html',
- styleUrls: ['./table-cell-endpoint-is-admin.component.scss']
-})
-export class TableCellEndpointIsAdminComponent extends TableCellCustom { }
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html
index 7bac8d5932..a4f26dd73a 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.html
@@ -1,5 +1,6 @@
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts
index 0c79d6d652..0526d50a15 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.spec.ts
@@ -1,19 +1,17 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { TableCellEndpointNameComponent } from './table-cell-endpoint-name.component';
-import { CoreModule } from '../../../../../../core/core.module';
import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { CoreModule } from '../../../../../../core/core.module';
+import { TableCellEndpointNameComponent } from './table-cell-endpoint-name.component';
describe('TableCellEndpointNameComponent', () => {
- let component: TableCellEndpointNameComponent<{}>;
- let fixture: ComponentFixture>;
+ let component: TableCellEndpointNameComponent;
+ let fixture: ComponentFixture;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TableCellEndpointNameComponent],
- imports: [
- CoreModule
- ]
+ imports: [CoreModule]
})
.compileComponents();
}));
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts
index f81ab00962..90f64c2ca7 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-name/table-cell-endpoint-name.component.ts
@@ -1,20 +1,26 @@
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
+import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { EndpointsService } from '../../../../../../core/endpoints.service';
import { TableCellCustom } from '../../../list.types';
-import { getEndpointTypes } from '../../../../../../features/endpoints/endpoint-helpers';
@Component({
selector: 'app-table-cell-endpoint-name',
templateUrl: './table-cell-endpoint-name.component.html',
styleUrls: ['./table-cell-endpoint-name.component.scss']
})
-export class TableCellEndpointNameComponent extends TableCellCustom {
+export class TableCellEndpointNameComponent extends TableCellCustom {
- getLinkForEndpoint(row) {
- const ext = getEndpointTypes().find(ep => ep.value === row.cnsi_type);
- if (ext && ext.homeLink) {
- return ext.homeLink(row.guid).join('/');
- }
- return '';
+ private tableRow: EndpointModel;
+ @Input('row')
+ set row(row: EndpointModel) {
+ this.tableRow = row;
+ }
+ get row(): EndpointModel {
+ return this.tableRow;
+ }
+
+ getLinkForEndpoint(row = this.tableRow) {
+ return EndpointsService.getLinkForEndpoint(row);
}
}
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html
index 4229b14f87..c18d5dd67b 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.html
@@ -1,6 +1,6 @@
- cloud_done
- cloud_off
+ cloud_done
+ cloud_off
help_outline
-
+
\ No newline at end of file
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts
index 37b8fe49dc..2bceee6209 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.spec.ts
@@ -1,12 +1,12 @@
-import { CoreModule } from '../../../../../../core/core.module';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status.component';
import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
+import { CoreModule } from '../../../../../../core/core.module';
+import { TableCellEndpointStatusComponent } from './table-cell-endpoint-status.component';
describe('TableCellEndpointStatusComponent', () => {
- let component: TableCellEndpointStatusComponent<{}>;
- let fixture: ComponentFixture>;
+ let component: TableCellEndpointStatusComponent;
+ let fixture: ComponentFixture;
beforeEach(async(() => {
TestBed.configureTestingModule({
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts
index 883dcfdfe1..74fe3d4bb3 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component.ts
@@ -1,5 +1,6 @@
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
+import { EndpointModel } from '../../../../../../../../store/src/types/endpoint.types';
import { TableCellCustom } from '../../../list.types';
/* tslint:disable:no-access-missing-member https://github.com/mgechev/codelyzer/issues/191*/
@@ -8,4 +9,6 @@ import { TableCellCustom } from '../../../list.types';
templateUrl: './table-cell-endpoint-status.component.html',
styleUrls: ['./table-cell-endpoint-status.component.scss']
})
-export class TableCellEndpointStatusComponent extends TableCellCustom { }
+export class TableCellEndpointStatusComponent extends TableCellCustom {
+ @Input() row: EndpointModel;
+}
diff --git a/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts b/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts
index a62b5230b4..939407b770 100644
--- a/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list.component.spec.ts
@@ -15,10 +15,11 @@ import { EntityMonitorFactory } from '../../monitors/entity-monitor.factory.serv
import { PaginationMonitorFactory } from '../../monitors/pagination-monitor.factory';
import { SharedModule } from '../../shared.module';
import { ApplicationStateService } from '../application-state/application-state.service';
-import { EndpointCardComponent } from './list-types/cf-endpoints/cf-endpoint-card/endpoint-card.component';
import { EndpointsListConfigService } from './list-types/endpoint/endpoints-list-config.service';
import { ListComponent } from './list.component';
import { ListConfig, ListViewTypes } from './list.component.types';
+import { EndpointListHelper } from './list-types/endpoint/endpoint-list.helpers';
+import { EndpointCardComponent } from './list-types/endpoint/endpoint-card/endpoint-card.component';
class MockedNgZone {
run = fn => fn();
@@ -58,6 +59,7 @@ describe('ListComponent', () => {
{ provide: ChangeDetectorRef, useValue: { detectChanges: () => { } } },
// Fun fact, NgZone will execute something on import which causes an undefined error
{ provide: MockedNgZone, useValue: new MockedNgZone() },
+ EndpointListHelper
]
});
inject([Store, ChangeDetectorRef, NgZone], (iStore: Store, cd: ChangeDetectorRef, ngZone: MockedNgZone) => {
@@ -119,7 +121,8 @@ describe('ListComponent', () => {
{ provide: ListConfig, useClass: EndpointsListConfigService },
ApplicationStateService,
PaginationMonitorFactory,
- EntityMonitorFactory
+ EntityMonitorFactory,
+ EndpointListHelper
],
imports: [
CoreModule,
diff --git a/src/frontend/packages/core/src/shared/components/list/list.types.ts b/src/frontend/packages/core/src/shared/components/list/list.types.ts
index 46d07a59d7..84d009cf44 100644
--- a/src/frontend/packages/core/src/shared/components/list/list.types.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list.types.ts
@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
-import { IListDataSource, RowState } from './data-sources-controllers/list-data-source-types';
import { Observable } from 'rxjs';
+import { IListDataSource, RowState } from './data-sources-controllers/list-data-source-types';
+
export abstract class TableCellCustom {
dataSource: IListDataSource;
row: T;
diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html
index 5a163c6313..bb37b10447 100644
--- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html
+++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html
@@ -9,8 +9,7 @@
-