From e49ffaf4d5896294cf66300167aefdecbf36499c Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 25 Oct 2019 12:14:22 -0400 Subject: [PATCH] Revert "feat(provider/aws): Functions (listing and searching) (#7536)" (#7567) This reverts commit 86a365bd406125498c1bbc45de2ee4d67f9fd0d5. --- app/scripts/modules/amazon/src/aws.module.ts | 7 +- .../amazon/src/domain/IAmazonFunction.ts | 29 --- .../modules/amazon/src/domain/index.ts | 1 - .../amazon/src/function/function.module.ts | 5 - .../src/function/function.transformer.ts | 7 - .../modules/amazon/src/function/index.ts | 1 - app/scripts/modules/amazon/src/index.ts | 1 - app/scripts/modules/core/src/core.module.ts | 4 +- .../modules/core/src/domain/IFunction.ts | 27 -- app/scripts/modules/core/src/domain/index.ts | 2 +- .../core/src/entityTag/EntityTagsReader.ts | 25 +- .../modules/core/src/function/Function.tsx | 46 ---- .../core/src/function/FunctionDetails.tsx | 11 - .../core/src/function/FunctionGroupings.tsx | 33 --- .../modules/core/src/function/FunctionPod.tsx | 39 --- .../modules/core/src/function/Functions.tsx | 106 -------- .../function/filter/FunctionFilterModel.ts | 25 -- .../filter/FunctionFilterService.spec.ts | 186 -------------- .../function/filter/FunctionFilterService.ts | 121 --------- .../src/function/filter/FunctionFilters.tsx | 240 ------------------ .../core/src/function/function.dataSource.ts | 43 ---- .../core/src/function/function.module.ts | 8 - .../src/function/function.read.service.ts | 58 ----- .../core/src/function/function.states.ts | 72 ------ .../core/src/function/function.transformer.js | 49 ---- .../core/src/function/functionPod.less | 40 --- .../modules/core/src/function/index.ts | 2 - app/scripts/modules/core/src/index.ts | 2 +- app/scripts/modules/core/src/state/index.ts | 11 - 29 files changed, 6 insertions(+), 1195 deletions(-) delete mode 100644 app/scripts/modules/amazon/src/domain/IAmazonFunction.ts delete mode 100644 app/scripts/modules/amazon/src/function/function.module.ts delete mode 100644 app/scripts/modules/amazon/src/function/function.transformer.ts delete mode 100644 app/scripts/modules/amazon/src/function/index.ts delete mode 100644 app/scripts/modules/core/src/domain/IFunction.ts delete mode 100644 app/scripts/modules/core/src/function/Function.tsx delete mode 100644 app/scripts/modules/core/src/function/FunctionDetails.tsx delete mode 100644 app/scripts/modules/core/src/function/FunctionGroupings.tsx delete mode 100644 app/scripts/modules/core/src/function/FunctionPod.tsx delete mode 100644 app/scripts/modules/core/src/function/Functions.tsx delete mode 100644 app/scripts/modules/core/src/function/filter/FunctionFilterModel.ts delete mode 100644 app/scripts/modules/core/src/function/filter/FunctionFilterService.spec.ts delete mode 100644 app/scripts/modules/core/src/function/filter/FunctionFilterService.ts delete mode 100644 app/scripts/modules/core/src/function/filter/FunctionFilters.tsx delete mode 100644 app/scripts/modules/core/src/function/function.dataSource.ts delete mode 100644 app/scripts/modules/core/src/function/function.module.ts delete mode 100644 app/scripts/modules/core/src/function/function.read.service.ts delete mode 100644 app/scripts/modules/core/src/function/function.states.ts delete mode 100644 app/scripts/modules/core/src/function/function.transformer.js delete mode 100644 app/scripts/modules/core/src/function/functionPod.less delete mode 100644 app/scripts/modules/core/src/function/index.ts diff --git a/app/scripts/modules/amazon/src/aws.module.ts b/app/scripts/modules/amazon/src/aws.module.ts index 682a33036e3..1887783f3d9 100644 --- a/app/scripts/modules/amazon/src/aws.module.ts +++ b/app/scripts/modules/amazon/src/aws.module.ts @@ -3,7 +3,6 @@ import { module } from 'angular'; import { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core'; import { AWS_LOAD_BALANCER_MODULE } from './loadBalancer/loadBalancer.module'; -import { AWS_FUNCTION_MODULE } from './function/function.module'; import { AWS_REACT_MODULE } from './reactShims/aws.react.module'; import { AWS_SECURITY_GROUP_MODULE } from './securityGroup/securityGroup.module'; import { AWS_SERVER_GROUP_TRANSFORMER } from './serverGroup/serverGroup.transformer'; @@ -18,7 +17,7 @@ import { AwsImageReader } from './image'; import { AmazonLoadBalancerClusterContainer } from './loadBalancer/AmazonLoadBalancerClusterContainer'; import { AmazonLoadBalancersTag } from './loadBalancer/AmazonLoadBalancersTag'; import { AwsLoadBalancerTransformer } from './loadBalancer/loadBalancer.transformer'; -import { AwsFunctionTransformer } from './function/function.transformer'; + import './deploymentStrategy/rollingPush.strategy'; import './logo/aws.logo.less'; @@ -74,7 +73,6 @@ module(AMAZON_MODULE, [ AWS_SERVER_GROUP_TRANSFORMER, require('./instance/awsInstanceType.service').name, AWS_LOAD_BALANCER_MODULE, - AWS_FUNCTION_MODULE, require('./instance/details/instance.details.controller').name, AWS_SECURITY_GROUP_MODULE, SUBNET_RENDERER, @@ -129,9 +127,6 @@ module(AMAZON_MODULE, [ ClusterContainer: AmazonLoadBalancerClusterContainer, LoadBalancersTag: AmazonLoadBalancersTag, }, - function: { - transformer: AwsFunctionTransformer, - }, securityGroup: { transformer: 'awsSecurityGroupTransformer', reader: 'awsSecurityGroupReader', diff --git a/app/scripts/modules/amazon/src/domain/IAmazonFunction.ts b/app/scripts/modules/amazon/src/domain/IAmazonFunction.ts deleted file mode 100644 index 40a37c5532f..00000000000 --- a/app/scripts/modules/amazon/src/domain/IAmazonFunction.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { IFunction } from '@spinnaker/core'; - -export interface IAmazonFunction extends IFunction { - credentials?: string; - role?: string; - runtime: string; - s3bucket: string; - s3key: string; - handler: string; - functionName: string; - publish: boolean; - description: string; - tags: [{}]; - memorySize: number; - timeout: number; - envVariables: {}; - tracingConfig: { - mode: string; - }; - deadLetterConfig: { - targetArn: string; - }; - KMSKeyArn: string; - vpcConfig: { - securityGroupIds: []; - subnetIds: []; - vpcId: string; - }; -} diff --git a/app/scripts/modules/amazon/src/domain/index.ts b/app/scripts/modules/amazon/src/domain/index.ts index 12849b007df..6faadf7ed7b 100644 --- a/app/scripts/modules/amazon/src/domain/index.ts +++ b/app/scripts/modules/amazon/src/domain/index.ts @@ -1,7 +1,6 @@ export * from './IAmazonCertificate'; export * from './IAmazonInstance'; export * from './IAmazonLoadBalancer'; -export * from './IAmazonFunction'; export * from './IAmazonLoadBalancerSourceData'; export * from './IAmazonHealth'; export * from './IAmazonScalingPolicy'; diff --git a/app/scripts/modules/amazon/src/function/function.module.ts b/app/scripts/modules/amazon/src/function/function.module.ts deleted file mode 100644 index 4c99e4b99d2..00000000000 --- a/app/scripts/modules/amazon/src/function/function.module.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { module } from 'angular'; - -export const AWS_FUNCTION_MODULE = 'spinnaker.amazon.function'; - -module(AWS_FUNCTION_MODULE, []); diff --git a/app/scripts/modules/amazon/src/function/function.transformer.ts b/app/scripts/modules/amazon/src/function/function.transformer.ts deleted file mode 100644 index f578374159b..00000000000 --- a/app/scripts/modules/amazon/src/function/function.transformer.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IAmazonFunction } from 'amazon/domain'; - -export class AwsFunctionTransformer { - public normalizeFunction(functionDef: IAmazonFunction): IAmazonFunction { - return functionDef; - } -} diff --git a/app/scripts/modules/amazon/src/function/index.ts b/app/scripts/modules/amazon/src/function/index.ts deleted file mode 100644 index 77369a8c3fb..00000000000 --- a/app/scripts/modules/amazon/src/function/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './function.transformer'; diff --git a/app/scripts/modules/amazon/src/index.ts b/app/scripts/modules/amazon/src/index.ts index f6c26e1099f..69b06d73dd2 100644 --- a/app/scripts/modules/amazon/src/index.ts +++ b/app/scripts/modules/amazon/src/index.ts @@ -6,7 +6,6 @@ export * from './common'; export * from './domain'; export * from './keyPairs'; export * from './loadBalancer'; -export * from './function'; export * from './reactShims'; export * from './serverGroup'; export * from './templates'; diff --git a/app/scripts/modules/core/src/core.module.ts b/app/scripts/modules/core/src/core.module.ts index 4d69cef48b6..5a69c135ccf 100644 --- a/app/scripts/modules/core/src/core.module.ts +++ b/app/scripts/modules/core/src/core.module.ts @@ -46,7 +46,7 @@ import { INSIGHT_MODULE } from './insight/insight.module'; import { INTERCEPTOR_MODULE } from './interceptor/interceptor.module'; import { LOAD_BALANCER_MODULE } from './loadBalancer/loadBalancer.module'; import { MANAGED_RESOURCE_CONFIG } from './application/config/managedResources/ManagedResourceConfig'; -import { FUNCTION_MODULE } from './function/function.module'; + import { NETWORK_INTERCEPTOR } from './api/network.interceptor'; import { PAGE_TITLE_MODULE } from './pageTitle/pageTitle.module'; @@ -114,7 +114,7 @@ module(CORE_MODULE, [ LABEL_FILTER_COMPONENT, LOAD_BALANCER_MODULE, - FUNCTION_MODULE, + MANAGED_RESOURCE_CONFIG, require('./modal/modal.module').name, diff --git a/app/scripts/modules/core/src/domain/IFunction.ts b/app/scripts/modules/core/src/domain/IFunction.ts deleted file mode 100644 index 3b5fdfb6ed4..00000000000 --- a/app/scripts/modules/core/src/domain/IFunction.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ITaggedEntity } from './ITaggedEntity'; - -export interface IFunctionSourceData { - cloudProvider?: string; - name?: string; - provider?: string; - type?: string; -} - -export interface IFunction extends ITaggedEntity { - account?: string; - cloudProvider?: string; - description?: string; - functionName?: string; - region?: string; - searchField?: string; - type?: string; - vpcId?: string; - vpcName?: string; -} - -export interface IFunctionGroup { - heading: string; - functionDef?: IFunction; - subgroups?: IFunctionGroup[]; - searchField?: string; -} diff --git a/app/scripts/modules/core/src/domain/index.ts b/app/scripts/modules/core/src/domain/index.ts index af7649983df..c5f2e34070e 100644 --- a/app/scripts/modules/core/src/domain/index.ts +++ b/app/scripts/modules/core/src/domain/index.ts @@ -19,7 +19,7 @@ export * from './IExecution'; export * from './IExecutionStage'; export * from './IExecutionTrigger'; export * from './IExpectedArtifact'; -export * from './IFunction'; + export * from './IHealth'; export * from './IInstance'; diff --git a/app/scripts/modules/core/src/entityTag/EntityTagsReader.ts b/app/scripts/modules/core/src/entityTag/EntityTagsReader.ts index 2decd822737..771e0c96ed8 100644 --- a/app/scripts/modules/core/src/entityTag/EntityTagsReader.ts +++ b/app/scripts/modules/core/src/entityTag/EntityTagsReader.ts @@ -5,15 +5,7 @@ import { $q } from 'ngimport'; import { API } from 'core/api/ApiService'; import { IEntityTags, IEntityTag, ICreationMetadataTag } from '../domain/IEntityTags'; import { Application } from 'core/application/application.model'; -import { - IExecution, - IPipeline, - IServerGroup, - IServerGroupManager, - ILoadBalancer, - ISecurityGroup, - IFunction, -} from 'core/domain'; +import { IExecution, IPipeline, IServerGroup, IServerGroupManager, ILoadBalancer, ISecurityGroup } from 'core/domain'; import { SETTINGS } from 'core/config/settings'; export class EntityTagsReader { @@ -79,21 +71,6 @@ export class EntityTagsReader { }); } - public static addTagsToFunctions(application: Application): void { - if (!SETTINGS.feature.entityTags) { - return; - } - const allTags = application.getDataSource('entityTags').data; - const functionTags: IEntityTags[] = allTags.filter(t => t.entityRef.entityType === 'function'); - application.getDataSource('functions').data.forEach((fn: IFunction) => { - fn.entityTags = functionTags.find( - t => - t.entityRef.entityId === fn.functionName && - t.entityRef.account === fn.account && - t.entityRef.region === fn.region, - ); - }); - } public static addTagsToSecurityGroups(application: Application): void { if (!SETTINGS.feature.entityTags) { return; diff --git a/app/scripts/modules/core/src/function/Function.tsx b/app/scripts/modules/core/src/function/Function.tsx deleted file mode 100644 index d2afa1380cf..00000000000 --- a/app/scripts/modules/core/src/function/Function.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import { UISref, UISrefActive } from '@uirouter/react'; -import { Application } from 'core/application/application.model'; -import { IFunction } from 'core/domain'; -import { EntityNotifications } from 'core/entityTag/notifications/EntityNotifications'; - -interface IFunctionProps { - application: Application; - functionDef: IFunction; -} - -const Function = (props: IFunctionProps) => { - const { application, functionDef } = props; - const params = { - application: application.name, - region: functionDef.region, - account: functionDef.account, - name: functionDef.functionName, - provider: functionDef.cloudProvider, - }; - return ( -
-
- - -
- -   {(functionDef.region || '').toUpperCase()} -
- application.functions.refresh()} - /> -
-
-
-
-
-
- ); -}; -export default Function; diff --git a/app/scripts/modules/core/src/function/FunctionDetails.tsx b/app/scripts/modules/core/src/function/FunctionDetails.tsx deleted file mode 100644 index a876a3f4722..00000000000 --- a/app/scripts/modules/core/src/function/FunctionDetails.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -import { Overridable, IOverridableProps } from 'core/overrideRegistry'; - -export interface IFunctionDetailsProps extends IOverridableProps {} - -@Overridable('function.details') -export class FunctionDetails extends React.Component { - public render() { - return

Function Details

; - } -} diff --git a/app/scripts/modules/core/src/function/FunctionGroupings.tsx b/app/scripts/modules/core/src/function/FunctionGroupings.tsx deleted file mode 100644 index 15ad08626f2..00000000000 --- a/app/scripts/modules/core/src/function/FunctionGroupings.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; -import { Application } from '@spinnaker/core'; -import { IFunctionGroup } from 'core/domain'; -import { FunctionPod } from './FunctionPod'; - -export interface IFunctionGroupingsProps { - app: Application; - groups: IFunctionGroup[]; -} -export class FunctionGroupings extends React.Component { - constructor(props: IFunctionGroupingsProps) { - super(props); - } - public render() { - return ( -
- {this.props.groups.map(group => ( -
- {group.subgroups && - group.subgroups.map(subgroup => ( - - ))} -
- ))} -
- ); - } -} diff --git a/app/scripts/modules/core/src/function/FunctionPod.tsx b/app/scripts/modules/core/src/function/FunctionPod.tsx deleted file mode 100644 index c9515d20600..00000000000 --- a/app/scripts/modules/core/src/function/FunctionPod.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; - -import { AccountTag } from 'core/account'; -import { Application } from 'core/application/application.model'; -import { IFunctionGroup } from 'core/domain'; -import Function from './Function'; - -import './functionPod.less'; - -export interface IFunctionPodProps { - grouping: IFunctionGroup; - application: Application; - parentHeading: string; -} - -export class FunctionPod extends React.Component { - public render(): React.ReactElement { - const { grouping, application, parentHeading } = this.props; - const subgroups = grouping.subgroups.map(subgroup => ( - - )); - - return ( -
-
-
-
- -
-
-
{grouping.heading}
-
-
-
-
{subgroups}
-
- ); - } -} diff --git a/app/scripts/modules/core/src/function/Functions.tsx b/app/scripts/modules/core/src/function/Functions.tsx deleted file mode 100644 index ea5b12064b9..00000000000 --- a/app/scripts/modules/core/src/function/Functions.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import * as React from 'react'; -import { Debounce } from 'lodash-decorators'; -import { Subscription } from 'rxjs'; -import { Application } from 'core/application/application.model'; -import { FilterTags, IFilterTag } from 'core/filterModel/FilterTags'; -import { IFunctionGroup } from 'core/domain'; -import { FunctionState } from 'core/state'; -import { Spinner } from 'core/widgets/spinners/Spinner'; -import { FunctionGroupings } from './FunctionGroupings'; - -export interface IFunctionsProps { - app: Application; -} - -export interface IFunctionsState { - initialized: boolean; - groups: IFunctionGroup[]; - tags: IFilterTag[]; -} - -export class Functions extends React.Component { - private groupsUpdatedListener: Subscription; - private functionsRefreshUnsubscribe: () => any; - - constructor(props: IFunctionsProps) { - super(props); - this.state = { - initialized: false, - groups: [], - tags: [], - }; - } - - public componentDidMount(): void { - const { app } = this.props; - - this.groupsUpdatedListener = FunctionState.filterService.groupsUpdatedStream.subscribe(() => this.groupsUpdated()); - FunctionState.filterModel.asFilterModel.activate(); - this.functionsRefreshUnsubscribe = app - .getDataSource('functions') - .onRefresh(null, () => this.updateFunctionGroups()); - app.setActiveState(app.loadBalancers); - this.updateFunctionGroups(); - } - - public componentWillUnmount(): void { - this.groupsUpdatedListener.unsubscribe(); - this.functionsRefreshUnsubscribe(); - } - - private groupsUpdated(): void { - this.setState({ - groups: FunctionState.filterModel.asFilterModel.groups, - tags: FunctionState.filterModel.asFilterModel.tags, - }); - } - - @Debounce(200) - private updateFunctionGroups(): void { - FunctionState.filterModel.asFilterModel.applyParamsToUrl(); - FunctionState.filterService.updateFunctionGroups(this.props.app); - this.groupsUpdated(); - - if (this.props.app.getDataSource('functions').loaded) { - this.setState({ initialized: true }); - } - } - - private clearFilters = (): void => { - FunctionState.filterService.clearFilters(); - this.updateFunctionGroups(); - }; - - private tagCleared = (): void => { - this.updateFunctionGroups(); - }; - - public render(): React.ReactElement { - const groupings = this.state.initialized ? ( -
- - {this.state.groups.length === 0 && ( -
-

No functions match the filters you've selected.

-
- )} -
- ) : ( -
- -
- ); - - return ( -
-
-
-
-
- -
-
{groupings}
-
- ); - } -} diff --git a/app/scripts/modules/core/src/function/filter/FunctionFilterModel.ts b/app/scripts/modules/core/src/function/filter/FunctionFilterModel.ts deleted file mode 100644 index d6bc66f8c15..00000000000 --- a/app/scripts/modules/core/src/function/filter/FunctionFilterModel.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IFunctionGroup } from 'core/domain'; -import { IFilterConfig, IFilterModel } from 'core/filterModel/IFilterModel'; -import { FilterModelService } from 'core/filterModel'; - -export const filterModelConfig: IFilterConfig[] = [ - { model: 'account', param: 'acct', type: 'trueKeyObject' }, - { model: 'detail', param: 'detail', type: 'trueKeyObject' }, - { model: 'filter', param: 'q', clearValue: '', type: 'string', filterLabel: 'search' }, - { model: 'providerType', type: 'trueKeyObject', filterLabel: 'provider' }, - { model: 'region', param: 'reg', type: 'trueKeyObject' }, -]; - -export interface IFunctionFilterModel extends IFilterModel { - groups: IFunctionGroup[]; -} - -export class FunctionFilterModel { - public asFilterModel: IFunctionFilterModel; - - constructor() { - this.asFilterModel = FilterModelService.configureFilterModel(this as any, filterModelConfig); - FilterModelService.registerRouterHooks(this.asFilterModel, '**.application.insight.functions.**'); - this.asFilterModel.activate(); - } -} diff --git a/app/scripts/modules/core/src/function/filter/FunctionFilterService.spec.ts b/app/scripts/modules/core/src/function/filter/FunctionFilterService.spec.ts deleted file mode 100644 index 9926e75a3a3..00000000000 --- a/app/scripts/modules/core/src/function/filter/FunctionFilterService.spec.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { Application } from 'core/application/application.model'; -import { ApplicationModelBuilder } from 'core/application/applicationModel.builder'; -import { FunctionState } from 'core/state'; -import { groupBy } from 'lodash'; - -// Most of this logic has been moved to filter.model.service.js, so these act more as integration tests -describe('Service: functionFilterService', function() { - const debounceTimeout = 30; - - let app: Application, resultJson: any; - - beforeEach(() => { - FunctionState.filterModel.asFilterModel.groups = []; - }); - - beforeEach(function() { - app = ApplicationModelBuilder.createApplicationForTests('app', { key: 'functions', lazy: true }); - app.getDataSource('functions').data = [ - { - functionName: 'function1', - region: 'us-east-1', - account: 'test', - }, - { - functionName: 'function2', - region: 'us-west-1', - account: 'prod', - }, - { - functionName: 'function3', - region: 'us-east-1', - account: 'test', - }, - ]; - - resultJson = [ - { heading: 'us-east-1', functionDef: app.functions.data[0] }, - { heading: 'us-west-1', functionDef: app.functions.data[1] }, - { heading: 'us-east-1', functionDef: app.functions.data[2] }, - ]; - FunctionState.filterModel.asFilterModel.clearFilters(); - }); - - describe('Updating the function group', function() { - it('no filter: should be transformed', function(done) { - const expected = [ - { - heading: 'prod', - subgroups: [{ heading: 'function2', subgroups: [resultJson[1]] }], - }, - { - heading: 'test', - subgroups: [ - { heading: 'function1', subgroups: [resultJson[0]] }, - { heading: 'function3', subgroups: [resultJson[2]] }, - ], - }, - ]; - FunctionState.filterService.updateFunctionGroups(app); - setTimeout(() => { - expect(FunctionState.filterModel.asFilterModel.groups).toEqual(expected); - done(); - }, debounceTimeout); - }); - - describe('filtering by account type', function() { - it('1 account filter: should be transformed showing only prod accounts', function(done) { - FunctionState.filterModel.asFilterModel.sortFilter.account = { prod: true }; - FunctionState.filterService.updateFunctionGroups(app); - - setTimeout(() => { - expect(FunctionState.filterModel.asFilterModel.groups).toEqual([ - { - heading: 'prod', - subgroups: [{ heading: 'function2', subgroups: [resultJson[1]] }], - }, - ]); - done(); - }, debounceTimeout); - }); - - it('All account filters: should show all accounts', function(done) { - FunctionState.filterModel.asFilterModel.sortFilter.account = { prod: true, test: true }; - FunctionState.filterService.updateFunctionGroups(app); - - setTimeout(() => { - expect(FunctionState.filterModel.asFilterModel.groups).toEqual([ - { - heading: 'prod', - subgroups: [{ heading: 'function2', subgroups: [resultJson[1]] }], - }, - { - heading: 'test', - subgroups: [ - { heading: 'function1', subgroups: [resultJson[0]] }, - { heading: 'function3', subgroups: [resultJson[2]] }, - ], - }, - ]); - done(); - }, debounceTimeout); - }); - }); - }); - - describe('filter by region', function() { - it('1 region: should filter by that region', function(done) { - FunctionState.filterModel.asFilterModel.sortFilter.region = { 'us-east-1': true }; - FunctionState.filterService.updateFunctionGroups(app); - - setTimeout(() => { - expect(FunctionState.filterModel.asFilterModel.groups).toEqual([ - { - heading: 'test', - subgroups: [ - { heading: 'function1', subgroups: [resultJson[0]] }, - { heading: 'function3', subgroups: [resultJson[2]] }, - ], - }, - ]); - done(); - }, debounceTimeout); - }); - - it('All regions: should show all functions', function(done) { - FunctionState.filterModel.asFilterModel.sortFilter.region = { 'us-east-1': true, 'us-west-1': true }; - FunctionState.filterService.updateFunctionGroups(app); - - setTimeout(() => { - expect(FunctionState.filterModel.asFilterModel.groups).toEqual([ - { - heading: 'prod', - subgroups: [{ heading: 'function2', subgroups: [resultJson[1]] }], - }, - { - heading: 'test', - subgroups: [ - { heading: 'function1', subgroups: [resultJson[0]] }, - { heading: 'function3', subgroups: [resultJson[2]] }, - ], - }, - ]); - done(); - }, debounceTimeout); - }); - }); - - it('Filter by region: filterFunctionsForDisplay', function(done) { - FunctionState.filterModel.asFilterModel.sortFilter.region = { 'us-west-1': true }; - const functionsToDisplay = FunctionState.filterService.filterFunctionsForDisplay(app.functions.data); - setTimeout(() => { - expect(functionsToDisplay).toEqual([resultJson[1].functionDef]); - done(); - }, debounceTimeout); - }); - - describe('function with same name and different regions ', function() { - it('grouped with region in heading', function(done) { - const newFunction = { - functionName: 'function1', - account: 'test', - region: 'eu-west-1', - }; - app.functions.data.push(newFunction); - const groupedByAccount = groupBy(app.functions.data, 'account'); - const groups = FunctionState.filterService.getFunctionGroups(groupedByAccount); - setTimeout(() => { - expect(groups).toEqual([ - { - heading: 'test', - subgroups: [ - { heading: 'function1 (eu-west-1)', subgroups: [{ heading: 'eu-west-1', functionDef: newFunction }] }, - { heading: 'function1 (us-east-1)', subgroups: [resultJson[0]] }, - { heading: 'function3', subgroups: [resultJson[2]] }, - ], - }, - { - heading: 'prod', - subgroups: [{ heading: 'function2', subgroups: [resultJson[1]] }], - }, - ]); - done(); - }, debounceTimeout); - }); - }); -}); diff --git a/app/scripts/modules/core/src/function/filter/FunctionFilterService.ts b/app/scripts/modules/core/src/function/filter/FunctionFilterService.ts deleted file mode 100644 index 28809542481..00000000000 --- a/app/scripts/modules/core/src/function/filter/FunctionFilterService.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { chain, forOwn, groupBy, intersection, sortBy, values, Dictionary } from 'lodash'; -import { Debounce } from 'lodash-decorators'; -import { Subject } from 'rxjs'; - -import { Application } from 'core/application/application.model'; -import { FilterModelService } from 'core/filterModel'; -import { IFunction, IFunctionGroup } from 'core/domain'; -import { FunctionState } from 'core/state'; - -export class FunctionFilterService { - public groupsUpdatedStream: Subject = new Subject(); - - private lastApplication: Application; - - constructor() {} - - private addSearchFields(functionDef: IFunction): void { - if (!functionDef.searchField) { - functionDef.searchField = [functionDef.functionName, functionDef.region.toLowerCase(), functionDef.account].join( - ' ', - ); - } - } - - private checkSearchTextFilter(functionDef: IFunction): boolean { - const filter = FunctionState.filterModel.asFilterModel.sortFilter.filter; - if (!filter) { - return true; - } - - if (filter.includes('vpc:')) { - const [, vpcName] = /vpc:([\w-]*)/.exec(filter); - return functionDef.vpcName.toLowerCase() === vpcName.toLowerCase(); - } - this.addSearchFields(functionDef); - return filter.split(' ').every((testWord: string) => { - return functionDef.searchField.includes(testWord); - }); - } - - public filterFunctionsForDisplay(functions: IFunction[]): IFunction[] { - return chain(functions) - .filter(fn => this.checkSearchTextFilter(fn)) - .filter(fn => FilterModelService.checkAccountFilters(FunctionState.filterModel.asFilterModel)(fn)) - .filter(fn => FilterModelService.checkRegionFilters(FunctionState.filterModel.asFilterModel)(fn)) - .filter(fn => FilterModelService.checkProviderFilters(FunctionState.filterModel.asFilterModel)(fn)) - .value(); - } - - public sortGroupsByHeading(): void { - // sort groups in place so Angular doesn't try to update the world - FunctionState.filterModel.asFilterModel.groups.sort((a, b) => { - return a.heading.localeCompare(b.heading); - }); - } - - public clearFilters(): void { - FunctionState.filterModel.asFilterModel.clearFilters(); - FunctionState.filterModel.asFilterModel.applyParamsToUrl(); - } - - public getFunctionGroups(groupedByAccount: Dictionary): IFunctionGroup[] { - const groups: IFunctionGroup[] = []; - forOwn(groupedByAccount, (group, account) => { - const groupedByRegion = values(groupBy(group, 'region')); - const namesByRegion = groupedByRegion.map(g => g.map(fn => fn.functionName)); - /** gather functions with same name but different region */ - const functionNames = - namesByRegion.length > 1 - ? intersection(...namesByRegion).reduce<{ [key: string]: boolean }>((acc, name) => { - acc[name] = true; - return acc; - }, {}) - : {}; - /* Group by functionName:region */ - const subGroupings = groupBy(group, fn => `${fn.functionName}:${fn.region}`), - subGroups: IFunctionGroup[] = []; - - forOwn(subGroupings, (subGroup, nameAndRegion) => { - const [name, region] = nameAndRegion.split(':'); - const subSubGroups: IFunctionGroup[] = []; - - subGroup.forEach(functionDef => { - subSubGroups.push({ - heading: functionDef.region, - functionDef, - }); - }); - - /* In case function with same name exists in a different region, heading = name(region)*/ - const heading = `${name}${functionNames[name] && region ? ` (${region})` : ''}`; - subGroups.push({ - heading, - subgroups: sortBy(subSubGroups, 'heading'), - }); - }); - groups.push({ heading: account, subgroups: sortBy(subGroups, 'heading') }); - }); - return groups; - } - - @Debounce(25) - public updateFunctionGroups(application: Application): void { - if (!application) { - application = this.lastApplication; - if (!this.lastApplication) { - return null; - } - } - - const functions = this.filterFunctionsForDisplay(application.functions.data); - const grouped = groupBy(functions, 'account'); - const groups = this.getFunctionGroups(grouped); - - FunctionState.filterModel.asFilterModel.groups = groups; - this.sortGroupsByHeading(); - FunctionState.filterModel.asFilterModel.addTags(); - this.lastApplication = application; - this.groupsUpdatedStream.next(groups); - } -} diff --git a/app/scripts/modules/core/src/function/filter/FunctionFilters.tsx b/app/scripts/modules/core/src/function/filter/FunctionFilters.tsx deleted file mode 100644 index c6f64140ba2..00000000000 --- a/app/scripts/modules/core/src/function/filter/FunctionFilters.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import * as React from 'react'; -import { chain, compact, debounce, uniq, map } from 'lodash'; -import { $rootScope } from 'ngimport'; -import { Subscription } from 'rxjs'; - -import { Application } from 'core/application'; -import { CloudProviderLabel, CloudProviderLogo } from 'core/cloudProvider'; -import { FilterCollapse, ISortFilter, digestDependentFilters } from 'core/filterModel'; -import { FilterSection } from 'core/cluster/filter/FilterSection'; -import { FunctionState } from 'core/state'; - -const poolValueCoordinates = [ - { filterField: 'providerType', on: 'function', localField: 'type' }, - { filterField: 'account', on: 'function', localField: 'account' }, - { filterField: 'region', on: 'function', localField: 'region' }, -]; - -function poolBuilder(functions: any[]) { - const pool = chain(functions) - .map(fn => { - const poolUnits = chain(poolValueCoordinates) - .filter({ on: 'function' }) - .reduce( - (acc, coordinate) => { - acc[coordinate.filterField] = fn[coordinate.localField]; - return acc; - }, - {} as any, - ) - .value(); - return poolUnits; - }) - .flatten() - .value(); - return pool; -} - -export interface IFunctionFiltersProps { - app: Application; -} - -export interface IFunctionFiltersState { - sortFilter: ISortFilter; - tags: any[]; - providerTypeHeadings: string[]; - accountHeadings: string[]; - regionHeadings: string[]; -} - -export class FunctionFilters extends React.Component { - private debouncedUpdateFunctionGroups: () => void; - private groupsUpdatedSubscription: Subscription; - private functionsRefreshUnsubscribe: () => void; - private locationChangeUnsubscribe: () => void; - - constructor(props: IFunctionFiltersProps) { - super(props); - this.state = { - sortFilter: FunctionState.filterModel.asFilterModel.sortFilter, - tags: FunctionState.filterModel.asFilterModel.tags, - providerTypeHeadings: [], - accountHeadings: [], - regionHeadings: [], - }; - - this.debouncedUpdateFunctionGroups = debounce(this.updateFunctionGroups, 300); - } - - public componentDidMount(): void { - const { app } = this.props; - - this.groupsUpdatedSubscription = FunctionState.filterService.groupsUpdatedStream.subscribe(() => { - this.setState({ tags: FunctionState.filterModel.asFilterModel.tags }); - }); - - if (app.functions && app.functions.loaded) { - this.updateFunctionGroups(); - } - - this.functionsRefreshUnsubscribe = app.functions.onRefresh(null, () => this.updateFunctionGroups()); - - this.locationChangeUnsubscribe = $rootScope.$on('$locationChangeSuccess', () => { - FunctionState.filterModel.asFilterModel.activate(); - FunctionState.filterService.updateFunctionGroups(app); - }); - } - - public componentWillUnmount(): void { - this.groupsUpdatedSubscription.unsubscribe(); - this.functionsRefreshUnsubscribe(); - this.locationChangeUnsubscribe(); - } - - public updateFunctionGroups = (applyParamsToUrl = true): void => { - const { app } = this.props; - - if (applyParamsToUrl) { - FunctionState.filterModel.asFilterModel.applyParamsToUrl(); - } - FunctionState.filterService.updateFunctionGroups(app); - - const { region, account } = digestDependentFilters({ - sortFilter: FunctionState.filterModel.asFilterModel.sortFilter, - dependencyOrder: ['providerType', 'account', 'region'], - pool: poolBuilder(app.functions.data), - }); - - this.setState({ - accountHeadings: account, - regionHeadings: region, - providerTypeHeadings: this.getHeadingsForOption('type'), - }); - }; - - private getHeadingsForOption = (option: string): string[] => { - return compact(uniq(map(this.props.app.functions.data, option) as string[])).sort(); - }; - - private clearFilters = (): void => { - FunctionState.filterService.clearFilters(); - FunctionState.filterModel.asFilterModel.applyParamsToUrl(); - FunctionState.filterService.updateFunctionGroups(this.props.app); - }; - - private handleSearchBlur = (event: React.ChangeEvent) => { - const target = event.target; - this.state.sortFilter.filter = target.value; - this.updateFunctionGroups(); - }; - - private handleSearchChange = (event: React.ChangeEvent) => { - const target = event.target; - this.state.sortFilter.filter = target.value; - this.setState({ sortFilter: this.state.sortFilter }); - this.debouncedUpdateFunctionGroups(); - }; - - public render() { - const fuctionsLoaded = this.props.app.functions.loaded; - const { accountHeadings, providerTypeHeadings, regionHeadings, sortFilter, tags } = this.state; - - return ( -
- -
- 0 ? 'inherit' : 'hidden' }} - onClick={this.clearFilters} - > - Clear All - - -
-
- -
-
-
-
- {fuctionsLoaded && ( -
- {providerTypeHeadings.length > 1 && ( - - {providerTypeHeadings.map(heading => ( - - ))} - - )} - - - {accountHeadings.map(heading => ( - - ))} - - - - {regionHeadings.map(heading => ( - - ))} - -
- )} -
- ); - } -} - -const FilterCheckbox = (props: { - heading: string; - sortFilterType: { [key: string]: boolean }; - onChange: () => void; - isCloudProvider?: boolean; -}): JSX.Element => { - const { heading, isCloudProvider, onChange, sortFilterType } = props; - const changeHandler = (event: React.ChangeEvent) => { - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; - sortFilterType[heading] = Boolean(value); - onChange(); - }; - return ( -
- -
- ); -}; diff --git a/app/scripts/modules/core/src/function/function.dataSource.ts b/app/scripts/modules/core/src/function/function.dataSource.ts deleted file mode 100644 index 5e1c86683f7..00000000000 --- a/app/scripts/modules/core/src/function/function.dataSource.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { module, IQService } from 'angular'; - -import { ApplicationDataSourceRegistry } from 'core/application/service/ApplicationDataSourceRegistry'; -import { INFRASTRUCTURE_KEY } from 'core/application/nav/defaultCategories'; -import { Application } from 'core/application/application.model'; -import { EntityTagsReader } from 'core/entityTag/EntityTagsReader'; -import { IFunction } from 'core/domain'; -import { FUNCTION_READ_SERVICE, FunctionReader } from 'core/function/function.read.service'; - -export const FUNCTION_DATA_SOURCE = 'spinnaker.core.functions.dataSource'; -module(FUNCTION_DATA_SOURCE, [FUNCTION_READ_SERVICE]).run([ - '$q', - 'functionReader', - ($q: IQService, functionReader: FunctionReader) => { - const functions = (application: Application) => { - return functionReader.loadFunctions(application.name); - }; - - const addFunctions = (_application: Application, functionList: IFunction[]) => { - return $q.when(functionList); - }; - - const addTags = (application: Application) => { - EntityTagsReader.addTagsToFunctions(application); - }; - - ApplicationDataSourceRegistry.registerDataSource({ - key: 'functions', - label: 'functions', - sref: '.insight.functions', - category: INFRASTRUCTURE_KEY, - optional: true, - icon: 'fa fa-xs fa-fw icon-sitemap', - loader: functions, - onLoad: addFunctions, - afterLoad: addTags, - providerField: 'cloudProvider', - credentialsField: 'account', - regionField: 'region', - description: 'Serverless Compute Service.', - }); - }, -]); diff --git a/app/scripts/modules/core/src/function/function.module.ts b/app/scripts/modules/core/src/function/function.module.ts deleted file mode 100644 index f83abb73086..00000000000 --- a/app/scripts/modules/core/src/function/function.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { module } from 'angular'; - -import { FUNCTION_DATA_SOURCE } from './function.dataSource'; -import { FUNCTION_STATES } from './function.states'; - -export const FUNCTION_MODULE = 'spinnaker.core.function'; - -module(FUNCTION_MODULE, [FUNCTION_DATA_SOURCE, FUNCTION_STATES]); diff --git a/app/scripts/modules/core/src/function/function.read.service.ts b/app/scripts/modules/core/src/function/function.read.service.ts deleted file mode 100644 index 0e285d6cd4f..00000000000 --- a/app/scripts/modules/core/src/function/function.read.service.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { IPromise, IQService, module } from 'angular'; - -import { API } from 'core/api/ApiService'; -import { IFunctionSourceData, IFunction } from 'core/domain'; - -export interface IFunctionByAccount { - name: string; - accounts: Array<{ - name: string; - regions: Array<{ - name: string; - functions: IFunctionSourceData[]; - }>; - }>; -} - -export class FunctionReader { - public static $inject = ['$q', 'functionTransformer']; - public constructor(private $q: IQService, private functionTransformer: any) {} - - public loadFunctions(applicationName: string): IPromise { - return API.one('applications', applicationName) - .all('functions') - .getList() - .then((functions: IFunctionSourceData[]) => { - functions = this.functionTransformer.normalizeFunctionSet(functions); - return this.$q.all(functions.map(fn => this.normalizeFunction(fn))); - }); - } - - public getFunctionDetails( - cloudProvider: string, - account: string, - region: string, - name: string, - ): IPromise { - return API.all('functions') - .withParams({ provider: cloudProvider, functionName: name, region: region, account: account }) - .get(); - } - - public listFunctions(cloudProvider: string): IPromise { - return API.all('functions') - .withParams({ provider: cloudProvider }) - .getList(); - } - - private normalizeFunction(functionDef: IFunctionSourceData): IPromise { - return this.functionTransformer.normalizeFunction(functionDef).then((fn: IFunction) => { - fn.cloudProvider = fn.cloudProvider || 'aws'; - return fn; - }); - } -} - -export const FUNCTION_READ_SERVICE = 'spinnaker.core.function.read.service'; - -module(FUNCTION_READ_SERVICE, [require('./function.transformer').name]).service('functionReader', FunctionReader); diff --git a/app/scripts/modules/core/src/function/function.states.ts b/app/scripts/modules/core/src/function/function.states.ts deleted file mode 100644 index ee3124d3543..00000000000 --- a/app/scripts/modules/core/src/function/function.states.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { module } from 'angular'; -import { StateParams } from '@uirouter/angularjs'; - -import { INestedState, StateConfigProvider } from 'core/navigation'; -import { APPLICATION_STATE_PROVIDER, ApplicationStateProvider } from 'core/application'; -import { filterModelConfig } from 'core/function/filter/FunctionFilterModel'; -import { Functions } from 'core/function/Functions'; - -import { FunctionDetails } from './FunctionDetails'; -import { FunctionFilters } from './filter/FunctionFilters'; - -export const FUNCTION_STATES = 'spinnaker.core.functions.states'; -module(FUNCTION_STATES, [APPLICATION_STATE_PROVIDER]).config([ - 'applicationStateProvider', - 'stateConfigProvider', - (applicationStateProvider: ApplicationStateProvider, stateConfigProvider: StateConfigProvider) => { - const functionDetails: INestedState = { - name: 'functionDetails', - url: '/functionDetails/:provider/:account/:region/:name', - views: { - 'detail@../insight': { - component: FunctionDetails, - $type: 'react', - }, - }, - resolve: { - accountId: ['$stateParams', ($stateParams: StateParams) => $stateParams.account], - functionObj: [ - '$stateParams', - ($stateParams: StateParams) => { - return { - name: $stateParams.name, - accountId: $stateParams.account, - region: $stateParams.region, - vpcId: $stateParams.vpcId, - }; - }, - ], - }, - data: { - pageTitleDetails: { - title: 'Function Details', - nameParam: 'functionName', - accountParam: 'credentials', - regionParam: 'region', - }, - history: { - type: 'functions', - }, - }, - }; - - const functions: INestedState = { - url: `/functions?${stateConfigProvider.paramsToQuery(filterModelConfig)}`, - name: 'functions', - views: { - nav: { component: FunctionFilters, $type: 'react' }, - master: { component: Functions, $type: 'react' }, - }, - params: stateConfigProvider.buildDynamicParams(filterModelConfig), - data: { - pageTitleSection: { - title: 'Functions', - }, - }, - children: [], - }; - - applicationStateProvider.addInsightState(functions); - applicationStateProvider.addInsightDetailState(functionDetails); - }, -]); diff --git a/app/scripts/modules/core/src/function/function.transformer.js b/app/scripts/modules/core/src/function/function.transformer.js deleted file mode 100644 index 5af7aa8ef8d..00000000000 --- a/app/scripts/modules/core/src/function/function.transformer.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; - -const angular = require('angular'); - -import { chain, flow } from 'lodash'; - -import { AccountService } from 'core/account/AccountService'; -import { PROVIDER_SERVICE_DELEGATE } from 'core/cloudProvider/providerService.delegate'; - -module.exports = angular - .module('spinnaker.core.function.transformer', [PROVIDER_SERVICE_DELEGATE]) - .factory('functionTransformer', [ - 'providerServiceDelegate', - function(providerServiceDelegate) { - function normalizeFunction(functionDef) { - return AccountService.getAccountDetails(functionDef.account).then(accountDetails => { - return providerServiceDelegate - .getDelegate( - functionDef.provider ? functionDef.provider : 'aws', - 'function.transformer', - accountDetails && accountDetails.skin, - ) - .normalizeFunction(functionDef); - }); - } - - function normalizeFunctionSet(functions) { - let setNormalizers = chain(functions) - .filter(fn => - providerServiceDelegate.hasDelegate(fn.provider ? fn.provider : 'aws', 'function.setTransformer'), - ) - .compact() - .map(fn => providerServiceDelegate.getDelegate(fn.provider, 'function.setTransformer').normalizeFunctionSet) - .uniq() - .value(); - - if (setNormalizers.length) { - return flow(setNormalizers)(functions); - } else { - return functions; - } - } - - return { - normalizeFunction: normalizeFunction, - normalizeFunctionSet: normalizeFunctionSet, - }; - }, - ]); diff --git a/app/scripts/modules/core/src/function/functionPod.less b/app/scripts/modules/core/src/function/functionPod.less deleted file mode 100644 index 7c0b5fbf406..00000000000 --- a/app/scripts/modules/core/src/function/functionPod.less +++ /dev/null @@ -1,40 +0,0 @@ -@import (reference) '~core/presentation/less/imports/commonImports.less'; - -.function-pod { - .cluster-container { - padding: 3px 15px; - &.disabled { - opacity: 0.4; - &:active, - &:hover { - opacity: 0.7; - } - } - } - .icon-sitemap { - color: var(--color-success); - } - .rollup-details { - .pod-subgroup { - h6 { - padding-bottom: 10px; - background: rgba(0, 0, 0, 0); - } - } - } - .function-header { - overflow: hidden; - background-color: var(--color-alabaster); - padding: 8px 20px 3px 20px; - .health-counts { - .instance-health-counts { - margin-top: -2px; - } - } - } - .function { - > .cluster-container { - padding-top: 0; - } - } -} diff --git a/app/scripts/modules/core/src/function/index.ts b/app/scripts/modules/core/src/function/index.ts deleted file mode 100644 index ee0ff5667c8..00000000000 --- a/app/scripts/modules/core/src/function/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './FunctionDetails'; -export * from './function.read.service'; diff --git a/app/scripts/modules/core/src/index.ts b/app/scripts/modules/core/src/index.ts index 11a873758b8..15a37081393 100644 --- a/app/scripts/modules/core/src/index.ts +++ b/app/scripts/modules/core/src/index.ts @@ -41,7 +41,7 @@ export * from './image'; export * from './instance'; export * from './loadBalancer'; -export * from './function'; + export * from './modal'; export * from './managed'; diff --git a/app/scripts/modules/core/src/state/index.ts b/app/scripts/modules/core/src/state/index.ts index e2a9f999429..2cf49e6ce7e 100644 --- a/app/scripts/modules/core/src/state/index.ts +++ b/app/scripts/modules/core/src/state/index.ts @@ -8,8 +8,6 @@ import { LoadBalancerFilterService } from 'core/loadBalancer/filter/LoadBalancer import { MultiselectModel } from 'core/cluster/filter/MultiselectModel'; import { SecurityGroupFilterModel } from 'core/securityGroup/filter/SecurityGroupFilterModel'; import { SecurityGroupFilterService } from 'core/securityGroup/filter/SecurityGroupFilterService'; -import { FunctionFilterModel } from 'core/function/filter/FunctionFilterModel'; -import { FunctionFilterService } from 'core/function/filter/FunctionFilterService'; export interface IStateCluster { filterModel: ClusterFilterModel; @@ -31,16 +29,10 @@ export interface IStateSecurityGroup { filterService: SecurityGroupFilterService; } -export interface IStateFunctions { - filterModel: FunctionFilterModel; - filterService: FunctionFilterService; -} - export const ClusterState = {} as IStateCluster; export const ExecutionState = {} as IStateExecution; export const LoadBalancerState = {} as IStateLoadBalancers; export const SecurityGroupState = {} as IStateSecurityGroup; -export const FunctionState = {} as IStateFunctions; export function initialize(): void { ClusterState.filterModel = new ClusterFilterModel(); @@ -52,9 +44,6 @@ export function initialize(): void { LoadBalancerState.filterModel = new LoadBalancerFilterModel(); LoadBalancerState.filterService = new LoadBalancerFilterService(); - FunctionState.filterModel = new FunctionFilterModel(); - FunctionState.filterService = new FunctionFilterService(); - SecurityGroupState.filterModel = new SecurityGroupFilterModel(); SecurityGroupState.filterService = new SecurityGroupFilterService(); if (SETTINGS.checkForUpdates) {