@pagerduty/backstage-plugin 0.18.0 → 0.19.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.
- package/CHANGELOG.md +11 -0
- package/dist/alpha/api.esm.js.map +1 -1
- package/dist/api/client.esm.js +91 -2
- package/dist/api/client.esm.js.map +1 -1
- package/dist/components/PagerDutyPage/AccountContext.esm.js +56 -0
- package/dist/components/PagerDutyPage/AccountContext.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/AutomaticMappingsDialog.esm.js +197 -0
- package/dist/components/PagerDutyPage/AutomaticMappingsDialog.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsDialog.esm.js +242 -0
- package/dist/components/PagerDutyPage/MappingsDialog.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/AutoMappingsButton.esm.js +74 -0
- package/dist/components/PagerDutyPage/MappingsTable/AutoMappingsButton.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/EmptyTableState.esm.js +26 -0
- package/dist/components/PagerDutyPage/MappingsTable/EmptyTableState.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/FilterRow.esm.js +67 -0
- package/dist/components/PagerDutyPage/MappingsTable/FilterRow.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingToast.esm.js +69 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingToast.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingsTable.esm.js +202 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingsTable.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingsTableContent.esm.js +231 -0
- package/dist/components/PagerDutyPage/MappingsTable/MappingsTableContent.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/ServiceCell.esm.js +31 -0
- package/dist/components/PagerDutyPage/MappingsTable/ServiceCell.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/StatusCell.esm.js +112 -0
- package/dist/components/PagerDutyPage/MappingsTable/StatusCell.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/TableSkeleton.esm.js +50 -0
- package/dist/components/PagerDutyPage/MappingsTable/TableSkeleton.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/MappingsTable/hooks/useConfirmMappings.esm.js +70 -0
- package/dist/components/PagerDutyPage/MappingsTable/hooks/useConfirmMappings.esm.js.map +1 -0
- package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js +67 -44
- package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js.map +1 -1
- package/dist/components/PagerDutyPage/index.esm.js +27 -12
- package/dist/components/PagerDutyPage/index.esm.js.map +1 -1
- package/dist/components/TriggerButton/index.esm.js +1 -1
- package/dist/components/TriggerButton/index.esm.js.map +1 -1
- package/dist/hooks/useDebounce.esm.js +13 -0
- package/dist/hooks/useDebounce.esm.js.map +1 -0
- package/dist/hooks/{index.esm.js → usePagerDutyEntity.esm.js} +1 -1
- package/dist/hooks/usePagerDutyEntity.esm.js.map +1 -0
- package/dist/index.d.ts +96 -4
- package/dist/package.json.esm.js +1 -1
- package/package.json +13 -13
- package/dist/components/PagerDutyPage/MappingTable.esm.js +0 -282
- package/dist/components/PagerDutyPage/MappingTable.esm.js.map +0 -1
- package/dist/hooks/index.esm.js.map +0 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Flex, ButtonIcon } from '@backstage/ui';
|
|
3
|
+
import { useState, useCallback } from 'react';
|
|
4
|
+
import MappingsDialog from '../MappingsDialog.esm.js';
|
|
5
|
+
import AutomaticMappingsDialog from '../AutomaticMappingsDialog.esm.js';
|
|
6
|
+
import AutoMappingsButton from './AutoMappingsButton.esm.js';
|
|
7
|
+
import { Refresh, FilterList } from '@mui/icons-material';
|
|
8
|
+
import MappingToast from './MappingToast.esm.js';
|
|
9
|
+
import { useConfirmMappings } from './hooks/useConfirmMappings.esm.js';
|
|
10
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
11
|
+
import { useAccountContext } from '../AccountContext.esm.js';
|
|
12
|
+
import MappingsTableContent from './MappingsTableContent.esm.js';
|
|
13
|
+
|
|
14
|
+
function MappingsTable() {
|
|
15
|
+
const queryClient = useQueryClient();
|
|
16
|
+
const { selectedAccount } = useAccountContext();
|
|
17
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
18
|
+
const [isAutoMappingOpen, setIsAutoMappingOpen] = useState(false);
|
|
19
|
+
const [selectedEntity, setSelectedEntity] = useState(
|
|
20
|
+
null
|
|
21
|
+
);
|
|
22
|
+
const [showFilters, setShowFilters] = useState(false);
|
|
23
|
+
const [filters, setFilters] = useState({
|
|
24
|
+
name: "",
|
|
25
|
+
serviceName: "",
|
|
26
|
+
status: "",
|
|
27
|
+
teamName: ""
|
|
28
|
+
});
|
|
29
|
+
const [toastOpen, setToastOpen] = useState(false);
|
|
30
|
+
const [toastSeverity, setToastSeverity] = useState("success");
|
|
31
|
+
const [toastMessage, setToastMessage] = useState("");
|
|
32
|
+
const [toastTotalMatches, setToastTotalMatches] = useState(0);
|
|
33
|
+
const [toastMappingCounts, setToastMappingCounts] = useState(
|
|
34
|
+
{}
|
|
35
|
+
);
|
|
36
|
+
const [autoMatchResults, setAutoMatchResults] = useState(
|
|
37
|
+
{}
|
|
38
|
+
);
|
|
39
|
+
const [refreshKey, setRefreshKey] = useState(0);
|
|
40
|
+
const hasMatches = Object.keys(autoMatchResults).length > 0;
|
|
41
|
+
const tableKey = `${selectedAccount}-${hasMatches ? `matches-${Object.keys(autoMatchResults).length}` : "no-matches"}-${refreshKey}`;
|
|
42
|
+
const clearMatches = useCallback(() => {
|
|
43
|
+
setAutoMatchResults({});
|
|
44
|
+
}, []);
|
|
45
|
+
const setMatches = (results) => {
|
|
46
|
+
setAutoMatchResults(results);
|
|
47
|
+
};
|
|
48
|
+
const removeMatch = useCallback((entityName) => {
|
|
49
|
+
setAutoMatchResults((prev) => {
|
|
50
|
+
const updated = { ...prev };
|
|
51
|
+
delete updated[entityName];
|
|
52
|
+
return updated;
|
|
53
|
+
});
|
|
54
|
+
}, []);
|
|
55
|
+
const handleFilterChange = useCallback(
|
|
56
|
+
(key, value) => {
|
|
57
|
+
setFilters((prev) => ({ ...prev, [key]: value }));
|
|
58
|
+
},
|
|
59
|
+
[]
|
|
60
|
+
);
|
|
61
|
+
const handleEditEntity = useCallback((entity) => {
|
|
62
|
+
setIsOpen(true);
|
|
63
|
+
setSelectedEntity(entity);
|
|
64
|
+
}, []);
|
|
65
|
+
const handleMappingSuccess = useCallback((isUnmapping) => {
|
|
66
|
+
setToastOpen(true);
|
|
67
|
+
setToastSeverity("info");
|
|
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.`
|
|
70
|
+
);
|
|
71
|
+
setToastTotalMatches(0);
|
|
72
|
+
setToastMappingCounts({});
|
|
73
|
+
}, []);
|
|
74
|
+
const handleRefresh = useCallback(() => {
|
|
75
|
+
setRefreshKey((prev) => prev + 1);
|
|
76
|
+
queryClient.invalidateQueries({
|
|
77
|
+
queryKey: ["pagerduty", "enhancedEntityMappings"]
|
|
78
|
+
});
|
|
79
|
+
}, [queryClient]);
|
|
80
|
+
const { confirmMappings, isConfirming } = useConfirmMappings({
|
|
81
|
+
autoMatchResults,
|
|
82
|
+
mappingEntities: Object.values(autoMatchResults).map((match) => ({
|
|
83
|
+
name: match.entity?.name || "",
|
|
84
|
+
id: match.entity?.entityRef || "",
|
|
85
|
+
namespace: "default",
|
|
86
|
+
type: "component",
|
|
87
|
+
system: "",
|
|
88
|
+
owner: match.entity?.owner || "",
|
|
89
|
+
lifecycle: "",
|
|
90
|
+
annotations: {
|
|
91
|
+
"pagerduty.com/integration-key": "",
|
|
92
|
+
"pagerduty.com/service-id": match.serviceId
|
|
93
|
+
}
|
|
94
|
+
})),
|
|
95
|
+
onSuccess: (successCount, totalCount, counts) => {
|
|
96
|
+
queryClient.invalidateQueries({
|
|
97
|
+
queryKey: ["pagerduty", "enhancedEntityMappings"]
|
|
98
|
+
});
|
|
99
|
+
clearMatches();
|
|
100
|
+
setToastOpen(true);
|
|
101
|
+
setToastSeverity("success");
|
|
102
|
+
setToastMessage(
|
|
103
|
+
`${successCount} of ${totalCount} mappings saved successfully.`
|
|
104
|
+
);
|
|
105
|
+
setToastTotalMatches(0);
|
|
106
|
+
setToastMappingCounts(counts);
|
|
107
|
+
},
|
|
108
|
+
onError: (errorMessage) => {
|
|
109
|
+
setToastOpen(true);
|
|
110
|
+
setToastSeverity("error");
|
|
111
|
+
setToastMessage(errorMessage);
|
|
112
|
+
setToastTotalMatches(0);
|
|
113
|
+
setToastMappingCounts({});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
117
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "end", gap: "2", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(
|
|
119
|
+
AutoMappingsButton,
|
|
120
|
+
{
|
|
121
|
+
hasMatches,
|
|
122
|
+
onAutoMapping: () => setIsAutoMappingOpen(true),
|
|
123
|
+
onConfirmMappings: confirmMappings,
|
|
124
|
+
onClearMappings: clearMatches,
|
|
125
|
+
isConfirming
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx(
|
|
129
|
+
ButtonIcon,
|
|
130
|
+
{
|
|
131
|
+
icon: /* @__PURE__ */ jsx(Refresh, {}),
|
|
132
|
+
"aria-label": "Refresh table",
|
|
133
|
+
onClick: handleRefresh,
|
|
134
|
+
variant: "secondary",
|
|
135
|
+
children: /* @__PURE__ */ jsx(Refresh, {})
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsx(
|
|
139
|
+
ButtonIcon,
|
|
140
|
+
{
|
|
141
|
+
icon: /* @__PURE__ */ jsx(FilterList, {}),
|
|
142
|
+
"aria-label": "Toggle filters",
|
|
143
|
+
onClick: () => setShowFilters(!showFilters),
|
|
144
|
+
variant: showFilters ? "primary" : "secondary",
|
|
145
|
+
children: /* @__PURE__ */ jsx(FilterList, {})
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
] }),
|
|
149
|
+
/* @__PURE__ */ jsx(
|
|
150
|
+
MappingsTableContent,
|
|
151
|
+
{
|
|
152
|
+
autoMatchResults,
|
|
153
|
+
hasMatches,
|
|
154
|
+
showFilters,
|
|
155
|
+
filters,
|
|
156
|
+
onFilterChange: handleFilterChange,
|
|
157
|
+
onEditEntity: handleEditEntity,
|
|
158
|
+
onRemoveMatch: removeMatch
|
|
159
|
+
},
|
|
160
|
+
tableKey
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsx(
|
|
163
|
+
MappingsDialog,
|
|
164
|
+
{
|
|
165
|
+
isOpen,
|
|
166
|
+
setIsOpen,
|
|
167
|
+
entity: selectedEntity,
|
|
168
|
+
onMappingSuccess: handleMappingSuccess
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
/* @__PURE__ */ jsx(
|
|
172
|
+
AutomaticMappingsDialog,
|
|
173
|
+
{
|
|
174
|
+
isOpen: isAutoMappingOpen,
|
|
175
|
+
setIsOpen: setIsAutoMappingOpen,
|
|
176
|
+
onAutoMatchComplete: (results) => {
|
|
177
|
+
setMatches(results);
|
|
178
|
+
const matchCount = Object.keys(results).length;
|
|
179
|
+
setToastOpen(true);
|
|
180
|
+
setToastSeverity("success");
|
|
181
|
+
setToastMessage(`${matchCount} services mapped successfully.`);
|
|
182
|
+
setToastTotalMatches(matchCount);
|
|
183
|
+
setToastMappingCounts({});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
),
|
|
187
|
+
/* @__PURE__ */ jsx(
|
|
188
|
+
MappingToast,
|
|
189
|
+
{
|
|
190
|
+
open: toastOpen,
|
|
191
|
+
severity: toastSeverity,
|
|
192
|
+
message: toastMessage,
|
|
193
|
+
totalMatches: toastTotalMatches,
|
|
194
|
+
mappingCounts: toastMappingCounts,
|
|
195
|
+
onClose: () => setToastOpen(false)
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
] });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { MappingsTable as default };
|
|
202
|
+
//# sourceMappingURL=MappingsTable.esm.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useTable, CellText, Table } from '@backstage/ui';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
5
|
+
import StatusCell from './StatusCell.esm.js';
|
|
6
|
+
import { ServiceCell } from './ServiceCell.esm.js';
|
|
7
|
+
import { Delete, Edit } from '@mui/icons-material';
|
|
8
|
+
import { FilterRow } from './FilterRow.esm.js';
|
|
9
|
+
import { TableSkeleton } from './TableSkeleton.esm.js';
|
|
10
|
+
import { EmptyTableState } from './EmptyTableState.esm.js';
|
|
11
|
+
import useDebounce from '../../../hooks/useDebounce.esm.js';
|
|
12
|
+
import { pagerDutyApiRef } from '../../../api/client.esm.js';
|
|
13
|
+
import { useAccountContext } from '../AccountContext.esm.js';
|
|
14
|
+
|
|
15
|
+
function MappingsTableContent({
|
|
16
|
+
autoMatchResults,
|
|
17
|
+
hasMatches,
|
|
18
|
+
showFilters,
|
|
19
|
+
filters,
|
|
20
|
+
onFilterChange,
|
|
21
|
+
onEditEntity,
|
|
22
|
+
onRemoveMatch
|
|
23
|
+
}) {
|
|
24
|
+
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
25
|
+
const { selectedAccount } = useAccountContext();
|
|
26
|
+
const debouncedFilters = useDebounce(filters);
|
|
27
|
+
const { tableProps } = useTable({
|
|
28
|
+
mode: "offset",
|
|
29
|
+
filter: debouncedFilters,
|
|
30
|
+
getData: async ({ offset, pageSize, sort, filter }) => {
|
|
31
|
+
if (hasMatches) {
|
|
32
|
+
let matchedEntities = Object.entries(
|
|
33
|
+
autoMatchResults
|
|
34
|
+
).map(([entityName, matchResult]) => {
|
|
35
|
+
const entityRef = matchResult.entity?.entityRef || "";
|
|
36
|
+
const refParts = entityRef.split(":");
|
|
37
|
+
const type = refParts[0] || "component";
|
|
38
|
+
const namespaceName = refParts[1]?.split("/") || ["default", entityName];
|
|
39
|
+
const namespace = namespaceName[0] || "default";
|
|
40
|
+
return {
|
|
41
|
+
id: entityRef || `${type}:${namespace}/${entityName}`,
|
|
42
|
+
name: entityName,
|
|
43
|
+
namespace,
|
|
44
|
+
type,
|
|
45
|
+
system: "",
|
|
46
|
+
owner: matchResult.entity?.owner || "",
|
|
47
|
+
lifecycle: "",
|
|
48
|
+
annotations: {
|
|
49
|
+
"pagerduty.com/integration-key": "",
|
|
50
|
+
"pagerduty.com/service-id": matchResult.serviceId
|
|
51
|
+
},
|
|
52
|
+
serviceName: matchResult.serviceName,
|
|
53
|
+
serviceUrl: `https://pagerduty.com/services/${matchResult.serviceId}`,
|
|
54
|
+
team: matchResult.entity?.owner || "",
|
|
55
|
+
escalationPolicy: "",
|
|
56
|
+
status: "AutoMapped",
|
|
57
|
+
account: matchResult.account,
|
|
58
|
+
mappingScore: matchResult.score,
|
|
59
|
+
autoMatchedServiceId: matchResult.serviceId,
|
|
60
|
+
autoMatchedServiceName: matchResult.serviceName
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
if (filter) {
|
|
64
|
+
matchedEntities = matchedEntities.filter((entity) => {
|
|
65
|
+
if (filter.name && !entity.name.toLowerCase().includes(filter.name.toLowerCase())) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (filter.serviceName && entity.serviceName && !entity.serviceName.toLowerCase().includes(filter.serviceName.toLowerCase())) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (filter.status && entity.status !== filter.status) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (filter.teamName && entity.owner && !entity.owner.toLowerCase().includes(filter.teamName.toLowerCase())) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (sort) {
|
|
81
|
+
matchedEntities.sort((a, b) => {
|
|
82
|
+
let aValue = "";
|
|
83
|
+
let bValue = "";
|
|
84
|
+
switch (sort.column) {
|
|
85
|
+
case "name":
|
|
86
|
+
aValue = a.name.toLowerCase();
|
|
87
|
+
bValue = b.name.toLowerCase();
|
|
88
|
+
break;
|
|
89
|
+
case "team":
|
|
90
|
+
aValue = (a.owner || "").toLowerCase();
|
|
91
|
+
bValue = (b.owner || "").toLowerCase();
|
|
92
|
+
break;
|
|
93
|
+
case "serviceName":
|
|
94
|
+
aValue = (a.serviceName || "").toLowerCase();
|
|
95
|
+
bValue = (b.serviceName || "").toLowerCase();
|
|
96
|
+
break;
|
|
97
|
+
case "status":
|
|
98
|
+
aValue = (a.status || "").toLowerCase();
|
|
99
|
+
bValue = (b.status || "").toLowerCase();
|
|
100
|
+
break;
|
|
101
|
+
case "mappingScore":
|
|
102
|
+
aValue = a.mappingScore ?? 0;
|
|
103
|
+
bValue = b.mappingScore ?? 0;
|
|
104
|
+
break;
|
|
105
|
+
default:
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
if (aValue < bValue) {
|
|
109
|
+
return sort.direction === "ascending" ? -1 : 1;
|
|
110
|
+
}
|
|
111
|
+
if (aValue > bValue) {
|
|
112
|
+
return sort.direction === "ascending" ? 1 : -1;
|
|
113
|
+
}
|
|
114
|
+
return 0;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const start = offset;
|
|
118
|
+
const end = offset + pageSize;
|
|
119
|
+
const paginatedData = matchedEntities.slice(start, end);
|
|
120
|
+
return {
|
|
121
|
+
data: paginatedData,
|
|
122
|
+
totalCount: matchedEntities.length
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const response = await pagerDutyApi.getEntityMappingsWithPagination({
|
|
126
|
+
offset,
|
|
127
|
+
limit: pageSize,
|
|
128
|
+
filters: filter,
|
|
129
|
+
sort: sort ? { column: String(sort.column), direction: sort.direction } : void 0,
|
|
130
|
+
account: selectedAccount
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
data: response.entities,
|
|
134
|
+
totalCount: response.totalCount
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
paginationOptions: {
|
|
138
|
+
pageSize: 10,
|
|
139
|
+
pageSizeOptions: [10, 25, 50, 100]
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
const columnConfig = useMemo(() => {
|
|
143
|
+
const baseColumns = [
|
|
144
|
+
{
|
|
145
|
+
id: "name",
|
|
146
|
+
label: "Name",
|
|
147
|
+
isRowHeader: true,
|
|
148
|
+
isSortable: true,
|
|
149
|
+
cell: (entity) => /* @__PURE__ */ jsx(CellText, { title: entity.name })
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: "team",
|
|
153
|
+
label: "Team",
|
|
154
|
+
isRowHeader: true,
|
|
155
|
+
isSortable: true,
|
|
156
|
+
cell: (entity) => /* @__PURE__ */ jsx(CellText, { title: entity.owner })
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "serviceName",
|
|
160
|
+
label: "PagerDuty service",
|
|
161
|
+
isRowHeader: true,
|
|
162
|
+
isSortable: true,
|
|
163
|
+
cell: (entity) => /* @__PURE__ */ jsx(ServiceCell, { entity })
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: "status",
|
|
167
|
+
label: "Status",
|
|
168
|
+
isRowHeader: true,
|
|
169
|
+
isSortable: true,
|
|
170
|
+
cell: (entity) => /* @__PURE__ */ jsx(StatusCell, { entity })
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
if (hasMatches) {
|
|
174
|
+
baseColumns.push({
|
|
175
|
+
id: "mappingScore",
|
|
176
|
+
label: "Mapping Score",
|
|
177
|
+
isRowHeader: true,
|
|
178
|
+
isSortable: true,
|
|
179
|
+
cell: (entity) => /* @__PURE__ */ jsx(
|
|
180
|
+
CellText,
|
|
181
|
+
{
|
|
182
|
+
title: entity.mappingScore !== void 0 ? `${entity.mappingScore}%` : "\u2014"
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
baseColumns.push({
|
|
188
|
+
id: "actions",
|
|
189
|
+
label: "Actions",
|
|
190
|
+
isRowHeader: true,
|
|
191
|
+
isSortable: false,
|
|
192
|
+
cell: (entity) => /* @__PURE__ */ jsx(
|
|
193
|
+
CellText,
|
|
194
|
+
{
|
|
195
|
+
leadingIcon: entity.mappingScore !== void 0 ? /* @__PURE__ */ jsx(Delete, { fontSize: "small" }) : /* @__PURE__ */ jsx(Edit, { fontSize: "small" }),
|
|
196
|
+
color: "secondary",
|
|
197
|
+
style: {
|
|
198
|
+
paddingLeft: "25px",
|
|
199
|
+
cursor: "pointer",
|
|
200
|
+
maxWidth: "min-content"
|
|
201
|
+
},
|
|
202
|
+
title: "",
|
|
203
|
+
onClick: () => {
|
|
204
|
+
if (entity.mappingScore !== void 0) {
|
|
205
|
+
onRemoveMatch(entity.name);
|
|
206
|
+
} else {
|
|
207
|
+
onEditEntity(entity);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
});
|
|
213
|
+
return baseColumns;
|
|
214
|
+
}, [hasMatches, onRemoveMatch, onEditEntity]);
|
|
215
|
+
const isInitialLoad = tableProps.loading && (!tableProps.data || tableProps.data.length === 0);
|
|
216
|
+
const hasActiveFilters = showFilters && (!!filters.name || !!filters.serviceName || !!filters.status || !!filters.teamName);
|
|
217
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
218
|
+
showFilters && /* @__PURE__ */ jsx(FilterRow, { filters, onFilterChange }),
|
|
219
|
+
isInitialLoad ? /* @__PURE__ */ jsx(TableSkeleton, {}) : /* @__PURE__ */ jsx(
|
|
220
|
+
Table,
|
|
221
|
+
{
|
|
222
|
+
columnConfig,
|
|
223
|
+
...tableProps,
|
|
224
|
+
emptyState: /* @__PURE__ */ jsx(EmptyTableState, { hasActiveFilters })
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] });
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export { MappingsTableContent as default };
|
|
231
|
+
//# sourceMappingURL=MappingsTableContent.esm.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { CellText } from '@backstage/ui';
|
|
3
|
+
import { makeStyles } from '@material-ui/core';
|
|
4
|
+
|
|
5
|
+
const useStyles = makeStyles((theme) => ({
|
|
6
|
+
underlinedCell: {
|
|
7
|
+
"& .bui-Text": {
|
|
8
|
+
textDecoration: "underline",
|
|
9
|
+
color: theme.palette.link,
|
|
10
|
+
transition: "color 0.15s",
|
|
11
|
+
"&:hover": {
|
|
12
|
+
opacity: 0.8
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
17
|
+
function ServiceCell({ entity }) {
|
|
18
|
+
const classes = useStyles();
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
CellText,
|
|
21
|
+
{
|
|
22
|
+
color: "secondary",
|
|
23
|
+
className: classes.underlinedCell,
|
|
24
|
+
title: entity.serviceName ?? "",
|
|
25
|
+
href: entity.serviceUrl
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { ServiceCell };
|
|
31
|
+
//# sourceMappingURL=ServiceCell.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServiceCell.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/ServiceCell.tsx"],"sourcesContent":["import { CellText } from '@backstage/ui';\nimport { makeStyles } from '@material-ui/core';\nimport { BackstageEntity } from '../../types';\n\nconst useStyles = makeStyles(theme => ({\n underlinedCell: {\n '& .bui-Text': {\n textDecoration: 'underline',\n color: theme.palette.link,\n transition: 'color 0.15s',\n '&:hover': {\n opacity: 0.8,\n },\n },\n },\n}));\n\ntype ServiceCellProps = {\n entity: BackstageEntity;\n};\n\nexport function ServiceCell({ entity }: ServiceCellProps) {\n const classes = useStyles();\n\n return (\n <CellText\n color=\"secondary\"\n className={classes.underlinedCell}\n title={entity.serviceName ?? ''}\n href={entity.serviceUrl}\n />\n );\n}\n"],"names":[],"mappings":";;;;AAIA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,cAAA,EAAgB;AAAA,IACd,aAAA,EAAe;AAAA,MACb,cAAA,EAAgB,WAAA;AAAA,MAChB,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA;AAAA,MACrB,UAAA,EAAY,aAAA;AAAA,MACZ,SAAA,EAAW;AAAA,QACT,OAAA,EAAS;AAAA;AACX;AACF;AAEJ,CAAA,CAAE,CAAA;AAMK,SAAS,WAAA,CAAY,EAAE,MAAA,EAAO,EAAqB;AACxD,EAAA,MAAM,UAAU,SAAA,EAAU;AAE1B,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,WAAA;AAAA,MACN,WAAW,OAAA,CAAQ,cAAA;AAAA,MACnB,KAAA,EAAO,OAAO,WAAA,IAAe,EAAA;AAAA,MAC7B,MAAM,MAAA,CAAO;AAAA;AAAA,GACf;AAEJ;;;;"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { CellText } from '@backstage/ui';
|
|
3
|
+
import { useTheme, makeStyles } from '@material-ui/core';
|
|
4
|
+
|
|
5
|
+
const statusDictionary = {
|
|
6
|
+
InSync: "In Sync",
|
|
7
|
+
OutOfSync: "Out of Sync",
|
|
8
|
+
NotMapped: "Not Mapped",
|
|
9
|
+
AutoMapped: "Auto Mapped",
|
|
10
|
+
ErrorWhenFetchingService: "Error occured while fetching service"
|
|
11
|
+
};
|
|
12
|
+
function getStatusName(status) {
|
|
13
|
+
return statusDictionary[status] || "Refresh to Update";
|
|
14
|
+
}
|
|
15
|
+
function getStatusColors(status, isDarkTheme) {
|
|
16
|
+
const statusKey = status;
|
|
17
|
+
if (isDarkTheme) {
|
|
18
|
+
const darkColors = {
|
|
19
|
+
InSync: {
|
|
20
|
+
color: "#4CAF50",
|
|
21
|
+
backgroundColor: "rgba(76, 175, 80, 0.15)",
|
|
22
|
+
borderColor: "rgba(76, 175, 80, 0.4)"
|
|
23
|
+
},
|
|
24
|
+
OutOfSync: {
|
|
25
|
+
color: "#f44336",
|
|
26
|
+
backgroundColor: "rgba(244, 67, 54, 0.15)",
|
|
27
|
+
borderColor: "rgba(244, 67, 54, 0.4)"
|
|
28
|
+
},
|
|
29
|
+
NotMapped: {
|
|
30
|
+
color: "#FFA726",
|
|
31
|
+
backgroundColor: "rgba(255, 167, 38, 0.15)",
|
|
32
|
+
borderColor: "rgba(255, 167, 38, 0.4)"
|
|
33
|
+
},
|
|
34
|
+
AutoMapped: {
|
|
35
|
+
color: "#42A5F5",
|
|
36
|
+
backgroundColor: "rgba(66, 165, 245, 0.15)",
|
|
37
|
+
borderColor: "rgba(66, 165, 245, 0.4)"
|
|
38
|
+
},
|
|
39
|
+
ErrorWhenFetchingService: {
|
|
40
|
+
color: "#f44336",
|
|
41
|
+
backgroundColor: "rgba(244, 67, 54, 0.15)",
|
|
42
|
+
borderColor: "rgba(244, 67, 54, 0.4)"
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return darkColors[statusKey] || {
|
|
46
|
+
color: "#999",
|
|
47
|
+
backgroundColor: "rgba(153, 153, 153, 0.15)",
|
|
48
|
+
borderColor: "rgba(153, 153, 153, 0.4)"
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const lightColors = {
|
|
52
|
+
InSync: {
|
|
53
|
+
color: "#00875A",
|
|
54
|
+
backgroundColor: "#E3FCEF",
|
|
55
|
+
borderColor: "#57D9A3"
|
|
56
|
+
},
|
|
57
|
+
OutOfSync: {
|
|
58
|
+
color: "#fff",
|
|
59
|
+
backgroundColor: "red",
|
|
60
|
+
borderColor: "red"
|
|
61
|
+
},
|
|
62
|
+
NotMapped: {
|
|
63
|
+
color: "#B88A00",
|
|
64
|
+
backgroundColor: "#FFF8E6",
|
|
65
|
+
borderColor: "#E8C547"
|
|
66
|
+
},
|
|
67
|
+
AutoMapped: {
|
|
68
|
+
color: "#1565C0",
|
|
69
|
+
backgroundColor: "#E3F2FD",
|
|
70
|
+
borderColor: "#64B5F6"
|
|
71
|
+
},
|
|
72
|
+
ErrorWhenFetchingService: {
|
|
73
|
+
color: "#fff",
|
|
74
|
+
backgroundColor: "red",
|
|
75
|
+
borderColor: "red"
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return lightColors[statusKey] || {
|
|
79
|
+
color: "gray",
|
|
80
|
+
backgroundColor: "#f0f0f0",
|
|
81
|
+
borderColor: "gray"
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const useStyles = makeStyles(() => {
|
|
85
|
+
return {
|
|
86
|
+
pill: (props) => ({
|
|
87
|
+
"& .bui-Text": {
|
|
88
|
+
backgroundColor: props.backgroundColor,
|
|
89
|
+
borderRadius: "4px",
|
|
90
|
+
color: props.color,
|
|
91
|
+
padding: "4px 12px",
|
|
92
|
+
maxWidth: "min-content",
|
|
93
|
+
fontSize: "12px",
|
|
94
|
+
fontWeight: 500,
|
|
95
|
+
border: `1px solid ${props.borderColor}`,
|
|
96
|
+
display: "inline-block"
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
function StatusCell({ entity }) {
|
|
102
|
+
const theme = useTheme();
|
|
103
|
+
const isDarkTheme = theme.palette.type === "dark";
|
|
104
|
+
const statusValue = entity.status || "NotMapped";
|
|
105
|
+
const { color, backgroundColor, borderColor } = getStatusColors(statusValue, isDarkTheme);
|
|
106
|
+
const classes = useStyles({ color, backgroundColor, borderColor });
|
|
107
|
+
const statusName = getStatusName(statusValue);
|
|
108
|
+
return /* @__PURE__ */ jsx(CellText, { title: statusName, className: classes.pill });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { StatusCell as default };
|
|
112
|
+
//# sourceMappingURL=StatusCell.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusCell.esm.js","sources":["../../../../src/components/PagerDutyPage/MappingsTable/StatusCell.tsx"],"sourcesContent":["import { CellText } from '@backstage/ui';\nimport { makeStyles, useTheme } from '@material-ui/core';\nimport { BackstageTheme } from '@backstage/theme';\nimport { BackstageEntity } from '../../types';\n\nconst statusDictionary = {\n InSync: 'In Sync',\n OutOfSync: 'Out of Sync',\n NotMapped: 'Not Mapped',\n AutoMapped: 'Auto Mapped',\n ErrorWhenFetchingService: 'Error occured while fetching service',\n} as const;\n\ntype StatusKey = keyof typeof statusDictionary;\n\nfunction getStatusName(status: string) {\n return statusDictionary[status as StatusKey] || 'Refresh to Update';\n}\n\nfunction getStatusColors(status: string, isDarkTheme: boolean) {\n const statusKey = status as StatusKey;\n\n if (isDarkTheme) {\n const darkColors = {\n InSync: {\n color: '#4CAF50',\n backgroundColor: 'rgba(76, 175, 80, 0.15)',\n borderColor: 'rgba(76, 175, 80, 0.4)',\n },\n OutOfSync: {\n color: '#f44336',\n backgroundColor: 'rgba(244, 67, 54, 0.15)',\n borderColor: 'rgba(244, 67, 54, 0.4)',\n },\n NotMapped: {\n color: '#FFA726',\n backgroundColor: 'rgba(255, 167, 38, 0.15)',\n borderColor: 'rgba(255, 167, 38, 0.4)',\n },\n AutoMapped: {\n color: '#42A5F5',\n backgroundColor: 'rgba(66, 165, 245, 0.15)',\n borderColor: 'rgba(66, 165, 245, 0.4)',\n },\n ErrorWhenFetchingService: {\n color: '#f44336',\n backgroundColor: 'rgba(244, 67, 54, 0.15)',\n borderColor: 'rgba(244, 67, 54, 0.4)',\n },\n };\n return darkColors[statusKey] || {\n color: '#999',\n backgroundColor: 'rgba(153, 153, 153, 0.15)',\n borderColor: 'rgba(153, 153, 153, 0.4)',\n };\n }\n\n const lightColors = {\n InSync: {\n color: '#00875A',\n backgroundColor: '#E3FCEF',\n borderColor: '#57D9A3',\n },\n OutOfSync: {\n color: '#fff',\n backgroundColor: 'red',\n borderColor: 'red',\n },\n NotMapped: {\n color: '#B88A00',\n backgroundColor: '#FFF8E6',\n borderColor: '#E8C547',\n },\n AutoMapped: {\n color: '#1565C0',\n backgroundColor: '#E3F2FD',\n borderColor: '#64B5F6',\n },\n ErrorWhenFetchingService: {\n color: '#fff',\n backgroundColor: 'red',\n borderColor: 'red',\n },\n };\n return lightColors[statusKey] || {\n color: 'gray',\n backgroundColor: '#f0f0f0',\n borderColor: 'gray',\n };\n}\n\ninterface StyleProps {\n color: string;\n backgroundColor: string;\n borderColor: string;\n}\n\nconst useStyles = makeStyles<BackstageTheme, StyleProps>(() => {\n return {\n pill: (props: StyleProps) => ({\n '& .bui-Text': {\n backgroundColor: props.backgroundColor,\n borderRadius: '4px',\n color: props.color,\n padding: '4px 12px',\n maxWidth: 'min-content',\n fontSize: '12px',\n fontWeight: 500,\n border: `1px solid ${props.borderColor}`,\n display: 'inline-block',\n },\n }),\n };\n});\n\nexport default function StatusCell({ entity }: { entity: BackstageEntity }) {\n const theme = useTheme();\n const isDarkTheme = theme.palette.type === 'dark';\n const statusValue = entity.status || 'NotMapped';\n const { color, backgroundColor, borderColor } = getStatusColors(statusValue, isDarkTheme);\n const classes = useStyles({ color, backgroundColor, borderColor });\n\n const statusName = getStatusName(statusValue);\n return <CellText title={statusName} className={classes.pill} />;\n}\n"],"names":[],"mappings":"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"}
|