@pagerduty/backstage-plugin 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/alpha/pages.esm.js +41 -4
  3. package/dist/alpha/pages.esm.js.map +1 -1
  4. package/dist/alpha/plugin.esm.js +4 -3
  5. package/dist/alpha/plugin.esm.js.map +1 -1
  6. package/dist/alpha.d.ts +105 -26
  7. package/dist/api/client.esm.js +145 -3
  8. package/dist/api/client.esm.js.map +1 -1
  9. package/dist/components/PagerDutyPage/AutomaticMappingsDialog.esm.js +86 -40
  10. package/dist/components/PagerDutyPage/AutomaticMappingsDialog.esm.js.map +1 -1
  11. package/dist/components/PagerDutyPage/ConfigurationPage.esm.js +119 -0
  12. package/dist/components/PagerDutyPage/ConfigurationPage.esm.js.map +1 -0
  13. package/dist/components/PagerDutyPage/CustomFieldModal.esm.js +152 -0
  14. package/dist/components/PagerDutyPage/CustomFieldModal.esm.js.map +1 -0
  15. package/dist/components/PagerDutyPage/CustomFields/ButtonTabs.esm.js +51 -0
  16. package/dist/components/PagerDutyPage/CustomFields/ButtonTabs.esm.js.map +1 -0
  17. package/dist/components/PagerDutyPage/CustomFields/CustomFieldsEmptyState.esm.js +46 -0
  18. package/dist/components/PagerDutyPage/CustomFields/CustomFieldsEmptyState.esm.js.map +1 -0
  19. package/dist/components/PagerDutyPage/CustomFields/CustomFieldsTabPanel.esm.js +154 -0
  20. package/dist/components/PagerDutyPage/CustomFields/CustomFieldsTabPanel.esm.js.map +1 -0
  21. package/dist/components/PagerDutyPage/CustomFields/DeleteCustomFieldDialog.esm.js +63 -0
  22. package/dist/components/PagerDutyPage/CustomFields/DeleteCustomFieldDialog.esm.js.map +1 -0
  23. package/dist/components/PagerDutyPage/CustomFields/SyncLogsFilters.esm.js +126 -0
  24. package/dist/components/PagerDutyPage/CustomFields/SyncLogsFilters.esm.js.map +1 -0
  25. package/dist/components/PagerDutyPage/CustomFields/SyncLogsTab.esm.js +285 -0
  26. package/dist/components/PagerDutyPage/CustomFields/SyncLogsTab.esm.js.map +1 -0
  27. package/dist/components/PagerDutyPage/CustomFields/customFieldErrors.esm.js +13 -0
  28. package/dist/components/PagerDutyPage/CustomFields/customFieldErrors.esm.js.map +1 -0
  29. package/dist/components/PagerDutyPage/CustomFields.esm.js +192 -0
  30. package/dist/components/PagerDutyPage/CustomFields.esm.js.map +1 -0
  31. package/dist/components/PagerDutyPage/MappingsDialog.esm.js +2 -0
  32. package/dist/components/PagerDutyPage/MappingsDialog.esm.js.map +1 -1
  33. package/dist/components/PagerDutyPage/MappingsTable/MappingsTable.esm.js +1 -1
  34. package/dist/components/PagerDutyPage/MappingsTable/MappingsTable.esm.js.map +1 -1
  35. package/dist/components/PagerDutyPage/MappingsTable/MappingsTableContent.esm.js +15 -3
  36. package/dist/components/PagerDutyPage/MappingsTable/MappingsTableContent.esm.js.map +1 -1
  37. package/dist/components/PagerDutyPage/MappingsTable/NameCell.esm.js +35 -0
  38. package/dist/components/PagerDutyPage/MappingsTable/NameCell.esm.js.map +1 -0
  39. package/dist/components/PagerDutyPage/MappingsTable/TableSkeleton.esm.js +26 -29
  40. package/dist/components/PagerDutyPage/MappingsTable/TableSkeleton.esm.js.map +1 -1
  41. package/dist/components/PagerDutyPage/ServiceMappingPage.esm.js +22 -0
  42. package/dist/components/PagerDutyPage/ServiceMappingPage.esm.js.map +1 -0
  43. package/dist/components/PagerDutyPage/index.esm.js +12 -127
  44. package/dist/components/PagerDutyPage/index.esm.js.map +1 -1
  45. package/dist/index.d.ts +60 -8
  46. package/dist/package.json.esm.js +1 -1
  47. package/package.json +17 -17
  48. package/dist/alpha/nav-items.esm.js +0 -21
  49. package/dist/alpha/nav-items.esm.js.map +0 -1
@@ -0,0 +1,192 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
3
+ import { QueryClientProvider, QueryClient, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
4
+ import { Box, Alert, Card, CardHeader, Flex, Text, CardBody, Switch, Select, Button } from '@backstage/ui';
5
+ import { useApi } from '@backstage/core-plugin-api';
6
+ import { NotFoundError } from '@backstage/errors';
7
+ import { makeStyles } from '@material-ui/core';
8
+ import { pagerDutyApiRef } from '../../api/client.esm.js';
9
+ import { ButtonTabs } from './CustomFields/ButtonTabs.esm.js';
10
+ import { CustomFieldsTabPanel } from './CustomFields/CustomFieldsTabPanel.esm.js';
11
+ import { SyncLogsTab } from './CustomFields/SyncLogsTab.esm.js';
12
+ import { AccountProvider, useAccountContext } from './AccountContext.esm.js';
13
+ import { CustomFieldModal } from './CustomFieldModal.esm.js';
14
+ import { toFieldErrors } from './CustomFields/customFieldErrors.esm.js';
15
+
16
+ const queryClient = new QueryClient();
17
+ const DATA_SYNC_SETTING_ID = "settings::data-sync";
18
+ const useStyles = makeStyles(() => ({
19
+ syncCardWrapper: {
20
+ minWidth: 220
21
+ },
22
+ syncCardBody: {
23
+ padding: "8px 12px"
24
+ },
25
+ accountSelector: {
26
+ width: 240
27
+ }
28
+ }));
29
+ const TABS = [
30
+ { key: "fields", label: "Custom Fields" },
31
+ { key: "logs", label: "Activity Logs" }
32
+ ];
33
+ const CustomFieldsTabContent = () => {
34
+ const pagerDutyApi = useApi(pagerDutyApiRef);
35
+ const reactQueryClient = useQueryClient();
36
+ const classes = useStyles();
37
+ const [activeTab, setActiveTab] = useState("fields");
38
+ const { selectedAccount, setSelectedAccount, accounts } = useAccountContext();
39
+ const account = selectedAccount || void 0;
40
+ const [isAddModalOpen, setIsAddModalOpen] = useState(false);
41
+ const [addSaving, setAddSaving] = useState(false);
42
+ const [addError, setAddError] = useState(null);
43
+ const showAccountSelector = accounts.length > 1;
44
+ const { data: orgWideSyncOn = false } = useQuery({
45
+ queryKey: ["pagerduty", "settings", DATA_SYNC_SETTING_ID],
46
+ queryFn: async () => {
47
+ try {
48
+ const result = await pagerDutyApi.getSetting(
49
+ DATA_SYNC_SETTING_ID
50
+ );
51
+ return result?.value === "enabled";
52
+ } catch (error) {
53
+ if (error instanceof NotFoundError) {
54
+ return false;
55
+ }
56
+ throw error;
57
+ }
58
+ }
59
+ });
60
+ const { mutate: toggleSync } = useMutation({
61
+ mutationFn: (enabled) => {
62
+ const setting = {
63
+ id: DATA_SYNC_SETTING_ID,
64
+ value: enabled ? "enabled" : "disabled"
65
+ };
66
+ return pagerDutyApi.storeSettings([setting]);
67
+ },
68
+ onMutate: (enabled) => {
69
+ reactQueryClient.setQueryData(
70
+ ["pagerduty", "settings", DATA_SYNC_SETTING_ID],
71
+ enabled
72
+ );
73
+ },
74
+ onError: (_error, enabled) => {
75
+ reactQueryClient.setQueryData(
76
+ ["pagerduty", "settings", DATA_SYNC_SETTING_ID],
77
+ !enabled
78
+ );
79
+ }
80
+ });
81
+ const handleOpenAdd = () => {
82
+ setAddError(null);
83
+ setIsAddModalOpen(true);
84
+ };
85
+ const handleCloseAdd = () => {
86
+ setIsAddModalOpen(false);
87
+ setAddError(null);
88
+ };
89
+ const handleSaveAdd = async (formData) => {
90
+ setAddSaving(true);
91
+ setAddError(null);
92
+ const result = await pagerDutyApi.createCustomField(formData, account);
93
+ if (result.status === "ok") {
94
+ reactQueryClient.invalidateQueries({ queryKey: ["pagerduty", "customFields", account ?? ""] });
95
+ setIsAddModalOpen(false);
96
+ } else {
97
+ setAddError(toFieldErrors(result.error));
98
+ }
99
+ setAddSaving(false);
100
+ };
101
+ return /* @__PURE__ */ jsxs(Box, { pl: "20px", pr: "20px", children: [
102
+ /* @__PURE__ */ jsx(
103
+ Alert,
104
+ {
105
+ status: "info",
106
+ icon: true,
107
+ title: "Enrich your PagerDuty services with data from your Backstage catalog.",
108
+ description: "Create custom field mappings to surface the right context \u2014 runbook links, team ownership, and more \u2014 directly in PagerDuty.",
109
+ style: { marginBottom: "8px" }
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsxs(Card, { children: [
113
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(Flex, { align: "start", justify: "between", gap: "3", children: [
114
+ /* @__PURE__ */ jsx(Flex, { direction: "column", gap: "1", children: /* @__PURE__ */ jsx(Text, { variant: "body-medium", weight: "bold", children: "Manage your custom fields and review their sync activity." }) }),
115
+ /* @__PURE__ */ jsx(Box, { className: classes.syncCardWrapper, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardBody, { className: classes.syncCardBody, children: /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", gap: "2", children: [
116
+ /* @__PURE__ */ jsxs(
117
+ Text,
118
+ {
119
+ variant: "body-small",
120
+ weight: "bold",
121
+ color: orgWideSyncOn ? "success" : "secondary",
122
+ children: [
123
+ "Org-Wide Data Sync: ",
124
+ orgWideSyncOn ? "On" : "Off"
125
+ ]
126
+ }
127
+ ),
128
+ /* @__PURE__ */ jsx(
129
+ Switch,
130
+ {
131
+ isSelected: orgWideSyncOn,
132
+ onChange: toggleSync,
133
+ "aria-label": "Toggle org-wide data sync"
134
+ }
135
+ )
136
+ ] }) }) }) })
137
+ ] }) }),
138
+ /* @__PURE__ */ jsxs(CardBody, { children: [
139
+ /* @__PURE__ */ jsxs(Flex, { align: "end", justify: "between", gap: "3", mb: "4", children: [
140
+ /* @__PURE__ */ jsxs(Flex, { align: "end", gap: "3", children: [
141
+ showAccountSelector && /* @__PURE__ */ jsx(Box, { className: classes.accountSelector, children: /* @__PURE__ */ jsx(
142
+ Select,
143
+ {
144
+ label: "Select Account",
145
+ isRequired: true,
146
+ selectionMode: "single",
147
+ size: "small",
148
+ value: selectedAccount,
149
+ onChange: (value) => setSelectedAccount(value?.toString() ?? ""),
150
+ placeholder: "Select account",
151
+ options: accounts
152
+ }
153
+ ) }),
154
+ /* @__PURE__ */ jsx(
155
+ ButtonTabs,
156
+ {
157
+ items: TABS,
158
+ value: activeTab,
159
+ onChange: setActiveTab
160
+ }
161
+ )
162
+ ] }),
163
+ /* @__PURE__ */ jsx(
164
+ Button,
165
+ {
166
+ variant: "secondary",
167
+ size: "small",
168
+ onClick: handleOpenAdd,
169
+ children: "+ Add New"
170
+ }
171
+ )
172
+ ] }),
173
+ activeTab === "fields" ? /* @__PURE__ */ jsx(CustomFieldsTabPanel, {}, selectedAccount) : /* @__PURE__ */ jsx(SyncLogsTab, {}, selectedAccount)
174
+ ] }),
175
+ /* @__PURE__ */ jsx(
176
+ CustomFieldModal,
177
+ {
178
+ open: isAddModalOpen,
179
+ saving: addSaving,
180
+ error: addError,
181
+ onClose: handleCloseAdd,
182
+ onSave: handleSaveAdd,
183
+ mode: "add"
184
+ }
185
+ )
186
+ ] })
187
+ ] });
188
+ };
189
+ const CustomFields = () => /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(AccountProvider, { children: /* @__PURE__ */ jsx(CustomFieldsTabContent, {}) }) });
190
+
191
+ export { CustomFields };
192
+ //# sourceMappingURL=CustomFields.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomFields.esm.js","sources":["../../../src/components/PagerDutyPage/CustomFields.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n QueryClient,\n QueryClientProvider,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardBody,\n CardHeader,\n Flex,\n Select,\n Switch,\n Text,\n} from '@backstage/ui';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { NotFoundError } from '@backstage/errors';\nimport { makeStyles } from '@material-ui/core';\nimport { pagerDutyApiRef } from '../../api';\nimport type { PagerDutySetting } from '@pagerduty/backstage-plugin-common';\nimport { ButtonTabs, ButtonTabItem } from './CustomFields/ButtonTabs';\nimport { CustomFieldsTabPanel } from './CustomFields/CustomFieldsTabPanel';\nimport { SyncLogsTab } from './CustomFields/SyncLogsTab';\nimport { AccountProvider, useAccountContext } from './AccountContext';\nimport { CustomFieldModal, FieldErrors } from './CustomFieldModal';\nimport { toFieldErrors } from './CustomFields/customFieldErrors';\n\nconst queryClient = new QueryClient();\n\nconst DATA_SYNC_SETTING_ID = 'settings::data-sync';\n\n// The data-sync toggle reuses the generic settings store but with its own\n// enabled/disabled value, distinct from the dependency-strategy PagerDutySetting.\ntype DataSyncSetting = { id: string; value: 'enabled' | 'disabled' };\n\nconst useStyles = makeStyles(() => ({\n syncCardWrapper: {\n minWidth: 220,\n },\n syncCardBody: {\n padding: '8px 12px',\n },\n accountSelector: {\n width: 240,\n },\n}));\n\ntype TabKey = 'fields' | 'logs';\n\nconst TABS: ButtonTabItem<TabKey>[] = [\n { key: 'fields', label: 'Custom Fields' },\n { key: 'logs', label: 'Activity Logs' },\n];\n\nconst CustomFieldsTabContent = () => {\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const reactQueryClient = useQueryClient();\n const classes = useStyles();\n const [activeTab, setActiveTab] = useState<TabKey>('fields');\n const { selectedAccount, setSelectedAccount, accounts } = useAccountContext();\n const account = selectedAccount || undefined;\n\n const [isAddModalOpen, setIsAddModalOpen] = useState(false);\n const [addSaving, setAddSaving] = useState(false);\n const [addError, setAddError] = useState<FieldErrors | null>(null);\n\n const showAccountSelector = accounts.length > 1;\n\n const { data: orgWideSyncOn = false } = useQuery({\n queryKey: ['pagerduty', 'settings', DATA_SYNC_SETTING_ID],\n queryFn: async () => {\n try {\n const result = (await pagerDutyApi.getSetting(\n DATA_SYNC_SETTING_ID,\n )) as DataSyncSetting;\n return result?.value === 'enabled';\n } catch (error) {\n if (error instanceof NotFoundError) {\n // The setting has never been saved — treat the sync as disabled.\n return false;\n }\n throw error;\n }\n },\n });\n\n const { mutate: toggleSync } = useMutation({\n mutationFn: (enabled: boolean) => {\n const setting: DataSyncSetting = {\n id: DATA_SYNC_SETTING_ID,\n value: enabled ? 'enabled' : 'disabled',\n };\n return pagerDutyApi.storeSettings([setting as PagerDutySetting]);\n },\n onMutate: (enabled: boolean) => {\n // Optimistically reflect the toggle while the request is in flight.\n reactQueryClient.setQueryData(\n ['pagerduty', 'settings', DATA_SYNC_SETTING_ID],\n enabled,\n );\n },\n onError: (_error, enabled: boolean) => {\n // Roll back to the previous value on failure.\n reactQueryClient.setQueryData(\n ['pagerduty', 'settings', DATA_SYNC_SETTING_ID],\n !enabled,\n );\n },\n });\n\n const handleOpenAdd = () => {\n setAddError(null);\n setIsAddModalOpen(true);\n };\n\n const handleCloseAdd = () => {\n setIsAddModalOpen(false);\n setAddError(null);\n };\n\n const handleSaveAdd = async (formData: { name: string; entityPath: string; description: string }) => {\n setAddSaving(true);\n setAddError(null);\n const result = await pagerDutyApi.createCustomField(formData, account);\n if (result.status === 'ok') {\n reactQueryClient.invalidateQueries({ queryKey: ['pagerduty', 'customFields', account ?? ''] });\n setIsAddModalOpen(false);\n } else {\n setAddError(toFieldErrors(result.error));\n }\n setAddSaving(false);\n };\n\n return (\n <Box pl=\"20px\" pr=\"20px\">\n <Alert\n status=\"info\"\n icon\n title=\"Enrich your PagerDuty services with data from your Backstage catalog.\"\n description=\"Create custom field mappings to surface the right context — runbook links, team ownership, and more — directly in PagerDuty.\"\n style={{marginBottom: '8px'}}\n />\n <Card>\n <CardHeader>\n <Flex align=\"start\" justify=\"between\" gap=\"3\">\n <Flex direction=\"column\" gap=\"1\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Manage your custom fields and review their sync activity.\n </Text>\n </Flex>\n <Box className={classes.syncCardWrapper}>\n <Card>\n <CardBody className={classes.syncCardBody}>\n <Flex align=\"center\" justify=\"between\" gap=\"2\">\n <Text\n variant=\"body-small\"\n weight=\"bold\"\n color={orgWideSyncOn ? 'success' : 'secondary'}\n >\n Org-Wide Data Sync: {orgWideSyncOn ? 'On' : 'Off'}\n </Text>\n <Switch\n isSelected={orgWideSyncOn}\n onChange={toggleSync}\n aria-label=\"Toggle org-wide data sync\"\n />\n </Flex>\n </CardBody>\n </Card>\n </Box>\n </Flex>\n </CardHeader>\n\n <CardBody>\n <Flex align=\"end\" justify=\"between\" gap=\"3\" mb=\"4\">\n <Flex align=\"end\" gap=\"3\">\n {showAccountSelector && (\n <Box className={classes.accountSelector}>\n <Select\n label=\"Select Account\"\n isRequired\n selectionMode=\"single\"\n size=\"small\"\n value={selectedAccount}\n onChange={value => setSelectedAccount(value?.toString() ?? '')}\n placeholder=\"Select account\"\n options={accounts}\n />\n </Box>\n )}\n <ButtonTabs<TabKey>\n items={TABS}\n value={activeTab}\n onChange={setActiveTab}\n />\n </Flex>\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={handleOpenAdd}\n >\n + Add New\n </Button>\n </Flex>\n\n {activeTab === 'fields' ? (\n <CustomFieldsTabPanel key={selectedAccount} />\n ) : (\n <SyncLogsTab key={selectedAccount} />\n )}\n </CardBody>\n\n <CustomFieldModal\n open={isAddModalOpen}\n saving={addSaving}\n error={addError}\n onClose={handleCloseAdd}\n onSave={handleSaveAdd}\n mode=\"add\"\n />\n </Card>\n </Box>\n );\n};\n\n/** @public */\nexport const CustomFields = () => (\n <QueryClientProvider client={queryClient}>\n <AccountProvider>\n <CustomFieldsTabContent />\n </AccountProvider>\n </QueryClientProvider>\n);\n"],"names":[],"mappings":"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"}
@@ -178,6 +178,8 @@ function MappingsDialog({
178
178
  placeholder: "All Teams",
179
179
  options: teamOptions,
180
180
  value: selectedTeamId,
181
+ searchPlaceholder: "Search teams...",
182
+ searchable: true,
181
183
  onChange: (value) => {
182
184
  setSelectedTeamId(String(value || ""));
183
185
  setSelectedServiceId("");
@@ -1 +1 @@
1
- {"version":3,"file":"MappingsDialog.esm.js","sources":["../../../src/components/PagerDutyPage/MappingsDialog.tsx"],"sourcesContent":["import {\n Dialog,\n DialogHeader,\n DialogBody,\n DialogFooter,\n Button,\n Select,\n Flex,\n Text,\n SearchField,\n RadioGroup,\n Radio,\n Box,\n TextField,\n} from '@backstage/ui';\nimport { Dispatch, useState, useEffect } from 'react';\nimport { BackstageEntity } from '../types';\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { pagerDutyApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core';\nimport { useAccountContext } from './AccountContext';\nimport useDebounce from '../../hooks/useDebounce';\n\nconst useStyles = makeStyles(() => ({\n radioListContainer: {\n maxHeight: '300px',\n overflowY: 'auto',\n border: '1px solid var(--bui-border)',\n borderRadius: 'var(--bui-radius-2)',\n padding: 0,\n '& > div > div': {\n gap: 0,\n },\n '& label[data-rac]': {\n margin: 0,\n padding: 'var(--bui-spacing-2) var(--bui-spacing-3)',\n minHeight: '32px',\n borderBottom: '1px solid var(--bui-gray-2)',\n borderLeft: '3px solid transparent',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease',\n display: 'flex',\n alignItems: 'center',\n '&:last-child': {\n borderBottom: 'none',\n },\n '&:hover': {\n backgroundColor: 'var(--bui-gray-1)',\n },\n '&[data-selected=\"true\"]': {\n backgroundColor: 'var(--bui-blue-1)',\n borderLeft: '3px solid var(--bui-blue-6)',\n fontWeight: 'var(--bui-font-weight-bold)',\n },\n },\n },\n}));\n\ninterface MappingsDialogProps {\n isOpen: boolean;\n setIsOpen: Dispatch<React.SetStateAction<boolean>>;\n entity: BackstageEntity | null;\n onMappingSuccess?: (isUnmapping: boolean) => void;\n}\n\nexport default function MappingsDialog({\n isOpen,\n setIsOpen,\n entity,\n onMappingSuccess,\n}: MappingsDialogProps) {\n const classes = useStyles();\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const queryClient = useQueryClient();\n const { selectedAccount } = useAccountContext();\n const [selectedServiceId, setSelectedServiceId] = useState<string>('');\n const [selectedTeamId, setSelectedTeamId] = useState<string>('');\n const [searchQuery, setSearchQuery] = useState<string>('');\n const debouncedSearchQuery = useDebounce(searchQuery);\n\n useEffect(() => {\n if (!isOpen) {\n setSelectedServiceId('');\n setSelectedTeamId('');\n setSearchQuery('');\n }\n }, [isOpen]);\n\n const accountParam = selectedAccount || undefined;\n\n const { data: teams, isLoading: isTeamsLoading } = useQuery({\n queryKey: ['pagerduty', 'getAllTeams', accountParam],\n queryFn: () => pagerDutyApi.getAllTeams(accountParam),\n enabled: isOpen,\n });\n\n const { data: services, isLoading: isServicesLoading } = useQuery({\n queryKey: ['pagerduty', 'getFilteredServices', selectedTeamId, debouncedSearchQuery, accountParam],\n queryFn: async () => {\n const teamIdsToSend = selectedTeamId ? [selectedTeamId] : undefined;\n const queryToSend = debouncedSearchQuery || undefined;\n const result = await pagerDutyApi.getFilteredServices(\n teamIdsToSend,\n queryToSend,\n 10,\n accountParam,\n );\n return result;\n },\n enabled: isOpen,\n });\n\n const { mutateAsync: createMapping, isPending: isCreatingMapping } =\n useMutation({\n mutationFn: async ({\n serviceId,\n integrationKey,\n entityRef,\n account,\n isUnmapping,\n }: {\n serviceId: string;\n integrationKey: string;\n entityRef: string;\n account: string;\n isUnmapping: boolean;\n }) => {\n await pagerDutyApi.storeServiceMapping(\n serviceId,\n integrationKey,\n entityRef,\n account,\n );\n return isUnmapping;\n },\n\n onSuccess: async (isUnmapping) => {\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n setIsOpen(false);\n setSelectedServiceId('');\n onMappingSuccess?.(isUnmapping);\n },\n });\n\n const handleSaveMapping = () => {\n if (!entity || !selectedServiceId) return;\n\n if (selectedServiceId === 'none') {\n const currentServiceId = entity.annotations?.['pagerduty.com/service-id'];\n const currentIntegrationKey = entity.annotations?.['pagerduty.com/integration-key'] || '';\n const account = entity.account || '';\n\n if (!currentServiceId) return;\n\n createMapping({\n serviceId: currentServiceId,\n integrationKey: currentIntegrationKey,\n entityRef: '',\n account: account,\n isUnmapping: true,\n });\n return;\n }\n\n const selectedService = services?.find(\n service => service.id === selectedServiceId,\n );\n\n if (!selectedService) return;\n\n const entityRef =\n `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase();\n\n createMapping({\n serviceId: selectedServiceId,\n integrationKey: '',\n entityRef: entityRef,\n account: selectedService.account ?? '',\n isUnmapping: false,\n });\n };\n\n // Prepare team options for Select\n const teamOptions = [\n { value: '', label: 'All Teams' },\n ...(teams?.map(team => ({\n value: team.id,\n label: team.name,\n })) || []),\n ];\n\n return (\n <Dialog isOpen={isOpen} onOpenChange={setIsOpen}>\n <DialogHeader>Update Entity Mapping</DialogHeader>\n <DialogBody>\n <Flex direction=\"column\" gap=\"2\" mb=\"4\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Backstage Component\n </Text>\n <TextField\n value={entity?.name || ''}\n isReadOnly\n />\n </Flex>\n\n <Flex direction=\"column\" gap=\"2\" mb=\"4\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Team\n </Text>\n <TextField\n value={entity?.owner || ''}\n isReadOnly\n />\n </Flex>\n\n <Box mb=\"3\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Map to Service\n </Text>\n </Box>\n\n <Box mb=\"3\">\n <Select\n name=\"team\"\n isDisabled={isTeamsLoading || isCreatingMapping}\n label=\"PagerDuty Team (Optional)\"\n placeholder=\"All Teams\"\n options={teamOptions}\n value={selectedTeamId}\n onChange={value => {\n setSelectedTeamId(String(value || ''));\n setSelectedServiceId('');\n }}\n />\n </Box>\n\n <Flex direction=\"column\" gap=\"2\" mb=\"3\">\n <Text variant=\"body-medium\" weight=\"bold\">\n PagerDuty Services\n </Text>\n <Text variant=\"body-small\">\n Search by service name or service ID\n </Text>\n <SearchField\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder=\"Search\"\n />\n </Flex>\n\n {isServicesLoading ? (\n <Text>Loading services...</Text>\n ) : (\n <>\n <Box\n className={classes.radioListContainer}\n mb=\"2\"\n >\n <RadioGroup\n value={selectedServiceId}\n onChange={setSelectedServiceId}\n >\n {entity?.annotations?.['pagerduty.com/service-id'] && (\n <Radio key=\"none\" value=\"none\">\n (None)\n </Radio>\n )}\n {services && services\n .filter(service => service.id !== entity?.annotations?.['pagerduty.com/service-id'])\n .map(service => (\n <Radio key={service.id} value={service.id}>\n {service.name}\n </Radio>\n ))}\n </RadioGroup>\n </Box>\n {services && services.length > 0 ? (\n <Text variant=\"body-small\">\n Showing {services.length} result{services.length !== 1 ? 's' : ''}\n </Text>\n ) : (\n <Text variant=\"body-small\">No services found</Text>\n )}\n </>\n )}\n </DialogBody>\n <DialogFooter>\n <Button variant=\"secondary\" slot=\"close\">\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n onClick={handleSaveMapping}\n isDisabled={!selectedServiceId || isCreatingMapping}\n >\n {isCreatingMapping ? 'Saving...' : 'Save'}\n </Button>\n </DialogFooter>\n </Dialog>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MappingsDialog.esm.js","sources":["../../../src/components/PagerDutyPage/MappingsDialog.tsx"],"sourcesContent":["import {\n Dialog,\n DialogHeader,\n DialogBody,\n DialogFooter,\n Button,\n Select,\n Flex,\n Text,\n SearchField,\n RadioGroup,\n Radio,\n Box,\n TextField,\n} from '@backstage/ui';\nimport { Dispatch, useState, useEffect } from 'react';\nimport { BackstageEntity } from '../types';\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { pagerDutyApiRef } from '../../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core';\nimport { useAccountContext } from './AccountContext';\nimport useDebounce from '../../hooks/useDebounce';\n\nconst useStyles = makeStyles(() => ({\n radioListContainer: {\n maxHeight: '300px',\n overflowY: 'auto',\n border: '1px solid var(--bui-border)',\n borderRadius: 'var(--bui-radius-2)',\n padding: 0,\n '& > div > div': {\n gap: 0,\n },\n '& label[data-rac]': {\n margin: 0,\n padding: 'var(--bui-spacing-2) var(--bui-spacing-3)',\n minHeight: '32px',\n borderBottom: '1px solid var(--bui-gray-2)',\n borderLeft: '3px solid transparent',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease',\n display: 'flex',\n alignItems: 'center',\n '&:last-child': {\n borderBottom: 'none',\n },\n '&:hover': {\n backgroundColor: 'var(--bui-gray-1)',\n },\n '&[data-selected=\"true\"]': {\n backgroundColor: 'var(--bui-blue-1)',\n borderLeft: '3px solid var(--bui-blue-6)',\n fontWeight: 'var(--bui-font-weight-bold)',\n },\n },\n },\n}));\n\ninterface MappingsDialogProps {\n isOpen: boolean;\n setIsOpen: Dispatch<React.SetStateAction<boolean>>;\n entity: BackstageEntity | null;\n onMappingSuccess?: (isUnmapping: boolean) => void;\n}\n\nexport default function MappingsDialog({\n isOpen,\n setIsOpen,\n entity,\n onMappingSuccess,\n}: MappingsDialogProps) {\n const classes = useStyles();\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const queryClient = useQueryClient();\n const { selectedAccount } = useAccountContext();\n const [selectedServiceId, setSelectedServiceId] = useState<string>('');\n const [selectedTeamId, setSelectedTeamId] = useState<string>('');\n const [searchQuery, setSearchQuery] = useState<string>('');\n const debouncedSearchQuery = useDebounce(searchQuery);\n\n useEffect(() => {\n if (!isOpen) {\n setSelectedServiceId('');\n setSelectedTeamId('');\n setSearchQuery('');\n }\n }, [isOpen]);\n\n const accountParam = selectedAccount || undefined;\n\n const { data: teams, isLoading: isTeamsLoading } = useQuery({\n queryKey: ['pagerduty', 'getAllTeams', accountParam],\n queryFn: () => pagerDutyApi.getAllTeams(accountParam),\n enabled: isOpen,\n });\n\n const { data: services, isLoading: isServicesLoading } = useQuery({\n queryKey: ['pagerduty', 'getFilteredServices', selectedTeamId, debouncedSearchQuery, accountParam],\n queryFn: async () => {\n const teamIdsToSend = selectedTeamId ? [selectedTeamId] : undefined;\n const queryToSend = debouncedSearchQuery || undefined;\n const result = await pagerDutyApi.getFilteredServices(\n teamIdsToSend,\n queryToSend,\n 10,\n accountParam,\n );\n return result;\n },\n enabled: isOpen,\n });\n\n const { mutateAsync: createMapping, isPending: isCreatingMapping } =\n useMutation({\n mutationFn: async ({\n serviceId,\n integrationKey,\n entityRef,\n account,\n isUnmapping,\n }: {\n serviceId: string;\n integrationKey: string;\n entityRef: string;\n account: string;\n isUnmapping: boolean;\n }) => {\n await pagerDutyApi.storeServiceMapping(\n serviceId,\n integrationKey,\n entityRef,\n account,\n );\n return isUnmapping;\n },\n\n onSuccess: async (isUnmapping) => {\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n setIsOpen(false);\n setSelectedServiceId('');\n onMappingSuccess?.(isUnmapping);\n },\n });\n\n const handleSaveMapping = () => {\n if (!entity || !selectedServiceId) return;\n\n if (selectedServiceId === 'none') {\n const currentServiceId = entity.annotations?.['pagerduty.com/service-id'];\n const currentIntegrationKey = entity.annotations?.['pagerduty.com/integration-key'] || '';\n const account = entity.account || '';\n\n if (!currentServiceId) return;\n\n createMapping({\n serviceId: currentServiceId,\n integrationKey: currentIntegrationKey,\n entityRef: '',\n account: account,\n isUnmapping: true,\n });\n return;\n }\n\n const selectedService = services?.find(\n service => service.id === selectedServiceId,\n );\n\n if (!selectedService) return;\n\n const entityRef =\n `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase();\n\n createMapping({\n serviceId: selectedServiceId,\n integrationKey: '',\n entityRef: entityRef,\n account: selectedService.account ?? '',\n isUnmapping: false,\n });\n };\n\n // Prepare team options for Select\n const teamOptions = [\n { value: '', label: 'All Teams' },\n ...(teams?.map(team => ({\n value: team.id,\n label: team.name,\n })) || []),\n ];\n\n return (\n <Dialog isOpen={isOpen} onOpenChange={setIsOpen}>\n <DialogHeader>Update Entity Mapping</DialogHeader>\n <DialogBody>\n <Flex direction=\"column\" gap=\"2\" mb=\"4\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Backstage Component\n </Text>\n <TextField\n value={entity?.name || ''}\n isReadOnly\n />\n </Flex>\n\n <Flex direction=\"column\" gap=\"2\" mb=\"4\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Team\n </Text>\n <TextField\n value={entity?.owner || ''}\n isReadOnly\n />\n </Flex>\n\n <Box mb=\"3\">\n <Text variant=\"body-medium\" weight=\"bold\">\n Map to Service\n </Text>\n </Box>\n\n <Box mb=\"3\">\n <Select\n name=\"team\"\n isDisabled={isTeamsLoading || isCreatingMapping}\n label=\"PagerDuty Team (Optional)\"\n placeholder=\"All Teams\"\n options={teamOptions}\n value={selectedTeamId}\n searchPlaceholder='Search teams...'\n searchable\n onChange={value => {\n setSelectedTeamId(String(value || ''));\n setSelectedServiceId('');\n }}\n />\n </Box>\n\n <Flex direction=\"column\" gap=\"2\" mb=\"3\">\n <Text variant=\"body-medium\" weight=\"bold\">\n PagerDuty Services\n </Text>\n <Text variant=\"body-small\">\n Search by service name or service ID\n </Text>\n <SearchField\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder=\"Search\"\n />\n </Flex>\n\n {isServicesLoading ? (\n <Text>Loading services...</Text>\n ) : (\n <>\n <Box\n className={classes.radioListContainer}\n mb=\"2\"\n >\n <RadioGroup\n value={selectedServiceId}\n onChange={setSelectedServiceId}\n >\n {entity?.annotations?.['pagerduty.com/service-id'] && (\n <Radio key=\"none\" value=\"none\">\n (None)\n </Radio>\n )}\n {services && services\n .filter(service => service.id !== entity?.annotations?.['pagerduty.com/service-id'])\n .map(service => (\n <Radio key={service.id} value={service.id}>\n {service.name}\n </Radio>\n ))}\n </RadioGroup>\n </Box>\n {services && services.length > 0 ? (\n <Text variant=\"body-small\">\n Showing {services.length} result{services.length !== 1 ? 's' : ''}\n </Text>\n ) : (\n <Text variant=\"body-small\">No services found</Text>\n )}\n </>\n )}\n </DialogBody>\n <DialogFooter>\n <Button variant=\"secondary\" slot=\"close\">\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n onClick={handleSaveMapping}\n isDisabled={!selectedServiceId || isCreatingMapping}\n >\n {isCreatingMapping ? 'Saving...' : 'Save'}\n </Button>\n </DialogFooter>\n </Dialog>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -66,7 +66,7 @@ function MappingsTable() {
66
66
  setToastOpen(true);
67
67
  setToastSeverity("info");
68
68
  setToastMessage(
69
- `Mapping ${isUnmapping ? "removed" : "created"} successfully. The catalog sync runs approximately every 30 seconds. Please wait a bit and refresh the page to see the updated status.`
69
+ `Mapping ${isUnmapping ? "removed" : "created"}. The status updates automatically once Backstage re-processes the entity \u2014 this can take a few minutes. Refresh the page to check.`
70
70
  );
71
71
  setToastTotalMatches(0);
72
72
  setToastMappingCounts({});
@@ -1 +1 @@
1
- {"version":3,"file":"MappingsTable.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/MappingsTable.tsx"],"sourcesContent":["import {\n Flex,\n ButtonIcon,\n} from '@backstage/ui';\nimport { useState, useCallback } from 'react';\nimport MappingsDialog from '../MappingsDialog';\nimport AutomaticMappingsDialog from '../AutomaticMappingsDialog';\nimport AutoMappingsButton from './AutoMappingsButton';\nimport { FilterList, Refresh } from '@mui/icons-material';\nimport { BackstageEntity } from '../../types';\nimport MappingToast, { MappingCounts, ToastSeverity } from './MappingToast';\nimport { useConfirmMappings } from './hooks/useConfirmMappings';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { FormattedBackstageEntity } from '@pagerduty/backstage-plugin-common';\nimport { useAccountContext } from '../AccountContext';\nimport MappingsTableContent from './MappingsTableContent';\n\nexport interface AutoMatchResult {\n score: number;\n serviceId: string;\n account: string;\n serviceName: string;\n entity?: {\n name: string;\n entityRef: string;\n owner: string;\n };\n}\n\nexport type AutoMatchResults = Record<string, AutoMatchResult>;\n\nexport default function MappingsTable() {\n const queryClient = useQueryClient();\n const { selectedAccount } = useAccountContext();\n\n const [isOpen, setIsOpen] = useState(false);\n const [isAutoMappingOpen, setIsAutoMappingOpen] = useState(false);\n const [selectedEntity, setSelectedEntity] = useState<BackstageEntity | null>(\n null,\n );\n const [showFilters, setShowFilters] = useState(false);\n\n const [filters, setFilters] = useState({\n name: '',\n serviceName: '',\n status: '',\n teamName: '',\n });\n\n const [toastOpen, setToastOpen] = useState(false);\n const [toastSeverity, setToastSeverity] = useState<ToastSeverity>('success');\n const [toastMessage, setToastMessage] = useState('');\n const [toastTotalMatches, setToastTotalMatches] = useState<number>(0);\n const [toastMappingCounts, setToastMappingCounts] = useState<MappingCounts>(\n {},\n );\n\n const [autoMatchResults, setAutoMatchResults] = useState<AutoMatchResults>(\n {},\n );\n const [refreshKey, setRefreshKey] = useState(0);\n const hasMatches = Object.keys(autoMatchResults).length > 0;\n const tableKey = `${selectedAccount}-${hasMatches ? `matches-${Object.keys(autoMatchResults).length}` : 'no-matches'}-${refreshKey}`;\n\n const clearMatches = useCallback(() => {\n setAutoMatchResults({});\n }, []);\n\n const setMatches = (results: AutoMatchResults) => {\n setAutoMatchResults(results);\n };\n\n const removeMatch = useCallback((entityName: string) => {\n setAutoMatchResults(prev => {\n const updated = { ...prev };\n delete updated[entityName];\n return updated;\n });\n }, []);\n\n const handleFilterChange = useCallback(\n (key: keyof typeof filters, value: string) => {\n setFilters(prev => ({ ...prev, [key]: value }));\n },\n [],\n );\n\n const handleEditEntity = useCallback((entity: BackstageEntity) => {\n setIsOpen(true);\n setSelectedEntity(entity);\n }, []);\n\n const handleMappingSuccess = useCallback((isUnmapping: boolean) => {\n setToastOpen(true);\n setToastSeverity('info');\n setToastMessage(\n `Mapping ${isUnmapping ? 'removed' : 'created'} successfully. The catalog sync runs approximately every 30 seconds. Please wait a bit and refresh the page to see the updated status.`\n );\n setToastTotalMatches(0);\n setToastMappingCounts({});\n }, []);\n\n const handleRefresh = useCallback(() => {\n setRefreshKey(prev => prev + 1);\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n }, [queryClient]);\n\n const { confirmMappings, isConfirming } = useConfirmMappings({\n autoMatchResults,\n mappingEntities: Object.values(autoMatchResults).map(match => ({\n name: match.entity?.name || '',\n id: match.entity?.entityRef || '',\n namespace: 'default',\n type: 'component',\n system: '',\n owner: match.entity?.owner || '',\n lifecycle: '',\n annotations: {\n 'pagerduty.com/integration-key': '',\n 'pagerduty.com/service-id': match.serviceId,\n },\n })) as FormattedBackstageEntity[],\n onSuccess: (successCount, totalCount, counts) => {\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n clearMatches();\n setToastOpen(true);\n setToastSeverity('success');\n setToastMessage(\n `${successCount} of ${totalCount} mappings saved successfully.`,\n );\n setToastTotalMatches(0);\n setToastMappingCounts(counts);\n },\n onError: errorMessage => {\n setToastOpen(true);\n setToastSeverity('error');\n setToastMessage(errorMessage);\n setToastTotalMatches(0);\n setToastMappingCounts({});\n },\n });\n\n return (\n <>\n <Flex justify=\"end\" gap=\"2\">\n <AutoMappingsButton\n hasMatches={hasMatches}\n onAutoMapping={() => setIsAutoMappingOpen(true)}\n onConfirmMappings={confirmMappings}\n onClearMappings={clearMatches}\n isConfirming={isConfirming}\n />\n\n <ButtonIcon\n icon={<Refresh />}\n aria-label=\"Refresh table\"\n onClick={handleRefresh}\n variant=\"secondary\"\n >\n <Refresh />\n </ButtonIcon>\n\n <ButtonIcon\n icon={<FilterList />}\n aria-label=\"Toggle filters\"\n onClick={() => setShowFilters(!showFilters)}\n variant={showFilters ? 'primary' : 'secondary'}\n >\n <FilterList />\n </ButtonIcon>\n </Flex>\n\n <MappingsTableContent\n key={tableKey}\n autoMatchResults={autoMatchResults}\n hasMatches={hasMatches}\n showFilters={showFilters}\n filters={filters}\n onFilterChange={handleFilterChange}\n onEditEntity={handleEditEntity}\n onRemoveMatch={removeMatch}\n />\n\n <MappingsDialog\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n entity={selectedEntity}\n onMappingSuccess={handleMappingSuccess}\n />\n <AutomaticMappingsDialog\n isOpen={isAutoMappingOpen}\n setIsOpen={setIsAutoMappingOpen}\n onAutoMatchComplete={results => {\n setMatches(results);\n const matchCount = Object.keys(results).length;\n setToastOpen(true);\n setToastSeverity('success');\n setToastMessage(`${matchCount} services mapped successfully.`);\n setToastTotalMatches(matchCount);\n setToastMappingCounts({});\n }}\n />\n <MappingToast\n open={toastOpen}\n severity={toastSeverity}\n message={toastMessage}\n totalMatches={toastTotalMatches}\n mappingCounts={toastMappingCounts}\n onClose={() => setToastOpen(false)}\n />\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MappingsTable.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/MappingsTable.tsx"],"sourcesContent":["import {\n Flex,\n ButtonIcon,\n} from '@backstage/ui';\nimport { useState, useCallback } from 'react';\nimport MappingsDialog from '../MappingsDialog';\nimport AutomaticMappingsDialog from '../AutomaticMappingsDialog';\nimport AutoMappingsButton from './AutoMappingsButton';\nimport { FilterList, Refresh } from '@mui/icons-material';\nimport { BackstageEntity } from '../../types';\nimport MappingToast, { MappingCounts, ToastSeverity } from './MappingToast';\nimport { useConfirmMappings } from './hooks/useConfirmMappings';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { FormattedBackstageEntity } from '@pagerduty/backstage-plugin-common';\nimport { useAccountContext } from '../AccountContext';\nimport MappingsTableContent from './MappingsTableContent';\n\nexport interface AutoMatchResult {\n score: number;\n serviceId: string;\n account: string;\n serviceName: string;\n entity?: {\n name: string;\n entityRef: string;\n owner: string;\n };\n}\n\nexport type AutoMatchResults = Record<string, AutoMatchResult>;\n\nexport default function MappingsTable() {\n const queryClient = useQueryClient();\n const { selectedAccount } = useAccountContext();\n\n const [isOpen, setIsOpen] = useState(false);\n const [isAutoMappingOpen, setIsAutoMappingOpen] = useState(false);\n const [selectedEntity, setSelectedEntity] = useState<BackstageEntity | null>(\n null,\n );\n const [showFilters, setShowFilters] = useState(false);\n\n const [filters, setFilters] = useState({\n name: '',\n serviceName: '',\n status: '',\n teamName: '',\n });\n\n const [toastOpen, setToastOpen] = useState(false);\n const [toastSeverity, setToastSeverity] = useState<ToastSeverity>('success');\n const [toastMessage, setToastMessage] = useState('');\n const [toastTotalMatches, setToastTotalMatches] = useState<number>(0);\n const [toastMappingCounts, setToastMappingCounts] = useState<MappingCounts>(\n {},\n );\n\n const [autoMatchResults, setAutoMatchResults] = useState<AutoMatchResults>(\n {},\n );\n const [refreshKey, setRefreshKey] = useState(0);\n const hasMatches = Object.keys(autoMatchResults).length > 0;\n const tableKey = `${selectedAccount}-${hasMatches ? `matches-${Object.keys(autoMatchResults).length}` : 'no-matches'}-${refreshKey}`;\n\n const clearMatches = useCallback(() => {\n setAutoMatchResults({});\n }, []);\n\n const setMatches = (results: AutoMatchResults) => {\n setAutoMatchResults(results);\n };\n\n const removeMatch = useCallback((entityName: string) => {\n setAutoMatchResults(prev => {\n const updated = { ...prev };\n delete updated[entityName];\n return updated;\n });\n }, []);\n\n const handleFilterChange = useCallback(\n (key: keyof typeof filters, value: string) => {\n setFilters(prev => ({ ...prev, [key]: value }));\n },\n [],\n );\n\n const handleEditEntity = useCallback((entity: BackstageEntity) => {\n setIsOpen(true);\n setSelectedEntity(entity);\n }, []);\n\n const handleMappingSuccess = useCallback((isUnmapping: boolean) => {\n setToastOpen(true);\n setToastSeverity('info');\n setToastMessage(\n `Mapping ${isUnmapping ? 'removed' : 'created'}. The status updates automatically once Backstage re-processes the entity — this can take a few minutes. Refresh the page to check.`\n );\n setToastTotalMatches(0);\n setToastMappingCounts({});\n }, []);\n\n const handleRefresh = useCallback(() => {\n setRefreshKey(prev => prev + 1);\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n }, [queryClient]);\n\n const { confirmMappings, isConfirming } = useConfirmMappings({\n autoMatchResults,\n mappingEntities: Object.values(autoMatchResults).map(match => ({\n name: match.entity?.name || '',\n id: match.entity?.entityRef || '',\n namespace: 'default',\n type: 'component',\n system: '',\n owner: match.entity?.owner || '',\n lifecycle: '',\n annotations: {\n 'pagerduty.com/integration-key': '',\n 'pagerduty.com/service-id': match.serviceId,\n },\n })) as FormattedBackstageEntity[],\n onSuccess: (successCount, totalCount, counts) => {\n queryClient.invalidateQueries({\n queryKey: ['pagerduty', 'enhancedEntityMappings'],\n });\n clearMatches();\n setToastOpen(true);\n setToastSeverity('success');\n setToastMessage(\n `${successCount} of ${totalCount} mappings saved successfully.`,\n );\n setToastTotalMatches(0);\n setToastMappingCounts(counts);\n },\n onError: errorMessage => {\n setToastOpen(true);\n setToastSeverity('error');\n setToastMessage(errorMessage);\n setToastTotalMatches(0);\n setToastMappingCounts({});\n },\n });\n\n return (\n <>\n <Flex justify=\"end\" gap=\"2\">\n <AutoMappingsButton\n hasMatches={hasMatches}\n onAutoMapping={() => setIsAutoMappingOpen(true)}\n onConfirmMappings={confirmMappings}\n onClearMappings={clearMatches}\n isConfirming={isConfirming}\n />\n\n <ButtonIcon\n icon={<Refresh />}\n aria-label=\"Refresh table\"\n onClick={handleRefresh}\n variant=\"secondary\"\n >\n <Refresh />\n </ButtonIcon>\n\n <ButtonIcon\n icon={<FilterList />}\n aria-label=\"Toggle filters\"\n onClick={() => setShowFilters(!showFilters)}\n variant={showFilters ? 'primary' : 'secondary'}\n >\n <FilterList />\n </ButtonIcon>\n </Flex>\n\n <MappingsTableContent\n key={tableKey}\n autoMatchResults={autoMatchResults}\n hasMatches={hasMatches}\n showFilters={showFilters}\n filters={filters}\n onFilterChange={handleFilterChange}\n onEditEntity={handleEditEntity}\n onRemoveMatch={removeMatch}\n />\n\n <MappingsDialog\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n entity={selectedEntity}\n onMappingSuccess={handleMappingSuccess}\n />\n <AutomaticMappingsDialog\n isOpen={isAutoMappingOpen}\n setIsOpen={setIsAutoMappingOpen}\n onAutoMatchComplete={results => {\n setMatches(results);\n const matchCount = Object.keys(results).length;\n setToastOpen(true);\n setToastSeverity('success');\n setToastMessage(`${matchCount} services mapped successfully.`);\n setToastTotalMatches(matchCount);\n setToastMappingCounts({});\n }}\n />\n <MappingToast\n open={toastOpen}\n severity={toastSeverity}\n message={toastMessage}\n totalMatches={toastTotalMatches}\n mappingCounts={toastMappingCounts}\n onClose={() => setToastOpen(false)}\n />\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { useMemo } from 'react';
4
4
  import { useApi } from '@backstage/core-plugin-api';
5
5
  import StatusCell from './StatusCell.esm.js';
6
6
  import { ServiceCell } from './ServiceCell.esm.js';
7
+ import { NameCell } from './NameCell.esm.js';
7
8
  import { Delete, Edit } from '@mui/icons-material';
8
9
  import { FilterRow } from './FilterRow.esm.js';
9
10
  import { TableSkeleton } from './TableSkeleton.esm.js';
@@ -146,7 +147,7 @@ function MappingsTableContent({
146
147
  label: "Name",
147
148
  isRowHeader: true,
148
149
  isSortable: true,
149
- cell: (entity) => /* @__PURE__ */ jsx(CellText, { title: entity.name })
150
+ cell: (entity) => /* @__PURE__ */ jsx(NameCell, { entity })
150
151
  },
151
152
  {
152
153
  id: "team",
@@ -212,11 +213,22 @@ function MappingsTableContent({
212
213
  });
213
214
  return baseColumns;
214
215
  }, [hasMatches, onRemoveMatch, onEditEntity]);
215
- const isInitialLoad = tableProps.loading && (!tableProps.data || tableProps.data.length === 0);
216
+ const isInitialLoad = tableProps.isPending && (!tableProps.data || tableProps.data.length === 0);
216
217
  const hasActiveFilters = showFilters && (!!filters.name || !!filters.serviceName || !!filters.status || !!filters.teamName);
217
218
  return /* @__PURE__ */ jsxs(Fragment, { children: [
218
219
  showFilters && /* @__PURE__ */ jsx(FilterRow, { filters, onFilterChange }),
219
- isInitialLoad ? /* @__PURE__ */ jsx(TableSkeleton, {}) : /* @__PURE__ */ jsx(
220
+ isInitialLoad ? /* @__PURE__ */ jsx(
221
+ TableSkeleton,
222
+ {
223
+ columns: [
224
+ { label: "Name", width: "20%" },
225
+ { label: "Team", width: "20%" },
226
+ { label: "PagerDuty service", width: "20%" },
227
+ { label: "Status", width: "20%" },
228
+ { label: "Actions", width: "20%" }
229
+ ]
230
+ }
231
+ ) : /* @__PURE__ */ jsx(
220
232
  Table,
221
233
  {
222
234
  columnConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"MappingsTableContent.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/MappingsTableContent.tsx"],"sourcesContent":["import {\n Table,\n useTable,\n CellText,\n type ColumnConfig,\n} from '@backstage/ui';\nimport { useMemo } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport StatusCell from './StatusCell';\nimport { ServiceCell } from './ServiceCell';\nimport { Edit, Delete } from '@mui/icons-material';\nimport { FilterRow } from './FilterRow';\nimport { TableSkeleton } from './TableSkeleton';\nimport { EmptyTableState } from './EmptyTableState';\nimport { BackstageEntity } from '../../types';\nimport useDebounce from '../../../hooks/useDebounce';\nimport { pagerDutyApiRef } from '../../../api';\nimport { AutoMatchResults } from './MappingsTable';\nimport { useAccountContext } from '../AccountContext';\n\ninterface MappingsTableContentProps {\n autoMatchResults: AutoMatchResults;\n hasMatches: boolean;\n showFilters: boolean;\n filters: {\n name: string;\n serviceName: string;\n status: string;\n teamName: string;\n };\n onFilterChange: (\n key: 'name' | 'serviceName' | 'status' | 'teamName',\n value: string,\n ) => void;\n onEditEntity: (entity: BackstageEntity) => void;\n onRemoveMatch: (entityName: string) => void;\n}\n\n\nexport default function MappingsTableContent({\n autoMatchResults,\n hasMatches,\n showFilters,\n filters,\n onFilterChange,\n onEditEntity,\n onRemoveMatch,\n}: MappingsTableContentProps) {\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const { selectedAccount } = useAccountContext();\n const debouncedFilters = useDebounce(filters);\n\n const { tableProps } = useTable<BackstageEntity, typeof filters>({\n mode: 'offset',\n filter: debouncedFilters,\n getData: async ({ offset, pageSize, sort, filter }) => {\n if (hasMatches) {\n let matchedEntities: BackstageEntity[] = Object.entries(\n autoMatchResults,\n ).map(([entityName, matchResult]) => {\n const entityRef = matchResult.entity?.entityRef || '';\n const refParts = entityRef.split(':');\n const type = refParts[0] || 'component';\n const namespaceName = refParts[1]?.split('/') || ['default', entityName];\n const namespace = namespaceName[0] || 'default';\n\n return {\n id: entityRef || `${type}:${namespace}/${entityName}`,\n name: entityName,\n namespace: namespace,\n type: type,\n system: '',\n owner: matchResult.entity?.owner || '',\n lifecycle: '',\n annotations: {\n 'pagerduty.com/integration-key': '',\n 'pagerduty.com/service-id': matchResult.serviceId,\n },\n serviceName: matchResult.serviceName,\n serviceUrl: `https://pagerduty.com/services/${matchResult.serviceId}`,\n team: matchResult.entity?.owner || '',\n escalationPolicy: '',\n status: 'AutoMapped' as const,\n account: matchResult.account,\n mappingScore: matchResult.score,\n autoMatchedServiceId: matchResult.serviceId,\n autoMatchedServiceName: matchResult.serviceName,\n } as BackstageEntity;\n });\n\n if (filter) {\n matchedEntities = matchedEntities.filter(entity => {\n if (filter.name && !entity.name.toLowerCase().includes(filter.name.toLowerCase())) {\n return false;\n }\n if (filter.serviceName && entity.serviceName && !entity.serviceName.toLowerCase().includes(filter.serviceName.toLowerCase())) {\n return false;\n }\n if (filter.status && entity.status !== filter.status) {\n return false;\n }\n if (filter.teamName && entity.owner && !entity.owner.toLowerCase().includes(filter.teamName.toLowerCase())) {\n return false;\n }\n return true;\n });\n }\n\n if (sort) {\n matchedEntities.sort((a, b) => {\n let aValue: string | number = '';\n let bValue: string | number = '';\n\n switch (sort.column) {\n case 'name':\n aValue = a.name.toLowerCase();\n bValue = b.name.toLowerCase();\n break;\n case 'team':\n aValue = (a.owner || '').toLowerCase();\n bValue = (b.owner || '').toLowerCase();\n break;\n case 'serviceName':\n aValue = (a.serviceName || '').toLowerCase();\n bValue = (b.serviceName || '').toLowerCase();\n break;\n case 'status':\n aValue = (a.status || '').toLowerCase();\n bValue = (b.status || '').toLowerCase();\n break;\n case 'mappingScore':\n aValue = a.mappingScore ?? 0;\n bValue = b.mappingScore ?? 0;\n break;\n default:\n return 0;\n }\n\n if (aValue < bValue) {\n return sort.direction === 'ascending' ? -1 : 1;\n }\n if (aValue > bValue) {\n return sort.direction === 'ascending' ? 1 : -1;\n }\n return 0;\n });\n }\n\n const start = offset;\n const end = offset + pageSize;\n const paginatedData = matchedEntities.slice(start, end);\n\n return {\n data: paginatedData,\n totalCount: matchedEntities.length,\n };\n }\n const response = await pagerDutyApi.getEntityMappingsWithPagination({\n offset,\n limit: pageSize,\n filters: filter,\n sort: sort\n ? { column: String(sort.column), direction: sort.direction }\n : undefined,\n account: selectedAccount,\n });\n\n return {\n data: response.entities as BackstageEntity[],\n totalCount: response.totalCount,\n };\n },\n paginationOptions: {\n pageSize: 10,\n pageSizeOptions: [10, 25, 50, 100],\n },\n });\n\n const columnConfig: ColumnConfig<BackstageEntity>[] = useMemo(() => {\n const baseColumns: ColumnConfig<BackstageEntity>[] = [\n {\n id: 'name',\n label: 'Name',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <CellText title={entity.name} />,\n },\n {\n id: 'team',\n label: 'Team',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <CellText title={entity.owner} />,\n },\n {\n id: 'serviceName',\n label: 'PagerDuty service',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <ServiceCell entity={entity} />,\n },\n {\n id: 'status',\n label: 'Status',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <StatusCell entity={entity} />,\n },\n ];\n \n if (hasMatches) {\n baseColumns.push({\n id: 'mappingScore',\n label: 'Mapping Score',\n isRowHeader: true,\n isSortable: true,\n cell: entity => (\n <CellText\n title={\n entity.mappingScore !== undefined\n ? `${entity.mappingScore}%`\n : '—'\n }\n />\n ),\n });\n }\n\n baseColumns.push({\n id: 'actions',\n label: 'Actions',\n isRowHeader: true,\n isSortable: false,\n cell: entity => (\n <CellText\n leadingIcon={\n entity.mappingScore !== undefined ? (\n <Delete fontSize=\"small\" />\n ) : (\n <Edit fontSize=\"small\" />\n )\n }\n color=\"secondary\"\n style={{\n paddingLeft: '25px',\n cursor: 'pointer',\n maxWidth: 'min-content',\n }}\n title=\"\"\n onClick={() => {\n if (entity.mappingScore !== undefined) {\n onRemoveMatch(entity.name);\n } else {\n onEditEntity(entity);\n }\n }}\n />\n ),\n });\n\n return baseColumns;\n }, [hasMatches, onRemoveMatch, onEditEntity]);\n\n const isInitialLoad =\n tableProps.loading && (!tableProps.data || tableProps.data.length === 0);\n\n const hasActiveFilters =\n showFilters &&\n (!!filters.name ||\n !!filters.serviceName ||\n !!filters.status ||\n !!filters.teamName);\n\n return (\n <>\n {showFilters && (\n <FilterRow filters={filters} onFilterChange={onFilterChange} />\n )}\n\n {isInitialLoad ? (\n <TableSkeleton />\n ) : (\n <Table\n columnConfig={columnConfig}\n {...tableProps}\n emptyState={<EmptyTableState hasActiveFilters={hasActiveFilters} />}\n />\n )}\n </>\n );\n}"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MappingsTableContent.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/MappingsTableContent.tsx"],"sourcesContent":["import {\n Table,\n useTable,\n CellText,\n type ColumnConfig,\n} from '@backstage/ui';\nimport { useMemo } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport StatusCell from './StatusCell';\nimport { ServiceCell } from './ServiceCell';\nimport { NameCell } from './NameCell';\nimport { Edit, Delete } from '@mui/icons-material';\nimport { FilterRow } from './FilterRow';\nimport { TableSkeleton } from './TableSkeleton';\nimport { EmptyTableState } from './EmptyTableState';\nimport { BackstageEntity } from '../../types';\nimport useDebounce from '../../../hooks/useDebounce';\nimport { pagerDutyApiRef } from '../../../api';\nimport { AutoMatchResults } from './MappingsTable';\nimport { useAccountContext } from '../AccountContext';\n\ninterface MappingsTableContentProps {\n autoMatchResults: AutoMatchResults;\n hasMatches: boolean;\n showFilters: boolean;\n filters: {\n name: string;\n serviceName: string;\n status: string;\n teamName: string;\n };\n onFilterChange: (\n key: 'name' | 'serviceName' | 'status' | 'teamName',\n value: string,\n ) => void;\n onEditEntity: (entity: BackstageEntity) => void;\n onRemoveMatch: (entityName: string) => void;\n}\n\n\nexport default function MappingsTableContent({\n autoMatchResults,\n hasMatches,\n showFilters,\n filters,\n onFilterChange,\n onEditEntity,\n onRemoveMatch,\n}: MappingsTableContentProps) {\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const { selectedAccount } = useAccountContext();\n const debouncedFilters = useDebounce(filters);\n\n const { tableProps } = useTable<BackstageEntity, typeof filters>({\n mode: 'offset',\n filter: debouncedFilters,\n getData: async ({ offset, pageSize, sort, filter }) => {\n if (hasMatches) {\n let matchedEntities: BackstageEntity[] = Object.entries(\n autoMatchResults,\n ).map(([entityName, matchResult]) => {\n const entityRef = matchResult.entity?.entityRef || '';\n const refParts = entityRef.split(':');\n const type = refParts[0] || 'component';\n const namespaceName = refParts[1]?.split('/') || ['default', entityName];\n const namespace = namespaceName[0] || 'default';\n\n return {\n id: entityRef || `${type}:${namespace}/${entityName}`,\n name: entityName,\n namespace: namespace,\n type: type,\n system: '',\n owner: matchResult.entity?.owner || '',\n lifecycle: '',\n annotations: {\n 'pagerduty.com/integration-key': '',\n 'pagerduty.com/service-id': matchResult.serviceId,\n },\n serviceName: matchResult.serviceName,\n serviceUrl: `https://pagerduty.com/services/${matchResult.serviceId}`,\n team: matchResult.entity?.owner || '',\n escalationPolicy: '',\n status: 'AutoMapped' as const,\n account: matchResult.account,\n mappingScore: matchResult.score,\n autoMatchedServiceId: matchResult.serviceId,\n autoMatchedServiceName: matchResult.serviceName,\n } as BackstageEntity;\n });\n\n if (filter) {\n matchedEntities = matchedEntities.filter(entity => {\n if (filter.name && !entity.name.toLowerCase().includes(filter.name.toLowerCase())) {\n return false;\n }\n if (filter.serviceName && entity.serviceName && !entity.serviceName.toLowerCase().includes(filter.serviceName.toLowerCase())) {\n return false;\n }\n if (filter.status && entity.status !== filter.status) {\n return false;\n }\n if (filter.teamName && entity.owner && !entity.owner.toLowerCase().includes(filter.teamName.toLowerCase())) {\n return false;\n }\n return true;\n });\n }\n\n if (sort) {\n matchedEntities.sort((a, b) => {\n let aValue: string | number = '';\n let bValue: string | number = '';\n\n switch (sort.column) {\n case 'name':\n aValue = a.name.toLowerCase();\n bValue = b.name.toLowerCase();\n break;\n case 'team':\n aValue = (a.owner || '').toLowerCase();\n bValue = (b.owner || '').toLowerCase();\n break;\n case 'serviceName':\n aValue = (a.serviceName || '').toLowerCase();\n bValue = (b.serviceName || '').toLowerCase();\n break;\n case 'status':\n aValue = (a.status || '').toLowerCase();\n bValue = (b.status || '').toLowerCase();\n break;\n case 'mappingScore':\n aValue = a.mappingScore ?? 0;\n bValue = b.mappingScore ?? 0;\n break;\n default:\n return 0;\n }\n\n if (aValue < bValue) {\n return sort.direction === 'ascending' ? -1 : 1;\n }\n if (aValue > bValue) {\n return sort.direction === 'ascending' ? 1 : -1;\n }\n return 0;\n });\n }\n\n const start = offset;\n const end = offset + pageSize;\n const paginatedData = matchedEntities.slice(start, end);\n\n return {\n data: paginatedData,\n totalCount: matchedEntities.length,\n };\n }\n const response = await pagerDutyApi.getEntityMappingsWithPagination({\n offset,\n limit: pageSize,\n filters: filter,\n sort: sort\n ? { column: String(sort.column), direction: sort.direction }\n : undefined,\n account: selectedAccount,\n });\n\n return {\n data: response.entities as BackstageEntity[],\n totalCount: response.totalCount,\n };\n },\n paginationOptions: {\n pageSize: 10,\n pageSizeOptions: [10, 25, 50, 100],\n },\n });\n\n const columnConfig: ColumnConfig<BackstageEntity>[] = useMemo(() => {\n const baseColumns: ColumnConfig<BackstageEntity>[] = [\n {\n id: 'name',\n label: 'Name',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <NameCell entity={entity} />,\n },\n {\n id: 'team',\n label: 'Team',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <CellText title={entity.owner} />,\n },\n {\n id: 'serviceName',\n label: 'PagerDuty service',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <ServiceCell entity={entity} />,\n },\n {\n id: 'status',\n label: 'Status',\n isRowHeader: true,\n isSortable: true,\n cell: entity => <StatusCell entity={entity} />,\n },\n ];\n \n if (hasMatches) {\n baseColumns.push({\n id: 'mappingScore',\n label: 'Mapping Score',\n isRowHeader: true,\n isSortable: true,\n cell: entity => (\n <CellText\n title={\n entity.mappingScore !== undefined\n ? `${entity.mappingScore}%`\n : '—'\n }\n />\n ),\n });\n }\n\n baseColumns.push({\n id: 'actions',\n label: 'Actions',\n isRowHeader: true,\n isSortable: false,\n cell: entity => (\n <CellText\n leadingIcon={\n entity.mappingScore !== undefined ? (\n <Delete fontSize=\"small\" />\n ) : (\n <Edit fontSize=\"small\" />\n )\n }\n color=\"secondary\"\n style={{\n paddingLeft: '25px',\n cursor: 'pointer',\n maxWidth: 'min-content',\n }}\n title=\"\"\n onClick={() => {\n if (entity.mappingScore !== undefined) {\n onRemoveMatch(entity.name);\n } else {\n onEditEntity(entity);\n }\n }}\n />\n ),\n });\n\n return baseColumns;\n }, [hasMatches, onRemoveMatch, onEditEntity]);\n\n const isInitialLoad =\n tableProps.isPending && (!tableProps.data || tableProps.data.length === 0);\n\n const hasActiveFilters =\n showFilters &&\n (!!filters.name ||\n !!filters.serviceName ||\n !!filters.status ||\n !!filters.teamName);\n\n return (\n <>\n {showFilters && (\n <FilterRow filters={filters} onFilterChange={onFilterChange} />\n )}\n\n {isInitialLoad ? (\n <TableSkeleton\n columns={[\n { label: 'Name', width: '20%' },\n { label: 'Team', width: '20%' },\n { label: 'PagerDuty service', width: '20%' },\n { label: 'Status', width: '20%' },\n { label: 'Actions', width: '20%' },\n ]}\n />\n ) : (\n <Table\n columnConfig={columnConfig}\n {...tableProps}\n emptyState={<EmptyTableState hasActiveFilters={hasActiveFilters} />}\n />\n )}\n </>\n );\n}"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { CellText, Cell } from '@backstage/ui';
3
+ import { makeStyles } from '@material-ui/core';
4
+ import { Link } from '@backstage/core-components';
5
+ import { DEFAULT_NAMESPACE } from '@backstage/catalog-model';
6
+
7
+ const useStyles = makeStyles((theme) => ({
8
+ link: {
9
+ textDecoration: "underline",
10
+ color: theme.palette.link,
11
+ transition: "color 0.15s",
12
+ "&:hover": {
13
+ opacity: 0.8
14
+ }
15
+ }
16
+ }));
17
+ function entityCatalogPath(entity) {
18
+ if (!entity.type || !entity.name) {
19
+ return void 0;
20
+ }
21
+ const namespace = (entity.namespace || DEFAULT_NAMESPACE).toLowerCase();
22
+ const kind = entity.type.toLowerCase();
23
+ return `/catalog/${namespace}/${kind}/${entity.name}`;
24
+ }
25
+ function NameCell({ entity }) {
26
+ const classes = useStyles();
27
+ const to = entityCatalogPath(entity);
28
+ if (!to) {
29
+ return /* @__PURE__ */ jsx(CellText, { title: entity.name });
30
+ }
31
+ return /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx(Link, { to, className: classes.link, title: entity.name, children: entity.name }) });
32
+ }
33
+
34
+ export { NameCell };
35
+ //# sourceMappingURL=NameCell.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NameCell.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/NameCell.tsx"],"sourcesContent":["import { Cell, CellText } from '@backstage/ui';\nimport { makeStyles } from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\nimport { DEFAULT_NAMESPACE } from '@backstage/catalog-model';\nimport { BackstageEntity } from '../../types';\n\nconst useStyles = makeStyles(theme => ({\n link: {\n textDecoration: 'underline',\n color: theme.palette.link,\n transition: 'color 0.15s',\n '&:hover': {\n opacity: 0.8,\n },\n },\n}));\n\ntype NameCellProps = {\n entity: BackstageEntity;\n};\n\nfunction entityCatalogPath(entity: BackstageEntity): string | undefined {\n if (!entity.type || !entity.name) {\n return undefined;\n }\n\n const namespace = (entity.namespace || DEFAULT_NAMESPACE).toLowerCase();\n const kind = entity.type.toLowerCase();\n\n return `/catalog/${namespace}/${kind}/${entity.name}`;\n}\n\nexport function NameCell({ entity }: NameCellProps) {\n const classes = useStyles();\n const to = entityCatalogPath(entity);\n\n if (!to) {\n return <CellText title={entity.name} />;\n }\n\n // Render the link via core-components' Link (react-router-aware) instead of\n // CellText's href, which emits a plain <a> and triggers a full page reload.\n return (\n <Cell>\n <Link to={to} className={classes.link} title={entity.name}>\n {entity.name}\n </Link>\n </Cell>\n );\n}\n"],"names":[],"mappings":";;;;;;AAMA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,cAAA,EAAgB,WAAA;AAAA,IAChB,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA;AAAA,IACrB,UAAA,EAAY,aAAA;AAAA,IACZ,SAAA,EAAW;AAAA,MACT,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA,CAAE,CAAA;AAMF,SAAS,kBAAkB,MAAA,EAA6C;AACtE,EAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,CAAC,OAAO,IAAA,EAAM;AAChC,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAA,CAAa,MAAA,CAAO,SAAA,IAAa,iBAAA,EAAmB,WAAA,EAAY;AACtE,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,WAAA,EAAY;AAErC,EAAA,OAAO,YAAY,SAAS,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,OAAO,IAAI,CAAA,CAAA;AACrD;AAEO,SAAS,QAAA,CAAS,EAAE,MAAA,EAAO,EAAkB;AAClD,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,EAAA,GAAK,kBAAkB,MAAM,CAAA;AAEnC,EAAA,IAAI,CAAC,EAAA,EAAI;AACP,IAAA,uBAAO,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,CAAA;AAAA,EACvC;AAIA,EAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,CAAO,IAAA,EAClD,QAAA,EAAA,MAAA,CAAO,MACV,CAAA,EACF,CAAA;AAEJ;;;;"}