Skip to content

Commit 658dbb8

Browse files
authored
CORE-527 Support lookup ws by name (#5337)
1 parent 1715d64 commit 658dbb8

File tree

3 files changed

+87
-17
lines changed

3 files changed

+87
-17
lines changed

src/libs/ajax/workspaces/Workspaces.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ export const Workspaces = (signal?: AbortSignal) => ({
9696
return res.json();
9797
},
9898

99+
adminGetId: async (namespace: string, name: string): Promise<string> => {
100+
const res = await fetchRawls(`admin/workspaces/${namespace}/${name}/id`, _.merge(authOpts(), { signal }));
101+
return res.json();
102+
},
103+
99104
workspaceV2: (namespace: string, name: string) => {
100105
const root = `workspaces/v2/${namespace}/${name}`;
101106

src/support/LookupSummaryAndPolicies.tsx

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import _ from 'lodash/fp';
33
import React, { useState } from 'react';
44
import { TextInput } from 'src/components/input';
55
import colors from 'src/libs/colors';
6+
import { reportError } from 'src/libs/error';
67
import * as Nav from 'src/libs/nav';
78
import { ResourcePolicies } from 'src/support/ResourcePolicies';
89
import { ResourceTypeSummaryProps, supportResources } from 'src/support/SupportResourceType';
@@ -11,23 +12,46 @@ import { SupportSummary } from 'src/support/SupportSummary';
1112
export const LookupSummaryAndPolicies = (props: ResourceTypeSummaryProps) => {
1213
const { query } = Nav.useRoute();
1314
const [resourceId, setResourceId] = useState<string>(props.fqResourceId.resourceId);
15+
const [lookupValue, setLookupValue] = useState<string>('');
1416

15-
function submit() {
16-
Nav.updateSearch({ ...query, resourceId: resourceId || undefined });
17+
function submit(overrideResourceId?: string) {
18+
Nav.updateSearch({ ...query, resourceId: overrideResourceId || resourceId || undefined });
1719
}
1820

1921
// event hook to clear the resourceId when resourceType changes
2022
React.useEffect(() => {
2123
setResourceId('');
24+
setLookupValue('');
2225
}, [props.fqResourceId.resourceTypeName]);
2326

2427
// the resourceType may be configured to skip policy retrieval/display
2528
const displayPolicies = !_.find((res) => res.resourceType === props.fqResourceId.resourceTypeName, supportResources)
2629
?.skipPolicies;
2730

31+
// Get the current resource type configuration
32+
const currentResourceType = _.find(
33+
(res) => res.resourceType === props.fqResourceId.resourceTypeName,
34+
supportResources
35+
);
36+
37+
// Handle lookup when the resource type has a lookupResourceId function
38+
const handleLookup = async () => {
39+
if (currentResourceType?.lookupResourceIdFn && lookupValue) {
40+
try {
41+
const result = await currentResourceType.lookupResourceIdFn(lookupValue);
42+
setResourceId(result.resourceId);
43+
// specify the resourceId to avoid waiting for state to update
44+
submit(result.resourceId);
45+
} catch (error: any) {
46+
const errorMessage = error.status === 404 ? `${lookupValue} not found` : `Error looking up id: ${error}`;
47+
await reportError(errorMessage);
48+
}
49+
}
50+
};
51+
2852
return (
2953
<>
30-
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '1rem' }}>
54+
<div style={{ display: 'flex', flexDirection: 'column', marginBottom: '1rem' }}>
3155
<div
3256
style={{
3357
color: colors.dark(),
@@ -36,24 +60,53 @@ export const LookupSummaryAndPolicies = (props: ResourceTypeSummaryProps) => {
3660
display: 'flex',
3761
alignItems: 'center',
3862
marginLeft: '1rem',
63+
marginBottom: '0.5rem',
3964
}}
4065
>
4166
{props.displayName}
4267
</div>
43-
<TextInput
44-
style={{ marginRight: '1rem', marginLeft: '1rem' }}
45-
placeholder={`Enter ${props.displayName} ID`}
46-
onChange={(newResourceId) => {
47-
setResourceId(newResourceId);
48-
}}
49-
onKeyDown={(e) => {
50-
if (e.key === 'Enter') {
51-
submit();
52-
}
53-
}}
54-
value={resourceId}
55-
/>
56-
<ButtonPrimary onClick={() => submit()}>Load</ButtonPrimary>
68+
69+
{currentResourceType?.lookupResourceIdFn && (
70+
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '0.5rem' }}>
71+
<TextInput
72+
style={{ marginRight: '0.5rem', marginLeft: '1rem', flex: 1 }}
73+
placeholder={`Enter ${currentResourceType.lookupResourceIdBoxPlaceholder}`}
74+
onChange={setLookupValue}
75+
onKeyDown={(e) => {
76+
if (e.key === 'Enter') {
77+
handleLookup();
78+
}
79+
}}
80+
value={lookupValue}
81+
/>
82+
<ButtonPrimary onClick={handleLookup}>
83+
Load By {currentResourceType.lookupResourceIdBoxPlaceholder}
84+
</ButtonPrimary>
85+
</div>
86+
)}
87+
88+
{currentResourceType?.lookupResourceIdFn && (
89+
<div style={{ marginRight: '0.5rem', marginLeft: '1rem', flex: 1, marginBottom: '0.5rem' }}>
90+
<div style={{ fontWeight: 500 }}>or</div>
91+
</div>
92+
)}
93+
94+
<div style={{ display: 'flex', alignItems: 'center' }}>
95+
<TextInput
96+
style={{ marginRight: '0.5rem', marginLeft: '1rem', flex: 1 }}
97+
placeholder={`Enter ${props.displayName} ID`}
98+
onChange={(newResourceId) => {
99+
setResourceId(newResourceId);
100+
}}
101+
onKeyDown={(e) => {
102+
if (e.key === 'Enter') {
103+
submit();
104+
}
105+
}}
106+
value={resourceId}
107+
/>
108+
<ButtonPrimary onClick={() => submit()}>Load By ID</ButtonPrimary>
109+
</div>
57110
</div>
58111
{!!props.loadSupportSummaryFn && <SupportSummary {...props} />}
59112
{displayPolicies && <ResourcePolicies {...props} />}

src/support/SupportResourceType.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export interface SupportResourceType {
1818
resourceType: string;
1919
loadSupportSummaryFn: ((id: FullyQualifiedResourceId) => Promise<SupportSummary>) | undefined;
2020
skipPolicies?: boolean;
21+
lookupResourceIdFn?: (value: string) => Promise<FullyQualifiedResourceId>;
22+
lookupResourceIdBoxPlaceholder?: string;
2123
}
2224

2325
// Define the supported resources, add your own here
@@ -31,6 +33,16 @@ export const supportResources: SupportResourceType[] = [
3133
displayName: 'Workspace',
3234
resourceType: 'workspace',
3335
loadSupportSummaryFn: (id: FullyQualifiedResourceId) => Workspaces().adminGetById(id.resourceId),
36+
lookupResourceIdFn: async (namespaceSlashName: string) => {
37+
const nameParts = namespaceSlashName.split('/');
38+
if (nameParts.length !== 2) {
39+
return Promise.reject('enter namespace and name separated by a /');
40+
}
41+
const id = await Workspaces().adminGetId(nameParts[0], nameParts[1]);
42+
const fqResourceId: FullyQualifiedResourceId = { resourceId: id, resourceTypeName: 'workspace' };
43+
return fqResourceId;
44+
},
45+
lookupResourceIdBoxPlaceholder: 'Namespace/Name',
3446
},
3547
{
3648
displayName: 'Billing Project',

0 commit comments

Comments
 (0)