Skip to content

Commit e6d15df

Browse files
Addresses fixes to backend api
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
1 parent de27d12 commit e6d15df

File tree

2 files changed

+45
-38
lines changed

2 files changed

+45
-38
lines changed

public/apps/resource-sharing/resource-sharing-panel.tsx

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,16 @@ interface ResourceRow {
6161
can_share?: boolean; // whether the current user can share this resource
6262
}
6363
interface TypeEntry {
64-
type: string; // fully qualified class name
65-
index: string; // name of the index to be supplied to the API as resource_type
64+
type: string; // type of resource, e.g. `sample-resource`
6665
action_groups: string[]; // known action-groups for this type
6766
}
6867
// Tiny API that the panel consumes
6968
interface Api {
7069
listTypes: () => Promise<{ types: TypeEntry[] } | TypeEntry[]>;
71-
listSharingRecords: (
72-
index: string
73-
) => Promise<ResourceRow[] | { resources: ResourceRow[] } | any>;
70+
listSharingRecords: (type: string) => Promise<ResourceRow[] | { resources: ResourceRow[] } | any>;
7471
getSharingRecord: (
7572
id: string,
76-
index: string
73+
type: string
7774
) => Promise<ResourceRow | { resource: ResourceRow } | any>;
7875
share: (payload: {
7976
resource_id: string;
@@ -523,28 +520,39 @@ const SharedWithExpanded: React.FC<{ sw?: ShareWith }> = ({ sw }) => {
523520
);
524521
};
525522

526-
// Helpers: pick simple class name and humanize it
527-
const simpleName = (fqn: string) => (fqn?.split('.').pop() || fqn || '').trim();
523+
// Helpers: pick simple name and humanize it
524+
const simpleName = (type?: string) =>
525+
(
526+
(type ?? '')
527+
.split('.')
528+
.filter(Boolean) // remove empty parts from trailing dots, etc.
529+
.pop() ?? ''
530+
).trim();
531+
532+
/** Humanize class names: e.g., "AnomalyDetector" -> "Anomaly Detector", "ADDetector" -> "AD Detector",
533+
* and kebab/underscore: "sample-resource" -> "Sample Resource", "anomaly-detector" -> "Anomaly Detector"
534+
*/
535+
const normalizeResourceTypeName = (t: string) => {
536+
const type = simpleName(t);
528537

529-
/** Humanize class names: e.g., "AnomalyDetector" -> "Anomaly Detector", "ADDetector" -> "AD Detector" */
530-
const humanizeClassName = (fqn: string) => {
531-
const cls = simpleName(fqn);
532-
return (
533-
cls
534-
// split "ADDetector" -> "AD Detector"
535-
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
536-
// split camelCase "AnomalyDetector" -> "Anomaly Detector"
537-
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
538-
// underscores to spaces
539-
.replace(/_/g, ' ')
540-
.trim()
541-
);
538+
// 1) Insert spaces at camel/acronym boundaries, and normalize separators to spaces
539+
let s = type
540+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') // "ADDetector" -> "AD Detector"
541+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2') // "AnomalyDetector" -> "Anomaly Detector"
542+
.replace(/[-_]+/g, ' ') // "sample-resource" / "sample_resource" -> "sample resource"
543+
.replace(/\s+/g, ' ') // collapse multiple spaces
544+
.trim();
545+
546+
// 2) Title-case tokens that are all-lowercase; keep existing caps/acronyms as-is.
547+
s = s.replace(/\b([a-z])([a-z0-9]*)\b/g, (_, a, rest) => a.toUpperCase() + rest);
548+
549+
return s;
542550
};
543551

544552
/** ---------- Main table ---------- */
545553
export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
546554
const [typeOptions, setTypeOptions] = useState<
547-
Array<{ value: string; text: string; fqn: string; actionGroups: string[] }>
555+
Array<{ value: string; text: string; actionGroups: string[] }>
548556
>([]);
549557
const [selectedType, setSelectedType] = useState<string>(''); // no default selection
550558
const [rows, setRows] = useState<ResourceRow[]>([]);
@@ -567,17 +575,16 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
567575
// value = index (what we send as resourceType); text = type (what we display)
568576
const options = raw
569577
.map((t) => ({
570-
value: t.index,
571-
text: humanizeClassName(t.type),
572-
fqn: t.type,
578+
value: t.type,
579+
text: normalizeResourceTypeName(t.type),
573580
actionGroups: t.action_groups,
574581
}))
575582
// sort alphabetically by text (and by value if text is equal)
576583
.sort((a, b) => {
577584
const byText = a.text.localeCompare(b.text, undefined, { sensitivity: 'base' });
578585
return byText !== 0
579586
? byText
580-
: a.fqn.localeCompare(b.fqn, undefined, { sensitivity: 'base' });
587+
: a.value.localeCompare(b.value, undefined, { sensitivity: 'base' });
581588
});
582589
setTypeOptions(options);
583590
} catch (e: any) {
@@ -590,10 +597,10 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
590597
}, [toasts]);
591598

592599
// GET visible resource sharing records for selected type
593-
const fetchSharingRecords = async (index: string) => {
600+
const fetchSharingRecords = async (type: string) => {
594601
setLoading(true);
595602
try {
596-
const res = await api.listSharingRecords(index);
603+
const res = await api.listSharingRecords(type);
597604
const data: ResourceRow[] = Array.isArray(res) ? res : res?.resources || res?.body || [];
598605
setRows(Array.isArray(data) ? data : []);
599606
} catch (e: any) {
@@ -609,7 +616,7 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
609616
selectedType,
610617
]);
611618
const selectedTypeLabel = selectedTypeMeta?.text ?? (selectedType || '—');
612-
const selectedTypeTooltip = selectedTypeMeta?.fqn; // actual class name
619+
const selectedTypeTooltip = selectedTypeMeta?.value; // actual resource type
613620

614621
const currentActionGroups = useMemo(
615622
() => Array.from(new Set(selectedTypeMeta?.actionGroups ?? [])).sort(),
@@ -753,9 +760,9 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
753760
const baseOptions = useMemo<Array<EuiSuperSelectOption<string>>>(
754761
() =>
755762
typeOptions.map((o) => ({
756-
value: o.value, // index you send to backend
763+
value: o.value, // type name to send to backend
757764
inputDisplay: o.text, // humanized label when selected
758-
dropdownDisplay: <span title={o.fqn}>{o.text}</span>, // show FQN on hover
765+
dropdownDisplay: <span title={o.value}>{o.text}</span>, // show original resource-type on hover
759766
})),
760767
[typeOptions]
761768
);
@@ -798,11 +805,11 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
798805
hasDividers
799806
onChange={async (value) => {
800807
if (value === PLACEHOLDER) return;
801-
const resourceTypeIndex = value;
802-
setSelectedType(resourceTypeIndex);
808+
const resourceType = value;
809+
setSelectedType(resourceType);
803810
setExpandedIds(new Set());
804811
setRows([]);
805-
if (resourceTypeIndex) await fetchSharingRecords(resourceTypeIndex);
812+
if (resourceType) await fetchSharingRecords(resourceType);
806813
}}
807814
/>
808815
</EuiFlexItem>

public/utils/resource-sharing-utils.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import { CoreStart } from '../../../../src/core/public';
1717

1818
export const buildResourceApi = (http: CoreStart['http']) => ({
1919
listTypes: () => http.get('/api/resource/types'),
20-
listSharingRecords: (idx: string) =>
21-
http.get('/api/resource/list', { query: { resourceType: idx } }),
22-
getSharingRecord: (id: string, idx: string) =>
23-
http.get('/api/resource/view', { query: { resourceId: id, resourceType: idx } }),
20+
listSharingRecords: (type: string) =>
21+
http.get('/api/resource/list', { query: { resourceType: type } }),
22+
getSharingRecord: (id: string, type: string) =>
23+
http.get('/api/resource/view', { query: { resourceId: id, resourceType: type } }),
2424
share: (payload: any) => http.put('/api/resource/share', { body: JSON.stringify(payload) }),
2525
update: (payload: any) =>
2626
http.patch('/api/resource/update_sharing', { body: JSON.stringify(payload) }),

0 commit comments

Comments
 (0)