Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(topology-resourcemenu): add resource menu actions
- Loading branch information
karthik
committed
Jan 16, 2020
1 parent
57bede6
commit d5b93a6
Showing
12 changed files
with
317 additions
and
13 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
frontend/packages/dev-console/src/actions/add-resources.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import * as React from 'react'; | ||
import { | ||
GitAltIcon, | ||
OsImageIcon, | ||
CatalogIcon, | ||
CubeIcon, | ||
DatabaseIcon, | ||
} from '@patternfly/react-icons'; | ||
import { ImportOptions } from '../components/import/import-types'; | ||
import { KebabAction, createKebabOption } from '../utils/add-resources-menu-utils'; | ||
|
||
export const fromGit = createKebabOption('From Git', <GitAltIcon />, ImportOptions.GIT); | ||
export const containerImage = createKebabOption( | ||
'Container Image', | ||
<OsImageIcon />, | ||
ImportOptions.CONTAINER, | ||
); | ||
export const fromCatalog = createKebabOption( | ||
'From Catalog', | ||
<CatalogIcon />, | ||
ImportOptions.CATALOG, | ||
); | ||
export const fromDockerfile = createKebabOption( | ||
'From Dockerfile', | ||
<CubeIcon />, | ||
ImportOptions.DOCKERFILE, | ||
); | ||
export const database = createKebabOption('Database', <DatabaseIcon />, ImportOptions.DATABASE); | ||
|
||
export const addResourceMenu: KebabAction[] = [ | ||
fromGit, | ||
containerImage, | ||
fromCatalog, | ||
fromDockerfile, | ||
database, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
frontend/packages/dev-console/src/components/topology/actions/graphActions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as _ from 'lodash'; | ||
import { KebabOption } from '@console/internal/components/utils/kebab'; | ||
import { GraphElement, Node } from '@console/topology'; | ||
import { TYPE_WORKLOAD } from '../const'; | ||
import { addResourceMenu } from '../../../actions/add-resources'; | ||
import { TopologyDataObject } from '../topology-types'; | ||
|
||
const addResourcesMenu = (workload: TopologyDataObject) => { | ||
let menuItems = []; | ||
if (_.isEmpty(workload)) { | ||
return menuItems; | ||
} | ||
const primaryResource = _.get(workload, ['resources', 'obj'], null); | ||
if (primaryResource) { | ||
menuItems = addResourceMenu.map((menuItem) => menuItem(primaryResource, false)); | ||
} | ||
return menuItems; | ||
}; | ||
|
||
export const graphActions = (elements: GraphElement[]): KebabOption[] => { | ||
const primaryResource: Node = _.find(elements, { | ||
type: TYPE_WORKLOAD, | ||
}) as Node; | ||
return [...addResourcesMenu(primaryResource.getData())]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
frontend/packages/dev-console/src/components/topology/components/GraphComponent.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
frontend/packages/dev-console/src/utils/__tests__/add-resources-menu-utils.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { URL } from 'url'; | ||
import { getMenuPath, getAddPageUrl } from '../add-resources-menu-utils'; | ||
import { | ||
fromGit, | ||
fromCatalog, | ||
containerImage, | ||
fromDockerfile, | ||
database, | ||
addResourceMenu, | ||
} from '../../actions/add-resources'; | ||
import { | ||
transformTopologyData, | ||
getTopologyResourceObject, | ||
} from '../../components/topology/topology-utils'; | ||
import { ImportOptions } from '../../components/import/import-types'; | ||
import { MockResources } from '../../components/topology/__tests__/topology-test-data'; | ||
import { TopologyDataResources } from '../../components/topology/topology-types'; | ||
|
||
const getTopologyData = (mockData: TopologyDataResources, transformByProp: string[]) => { | ||
const result = transformTopologyData(mockData, transformByProp); | ||
const keys = Object.keys(result.topology); | ||
const resource = getTopologyResourceObject(result.topology[keys[0]]); | ||
return { resource }; | ||
}; | ||
|
||
describe('addResourceMenuUtils: ', () => { | ||
it('should give proper menu item path based on the application', () => { | ||
let menuTitle = ''; | ||
menuTitle = getMenuPath(true); | ||
expect(menuTitle).toEqual('Add to Application'); | ||
|
||
menuTitle = getMenuPath(false); | ||
expect(menuTitle).toEqual('Add to Project'); | ||
}); | ||
|
||
it('should return the list of menu items for add resources', () => { | ||
expect(addResourceMenu).toEqual([ | ||
fromGit, | ||
containerImage, | ||
fromCatalog, | ||
fromDockerfile, | ||
database, | ||
]); | ||
}); | ||
|
||
it('should return the page url with proper queryparams for git import flow', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL(getAddPageUrl(resource, ImportOptions.GIT, true), 'https://mock.test.com'); | ||
// Check that url contains all expected params | ||
expect(url.pathname).toBe('/import/ns/testproject1'); | ||
expect(url.searchParams.get('importType')).toBe('git'); | ||
expect(url.searchParams.get('application')).toBe('application-1'); | ||
expect(url.searchParams.get('isKnativeDisabled')).toBe('true'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('preselected-ns')).toBe(false); | ||
expect(url.searchParams.has('catagory')).toBe(false); | ||
}); | ||
|
||
it('should return the page url without application params in the url', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL(getAddPageUrl(resource, ImportOptions.GIT, false), 'https://mock.test.com'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('application')).toBe(false); | ||
expect(url.searchParams.has('preselected-ns')).toBe(false); | ||
expect(url.searchParams.has('catagory')).toBe(false); | ||
}); | ||
|
||
it('should return the page url with proper queryparams for container image flow', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL( | ||
getAddPageUrl(resource, ImportOptions.CONTAINER, true), | ||
'https://mock.test.com', | ||
); | ||
// Check that url contains all expected params | ||
expect(url.pathname).toBe('/deploy-image/ns/testproject1'); | ||
expect(url.searchParams.get('preselected-ns')).toBe('testproject1'); | ||
expect(url.searchParams.get('application')).toBe('application-1'); | ||
expect(url.searchParams.get('isKnativeDisabled')).toBe('true'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('importType')).toBe(false); | ||
expect(url.searchParams.has('catagory')).toBe(false); | ||
}); | ||
|
||
it('should return the page url with proper queryparams for catalog flow', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL( | ||
getAddPageUrl(resource, ImportOptions.CATALOG, true), | ||
'https://mock.test.com', | ||
); | ||
// Check that url contains all expected params | ||
expect(url.pathname).toBe('/catalog'); | ||
expect(url.searchParams.get('application')).toBe('application-1'); | ||
expect(url.searchParams.get('isKnativeDisabled')).toBe('true'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('importType')).toBe(false); | ||
expect(url.searchParams.has('preselected-ns')).toBe(false); | ||
expect(url.searchParams.has('catagory')).toBe(false); | ||
}); | ||
|
||
it('should return the page url with proper queryparams for dockerfile flow', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL( | ||
getAddPageUrl(resource, ImportOptions.DOCKERFILE, true), | ||
'https://mock.test.com', | ||
); | ||
// Check that url contains all expected params | ||
expect(url.pathname).toBe('/import/ns/testproject1'); | ||
expect(url.searchParams.get('importType')).toBe('docker'); | ||
expect(url.searchParams.get('application')).toBe('application-1'); | ||
expect(url.searchParams.get('isKnativeDisabled')).toBe('true'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('preselected-ns')).toBe(false); | ||
expect(url.searchParams.has('catagory')).toBe(false); | ||
}); | ||
|
||
it('should return the page url with proper queryparams for database flow', () => { | ||
const { resource } = getTopologyData(MockResources, ['deployments']); | ||
const url = new URL( | ||
getAddPageUrl(resource, ImportOptions.DATABASE, true), | ||
'https://mock.test.com', | ||
); | ||
// Check that url contains all expected params | ||
expect(url.pathname).toBe('/catalog/ns/testproject1'); | ||
expect(url.searchParams.get('category')).toBe('databases'); | ||
expect(url.searchParams.get('application')).toBe('application-1'); | ||
expect(url.searchParams.get('isKnativeDisabled')).toBe('true'); | ||
// Negative checks for queryparams params. | ||
expect(url.searchParams.has('preselected-ns')).toBe(false); | ||
expect(url.searchParams.has('importType')).toBe(false); | ||
}); | ||
}); |
74 changes: 74 additions & 0 deletions
74
frontend/packages/dev-console/src/utils/add-resources-menu-utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import * as _ from 'lodash'; | ||
import { K8sResourceKind, modelFor, referenceFor } from '@console/internal/module/k8s'; | ||
import { KebabOption, asAccessReview } from '@console/internal/components/utils'; | ||
import { ImportOptions } from '../components/import/import-types'; | ||
|
||
const PART_OF = 'app.kubernetes.io/part-of'; | ||
|
||
export const getAddPageUrl = ( | ||
obj: K8sResourceKind, | ||
type: string, | ||
hasApplication: boolean, | ||
): string => { | ||
let pageUrl = ''; | ||
const params = new URLSearchParams(); | ||
const { | ||
metadata: { namespace: ns }, | ||
} = obj; | ||
switch (type) { | ||
case ImportOptions.GIT: | ||
pageUrl = `/import/ns/${ns}`; | ||
params.append('importType', 'git'); | ||
break; | ||
case ImportOptions.CONTAINER: | ||
pageUrl = `/deploy-image/ns/${ns}`; | ||
params.append('preselected-ns', ns); | ||
break; | ||
case ImportOptions.CATALOG: | ||
pageUrl = '/catalog'; | ||
break; | ||
case ImportOptions.DOCKERFILE: | ||
pageUrl = `/import/ns/${ns}`; | ||
params.append('importType', 'docker'); | ||
break; | ||
case ImportOptions.DATABASE: | ||
pageUrl = `/catalog/ns/${ns}`; | ||
params.append('category', 'databases'); | ||
break; | ||
default: | ||
pageUrl = `add/ns/${ns}`; | ||
} | ||
params.append('isKnativeDisabled', 'true'); | ||
const appGroup = _.get(obj, ['metadata', 'labels', PART_OF], ''); | ||
|
||
if (!hasApplication || !appGroup) { | ||
return `${pageUrl}?${params.toString()}`; | ||
} | ||
params.append('application', encodeURIComponent(appGroup)); | ||
return `${pageUrl}?${params.toString()}`; | ||
}; | ||
|
||
export const getMenuPath = (hasApplication: boolean): string => | ||
hasApplication ? 'Add to Application' : 'Add to Project'; | ||
|
||
type KebabFactory = ( | ||
label: string, | ||
icon: React.ReactNode, | ||
importType: ImportOptions, | ||
) => KebabAction; | ||
|
||
export type KebabAction = (obj?: K8sResourceKind, hasApplication?: boolean) => KebabOption; | ||
|
||
export const createKebabOption: KebabFactory = (label, icon, importType) => ( | ||
obj: K8sResourceKind, | ||
hasApplication: boolean, | ||
) => { | ||
const resourceModel = modelFor(referenceFor(obj)); | ||
return { | ||
label, | ||
icon, | ||
path: getMenuPath(hasApplication), | ||
href: getAddPageUrl(obj, importType, hasApplication), | ||
accessReview: asAccessReview(resourceModel, obj, 'create'), | ||
}; | ||
}; |
Oops, something went wrong.