@backstage-community/plugin-servicenow 1.0.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 (56) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +34 -0
  3. package/dist/api/ServiceNowBackendClient.esm.js +45 -0
  4. package/dist/api/ServiceNowBackendClient.esm.js.map +1 -0
  5. package/dist/components/Servicenow/ClosedIcon.esm.js +14 -0
  6. package/dist/components/Servicenow/ClosedIcon.esm.js.map +1 -0
  7. package/dist/components/Servicenow/CustomSvgIcon.esm.js +13 -0
  8. package/dist/components/Servicenow/CustomSvgIcon.esm.js.map +1 -0
  9. package/dist/components/Servicenow/InProgressIcon.esm.js +14 -0
  10. package/dist/components/Servicenow/InProgressIcon.esm.js.map +1 -0
  11. package/dist/components/Servicenow/IncidentsFilter.esm.js +69 -0
  12. package/dist/components/Servicenow/IncidentsFilter.esm.js.map +1 -0
  13. package/dist/components/Servicenow/IncidentsListColumns.esm.js +43 -0
  14. package/dist/components/Servicenow/IncidentsListColumns.esm.js.map +1 -0
  15. package/dist/components/Servicenow/IncidentsTableBody.esm.js +28 -0
  16. package/dist/components/Servicenow/IncidentsTableBody.esm.js.map +1 -0
  17. package/dist/components/Servicenow/IncidentsTableHeader.esm.js +44 -0
  18. package/dist/components/Servicenow/IncidentsTableHeader.esm.js.map +1 -0
  19. package/dist/components/Servicenow/IncidentsTableRow.esm.js +54 -0
  20. package/dist/components/Servicenow/IncidentsTableRow.esm.js.map +1 -0
  21. package/dist/components/Servicenow/ModerateIcon.esm.js +14 -0
  22. package/dist/components/Servicenow/ModerateIcon.esm.js.map +1 -0
  23. package/dist/components/Servicenow/ServicenowContent.esm.js +196 -0
  24. package/dist/components/Servicenow/ServicenowContent.esm.js.map +1 -0
  25. package/dist/components/Servicenow/index.esm.js +2 -0
  26. package/dist/components/Servicenow/index.esm.js.map +1 -0
  27. package/dist/components/shared-components/IncidentEnumFilter.esm.js +79 -0
  28. package/dist/components/shared-components/IncidentEnumFilter.esm.js.map +1 -0
  29. package/dist/hooks/useDebouncedValue.esm.js +13 -0
  30. package/dist/hooks/useDebouncedValue.esm.js.map +1 -0
  31. package/dist/hooks/useQueryArrayFilter.esm.js +38 -0
  32. package/dist/hooks/useQueryArrayFilter.esm.js.map +1 -0
  33. package/dist/hooks/useQueryArrayState.esm.js +44 -0
  34. package/dist/hooks/useQueryArrayState.esm.js.map +1 -0
  35. package/dist/hooks/useQueryHelpers.esm.js +24 -0
  36. package/dist/hooks/useQueryHelpers.esm.js.map +1 -0
  37. package/dist/hooks/useQueryState.esm.js +50 -0
  38. package/dist/hooks/useQueryState.esm.js.map +1 -0
  39. package/dist/hooks/useUserEmail.esm.js +22 -0
  40. package/dist/hooks/useUserEmail.esm.js.map +1 -0
  41. package/dist/index.d.ts +23 -0
  42. package/dist/index.esm.js +2 -0
  43. package/dist/index.esm.js.map +1 -0
  44. package/dist/plugin.esm.js +43 -0
  45. package/dist/plugin.esm.js.map +1 -0
  46. package/dist/routes.esm.js +8 -0
  47. package/dist/routes.esm.js.map +1 -0
  48. package/dist/types.esm.js +13 -0
  49. package/dist/types.esm.js.map +1 -0
  50. package/dist/utils/incidentUtils.esm.js +58 -0
  51. package/dist/utils/incidentUtils.esm.js.map +1 -0
  52. package/dist/utils/queryParamsUtils.esm.js +37 -0
  53. package/dist/utils/queryParamsUtils.esm.js.map +1 -0
  54. package/dist/utils/stringUtils.esm.js +13 -0
  55. package/dist/utils/stringUtils.esm.js.map +1 -0
  56. package/package.json +88 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @backstage-community/plugin-servicenow
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 3d708ba: First version of Servicenow plugin
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [3d708ba]
12
+ - @backstage-community/plugin-servicenow-common@1.0.0
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # ServiceNow Frontend Plugin
2
+
3
+ This is the frontend implementation of the ServiceNow plugin for Backstage.
4
+
5
+ It is responsible for rendering the ServiceNow tab content, fetching incident data, and integrating with Backstage's dynamic plugin system.
6
+
7
+ ---
8
+
9
+ ## 🚀 Getting Started
10
+
11
+ 1. Install dependencies:
12
+
13
+ ```bash
14
+ yarn install
15
+ ```
16
+
17
+ 2. Start the Backstage dev app:
18
+
19
+ Your plugin has been added to the example app in this `plugins/servicenow` directory, meaning you'll be able to access it by running `yarn start` in the current directory, and then navigating to [/servicenow](http://localhost:3000/servicenow).
20
+
21
+ ## Frontend Configuration
22
+
23
+ This plugin supports dynamic mounting via `dynamic-plugins.yaml`.
24
+ Please refer to the main plugin [README](../README.md) for complete instructions on:
25
+
26
+ - Adding dynamic mount points
27
+ - Configuring tabs
28
+ - Using the `isMyProfile` condition on mount point configuration
29
+
30
+ ## Notes on Identity Handling
31
+
32
+ When using this plugin in a Backstage instance that supports dynamic plugins (e.g., RHDH), it enables user-specific incident filtering in the **"My ServiceNow Tickets"** tab, shown on the entity page of the currently logged-in user.
33
+
34
+ > **NOTE:** The local dev app does **not** support user-specific incident filtering.
@@ -0,0 +1,45 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const serviceNowApiRef = createApiRef({
4
+ id: "plugin.servicenow.service"
5
+ });
6
+ class ServiceNowBackendClient {
7
+ constructor(discoveryApi, fetchApi, identityApi) {
8
+ this.discoveryApi = discoveryApi;
9
+ this.fetchApi = fetchApi;
10
+ this.identityApi = identityApi;
11
+ }
12
+ async fetchFromServiceNow(path, queryParams) {
13
+ const proxyBase = await this.discoveryApi.getBaseUrl("servicenow");
14
+ const url = `${proxyBase}${path}${queryParams ? `?${queryParams}` : ""}`;
15
+ const { token } = await this.identityApi.getCredentials();
16
+ const headers = {
17
+ Authorization: `Bearer ${token}`
18
+ };
19
+ const response = await this.fetchApi.fetch(url, { headers });
20
+ if (!response.ok) {
21
+ throw new Error(`ServiceNow API request failed: ${response.status}`);
22
+ }
23
+ return await response.json();
24
+ }
25
+ async getIncidents(queryParams) {
26
+ const { items, totalCount } = await this.fetchFromServiceNow("/incidents", queryParams);
27
+ const incidents = incidentsPickToIncidentsData(items);
28
+ return { incidents, totalCount };
29
+ }
30
+ }
31
+ function incidentsPickToIncidentsData(data) {
32
+ return data.map((item) => ({
33
+ sysId: item.sys_id,
34
+ number: item.number,
35
+ shortDescription: item.short_description,
36
+ description: item.description,
37
+ sysCreatedOn: item.sys_created_on,
38
+ priority: item.priority,
39
+ incidentState: item.incident_state,
40
+ url: item.url
41
+ }));
42
+ }
43
+
44
+ export { ServiceNowBackendClient, incidentsPickToIncidentsData, serviceNowApiRef };
45
+ //# sourceMappingURL=ServiceNowBackendClient.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceNowBackendClient.esm.js","sources":["../../src/api/ServiceNowBackendClient.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { IncidentPick } from '@backstage-community/plugin-servicenow-common';\nimport {\n createApiRef,\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { IncidentsData, PaginatedIncidentsData } from '../types';\n\nexport interface ServiceNowBackendAPI {\n getIncidents(queryParams: URLSearchParams): Promise<PaginatedIncidentsData>;\n}\n\nexport const serviceNowApiRef = createApiRef<ServiceNowBackendAPI>({\n id: 'plugin.servicenow.service',\n});\n\nexport class ServiceNowBackendClient implements ServiceNowBackendAPI {\n constructor(\n private readonly discoveryApi: DiscoveryApi,\n private readonly fetchApi: FetchApi,\n private readonly identityApi: IdentityApi,\n ) {}\n\n private async fetchFromServiceNow<T>(\n path: string,\n queryParams?: URLSearchParams,\n ): Promise<{ items: T; totalCount: number }> {\n const proxyBase = await this.discoveryApi.getBaseUrl('servicenow');\n const url = `${proxyBase}${path}${queryParams ? `?${queryParams}` : ''}`;\n\n const { token } = await this.identityApi.getCredentials();\n const headers = {\n Authorization: `Bearer ${token}`,\n };\n\n const response = await this.fetchApi.fetch(url, { headers });\n if (!response.ok) {\n throw new Error(`ServiceNow API request failed: ${response.status}`);\n }\n\n return (await response.json()) as { items: T; totalCount: number };\n }\n\n async getIncidents(\n queryParams: URLSearchParams,\n ): Promise<PaginatedIncidentsData> {\n const { items, totalCount } = await this.fetchFromServiceNow<\n IncidentPick[]\n >('/incidents', queryParams);\n\n const incidents = incidentsPickToIncidentsData(items);\n return { incidents, totalCount };\n }\n}\n\nexport function incidentsPickToIncidentsData(\n data: IncidentPick[],\n): IncidentsData[] {\n return data.map(item => ({\n sysId: item.sys_id,\n number: item.number,\n shortDescription: item.short_description,\n description: item.description,\n sysCreatedOn: item.sys_created_on,\n priority: item.priority,\n incidentState: item.incident_state,\n url: item.url,\n }));\n}\n"],"names":[],"mappings":";;AA4BO,MAAM,mBAAmB,YAAmC,CAAA;AAAA,EACjE,EAAI,EAAA;AACN,CAAC;AAEM,MAAM,uBAAwD,CAAA;AAAA,EACnE,WAAA,CACmB,YACA,EAAA,QAAA,EACA,WACjB,EAAA;AAHiB,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA;AAChB,EAEH,MAAc,mBACZ,CAAA,IAAA,EACA,WAC2C,EAAA;AAC3C,IAAA,MAAM,SAAY,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,YAAY,CAAA;AACjE,IAAM,MAAA,GAAA,GAAM,CAAG,EAAA,SAAS,CAAG,EAAA,IAAI,GAAG,WAAc,GAAA,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AAEtE,IAAA,MAAM,EAAE,KAAM,EAAA,GAAI,MAAM,IAAA,CAAK,YAAY,cAAe,EAAA;AACxD,IAAA,MAAM,OAAU,GAAA;AAAA,MACd,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA,KAChC;AAEA,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAK,EAAA,EAAE,SAAS,CAAA;AAC3D,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAkC,+BAAA,EAAA,QAAA,CAAS,MAAM,CAAE,CAAA,CAAA;AAAA;AAGrE,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC9B,EAEA,MAAM,aACJ,WACiC,EAAA;AACjC,IAAM,MAAA,EAAE,OAAO,UAAW,EAAA,GAAI,MAAM,IAAK,CAAA,mBAAA,CAEvC,cAAc,WAAW,CAAA;AAE3B,IAAM,MAAA,SAAA,GAAY,6BAA6B,KAAK,CAAA;AACpD,IAAO,OAAA,EAAE,WAAW,UAAW,EAAA;AAAA;AAEnC;AAEO,SAAS,6BACd,IACiB,EAAA;AACjB,EAAO,OAAA,IAAA,CAAK,IAAI,CAAS,IAAA,MAAA;AAAA,IACvB,OAAO,IAAK,CAAA,MAAA;AAAA,IACZ,QAAQ,IAAK,CAAA,MAAA;AAAA,IACb,kBAAkB,IAAK,CAAA,iBAAA;AAAA,IACvB,aAAa,IAAK,CAAA,WAAA;AAAA,IAClB,cAAc,IAAK,CAAA,cAAA;AAAA,IACnB,UAAU,IAAK,CAAA,QAAA;AAAA,IACf,eAAe,IAAK,CAAA,cAAA;AAAA,IACpB,KAAK,IAAK,CAAA;AAAA,GACV,CAAA,CAAA;AACJ;;;;"}
@@ -0,0 +1,14 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { CustomSvgIcon } from './CustomSvgIcon.esm.js';
3
+
4
+ const ClosedIcon = (props) => /* @__PURE__ */ jsx(
5
+ CustomSvgIcon,
6
+ {
7
+ viewBox: "0 0 16 16",
8
+ path: /* @__PURE__ */ jsx("path", { d: "M2.333 8.667c-.278 0-.486-.236-.65-.4-.163-.163-.4-.372-.4-.65s.236-.486.4-.65c.163-.163.372-.4.65-.4h4c.278 0 .486.236.65.4.163.163.4.372.4.65s-.236.486-.4.65c-.163.163-.372.4-.65.4h-4Zm7.333 0c-.278 0-.486-.236-.65-.4-.163-.163-.4-.372-.4-.65s.236-.486.4-.65c.163-.163.372-.4.65-.4h4c.278 0 .486.236.65.4.163.163.4.372.4.65s-.236.486-.4.65c-.163.163-.372.4-.65.4h-4Z" }),
9
+ ...props
10
+ }
11
+ );
12
+
13
+ export { ClosedIcon };
14
+ //# sourceMappingURL=ClosedIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClosedIcon.esm.js","sources":["../../../src/components/Servicenow/ClosedIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CustomSvgIcon } from './CustomSvgIcon';\n\nexport const ClosedIcon = (props: any) => (\n <CustomSvgIcon\n viewBox=\"0 0 16 16\"\n path={\n <path d=\"M2.333 8.667c-.278 0-.486-.236-.65-.4-.163-.163-.4-.372-.4-.65s.236-.486.4-.65c.163-.163.372-.4.65-.4h4c.278 0 .486.236.65.4.163.163.4.372.4.65s-.236.486-.4.65c-.163.163-.372.4-.65.4h-4Zm7.333 0c-.278 0-.486-.236-.65-.4-.163-.163-.4-.372-.4-.65s.236-.486.4-.65c.163-.163.372-.4.65-.4h4c.278 0 .486.236.65.4.163.163.4.372.4.65s-.236.486-.4.65c-.163.163-.372.4-.65.4h-4Z\" />\n }\n {...props}\n />\n);\n"],"names":[],"mappings":";;;AAkBa,MAAA,UAAA,GAAa,CAAC,KACzB,qBAAA,GAAA;AAAA,EAAC,aAAA;AAAA,EAAA;AAAA,IACC,OAAQ,EAAA,WAAA;AAAA,IACR,IACE,kBAAA,GAAA,CAAC,MAAK,EAAA,EAAA,CAAA,EAAE,kXAAmX,EAAA,CAAA;AAAA,IAE5X,GAAG;AAAA;AACN;;;;"}
@@ -0,0 +1,13 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import SvgIcon from '@mui/material/SvgIcon';
3
+
4
+ const CustomSvgIcon = ({
5
+ path,
6
+ viewBox = "0 0 24 24",
7
+ ...props
8
+ }) => {
9
+ return /* @__PURE__ */ jsx(SvgIcon, { viewBox, ...props, children: path });
10
+ };
11
+
12
+ export { CustomSvgIcon };
13
+ //# sourceMappingURL=CustomSvgIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomSvgIcon.esm.js","sources":["../../../src/components/Servicenow/CustomSvgIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SvgIcon from '@mui/material/SvgIcon';\n\nexport const CustomSvgIcon = ({\n path,\n viewBox = '0 0 24 24',\n ...props\n}: any) => {\n return (\n <SvgIcon viewBox={viewBox} {...props}>\n {path}\n </SvgIcon>\n );\n};\n"],"names":[],"mappings":";;;AAkBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,IAAA;AAAA,EACA,OAAU,GAAA,WAAA;AAAA,EACV,GAAG;AACL,CAAW,KAAA;AACT,EAAA,uBACG,GAAA,CAAA,OAAA,EAAA,EAAQ,OAAmB,EAAA,GAAG,OAC5B,QACH,EAAA,IAAA,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,14 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { CustomSvgIcon } from './CustomSvgIcon.esm.js';
3
+
4
+ const InProgressIcon = (props) => /* @__PURE__ */ jsx(
5
+ CustomSvgIcon,
6
+ {
7
+ viewBox: "0 0 16 16",
8
+ path: /* @__PURE__ */ jsx("path", { d: "M7.99992 14.6667C7.08881 14.6667 6.2277 14.4917 5.41658 14.1417C4.60547 13.7917 3.89714 13.3139 3.29159 12.7083C2.68603 12.1028 2.20825 11.3945 1.85825 10.5833C1.50825 9.77223 1.33325 8.91112 1.33325 8.00001C1.33325 7.07779 1.50825 6.2139 1.85825 5.40834C2.20825 4.60279 2.68603 3.89723 3.29159 3.29168C3.89714 2.68612 4.60547 2.20834 5.41658 1.85834C6.2277 1.50834 7.08881 1.33334 7.99992 1.33334C8.18881 1.33334 8.34714 1.39723 8.47492 1.52501C8.6027 1.65279 8.66658 1.81112 8.66658 2.00001C8.66658 2.1889 8.6027 2.34723 8.47492 2.47501C8.34714 2.60279 8.18881 2.66668 7.99992 2.66668C6.52214 2.66668 5.26381 3.18612 4.22492 4.22501C3.18603 5.2639 2.66659 6.52223 2.66659 8.00001C2.66659 9.47779 3.18603 10.7361 4.22492 11.775C5.26381 12.8139 6.52214 13.3333 7.99992 13.3333C9.4777 13.3333 10.736 12.8139 11.7749 11.775C12.8138 10.7361 13.3333 9.47779 13.3333 8.00001C13.3333 7.81112 13.3971 7.65279 13.5249 7.52501C13.6527 7.39723 13.811 7.33334 13.9999 7.33334C14.1888 7.33334 14.3471 7.39723 14.4749 7.52501C14.6027 7.65279 14.6666 7.81112 14.6666 8.00001C14.6666 8.91112 14.4916 9.77223 14.1416 10.5833C13.7916 11.3945 13.3138 12.1028 12.7083 12.7083C12.1027 13.3139 11.3971 13.7917 10.5916 14.1417C9.78603 14.4917 8.92214 14.6667 7.99992 14.6667Z" }),
9
+ ...props
10
+ }
11
+ );
12
+
13
+ export { InProgressIcon };
14
+ //# sourceMappingURL=InProgressIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InProgressIcon.esm.js","sources":["../../../src/components/Servicenow/InProgressIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CustomSvgIcon } from './CustomSvgIcon';\n\nexport const InProgressIcon = (props: any) => (\n <CustomSvgIcon\n viewBox=\"0 0 16 16\"\n path={\n <path d=\"M7.99992 14.6667C7.08881 14.6667 6.2277 14.4917 5.41658 14.1417C4.60547 13.7917 3.89714 13.3139 3.29159 12.7083C2.68603 12.1028 2.20825 11.3945 1.85825 10.5833C1.50825 9.77223 1.33325 8.91112 1.33325 8.00001C1.33325 7.07779 1.50825 6.2139 1.85825 5.40834C2.20825 4.60279 2.68603 3.89723 3.29159 3.29168C3.89714 2.68612 4.60547 2.20834 5.41658 1.85834C6.2277 1.50834 7.08881 1.33334 7.99992 1.33334C8.18881 1.33334 8.34714 1.39723 8.47492 1.52501C8.6027 1.65279 8.66658 1.81112 8.66658 2.00001C8.66658 2.1889 8.6027 2.34723 8.47492 2.47501C8.34714 2.60279 8.18881 2.66668 7.99992 2.66668C6.52214 2.66668 5.26381 3.18612 4.22492 4.22501C3.18603 5.2639 2.66659 6.52223 2.66659 8.00001C2.66659 9.47779 3.18603 10.7361 4.22492 11.775C5.26381 12.8139 6.52214 13.3333 7.99992 13.3333C9.4777 13.3333 10.736 12.8139 11.7749 11.775C12.8138 10.7361 13.3333 9.47779 13.3333 8.00001C13.3333 7.81112 13.3971 7.65279 13.5249 7.52501C13.6527 7.39723 13.811 7.33334 13.9999 7.33334C14.1888 7.33334 14.3471 7.39723 14.4749 7.52501C14.6027 7.65279 14.6666 7.81112 14.6666 8.00001C14.6666 8.91112 14.4916 9.77223 14.1416 10.5833C13.7916 11.3945 13.3138 12.1028 12.7083 12.7083C12.1027 13.3139 11.3971 13.7917 10.5916 14.1417C9.78603 14.4917 8.92214 14.6667 7.99992 14.6667Z\" />\n }\n {...props}\n />\n);\n"],"names":[],"mappings":";;;AAkBa,MAAA,cAAA,GAAiB,CAAC,KAC7B,qBAAA,GAAA;AAAA,EAAC,aAAA;AAAA,EAAA;AAAA,IACC,OAAQ,EAAA,WAAA;AAAA,IACR,IACE,kBAAA,GAAA,CAAC,MAAK,EAAA,EAAA,CAAA,EAAE,uuCAAwuC,EAAA,CAAA;AAAA,IAEjvC,GAAG;AAAA;AACN;;;;"}
@@ -0,0 +1,69 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import Box from '@mui/material/Box';
3
+ import { IncidentEnumFilter } from '../shared-components/IncidentEnumFilter.esm.js';
4
+ import { INCIDENT_STATE_MAP, PRIORITY_MAP } from '../../utils/incidentUtils.esm.js';
5
+ import { useQueryArrayFilter } from '../../hooks/useQueryArrayFilter.esm.js';
6
+ import { useMemo, useCallback } from 'react';
7
+ import { useUpdateQueryParams } from '../../hooks/useQueryHelpers.esm.js';
8
+
9
+ const IncidentsFilter = () => {
10
+ const stateFilter = useQueryArrayFilter("state");
11
+ const priorityFilter = useQueryArrayFilter("priority");
12
+ const updateQueryParams = useUpdateQueryParams();
13
+ const stateValue = useMemo(() => stateFilter.current, [stateFilter]);
14
+ const priorityValue = useMemo(() => priorityFilter.current, [priorityFilter]);
15
+ const handleStateChange = useCallback(
16
+ (_e, value) => {
17
+ updateQueryParams({
18
+ state: value.map((v) => v.value).join(","),
19
+ offset: "0"
20
+ });
21
+ },
22
+ [updateQueryParams]
23
+ );
24
+ const handlePriorityChange = useCallback(
25
+ (_e, value) => {
26
+ updateQueryParams({
27
+ priority: value.map((v) => v.value).join(","),
28
+ offset: "0"
29
+ });
30
+ },
31
+ [updateQueryParams]
32
+ );
33
+ return /* @__PURE__ */ jsxs(
34
+ Box,
35
+ {
36
+ sx: {
37
+ display: "flex",
38
+ flexDirection: "column",
39
+ gap: 2,
40
+ minWidth: { xs: 200, lg: "auto" }
41
+ },
42
+ children: [
43
+ /* @__PURE__ */ jsx(
44
+ IncidentEnumFilter,
45
+ {
46
+ label: "State",
47
+ filterKey: "state",
48
+ dataMap: INCIDENT_STATE_MAP,
49
+ value: stateValue,
50
+ onChange: handleStateChange
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx(
54
+ IncidentEnumFilter,
55
+ {
56
+ label: "Priority",
57
+ filterKey: "priority",
58
+ dataMap: PRIORITY_MAP,
59
+ value: priorityValue,
60
+ onChange: handlePriorityChange
61
+ }
62
+ )
63
+ ]
64
+ }
65
+ );
66
+ };
67
+
68
+ export { IncidentsFilter };
69
+ //# sourceMappingURL=IncidentsFilter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncidentsFilter.esm.js","sources":["../../../src/components/Servicenow/IncidentsFilter.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@mui/material/Box';\nimport { IncidentEnumFilter } from '../shared-components/IncidentEnumFilter';\nimport { INCIDENT_STATE_MAP, PRIORITY_MAP } from '../../utils/incidentUtils';\nimport { useQueryArrayFilter } from '../../hooks/useQueryArrayFilter';\nimport { useMemo, useCallback } from 'react';\nimport { SelectItem } from '@backstage/core-components';\nimport { useUpdateQueryParams } from '../../hooks/useQueryHelpers';\n\nexport const IncidentsFilter = () => {\n const stateFilter = useQueryArrayFilter('state');\n const priorityFilter = useQueryArrayFilter('priority');\n const updateQueryParams = useUpdateQueryParams();\n\n const stateValue = useMemo(() => stateFilter.current, [stateFilter]);\n const priorityValue = useMemo(() => priorityFilter.current, [priorityFilter]);\n\n const handleStateChange = useCallback(\n (_e: any, value: SelectItem[]) => {\n updateQueryParams({\n state: value.map(v => v.value).join(','),\n offset: '0',\n });\n },\n [updateQueryParams],\n );\n\n const handlePriorityChange = useCallback(\n (_e: any, value: SelectItem[]) => {\n updateQueryParams({\n priority: value.map(v => v.value).join(','),\n offset: '0',\n });\n },\n [updateQueryParams],\n );\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n minWidth: { xs: 200, lg: 'auto' },\n }}\n >\n <IncidentEnumFilter\n label=\"State\"\n filterKey=\"state\"\n dataMap={INCIDENT_STATE_MAP}\n value={stateValue}\n onChange={handleStateChange}\n />\n <IncidentEnumFilter\n label=\"Priority\"\n filterKey=\"priority\"\n dataMap={PRIORITY_MAP}\n value={priorityValue}\n onChange={handlePriorityChange}\n />\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,kBAAkB,MAAM;AACnC,EAAM,MAAA,WAAA,GAAc,oBAAoB,OAAO,CAAA;AAC/C,EAAM,MAAA,cAAA,GAAiB,oBAAoB,UAAU,CAAA;AACrD,EAAA,MAAM,oBAAoB,oBAAqB,EAAA;AAE/C,EAAA,MAAM,aAAa,OAAQ,CAAA,MAAM,YAAY,OAAS,EAAA,CAAC,WAAW,CAAC,CAAA;AACnE,EAAA,MAAM,gBAAgB,OAAQ,CAAA,MAAM,eAAe,OAAS,EAAA,CAAC,cAAc,CAAC,CAAA;AAE5E,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,IAAS,KAAwB,KAAA;AAChC,MAAkB,iBAAA,CAAA;AAAA,QAChB,KAAA,EAAO,MAAM,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,QACvC,MAAQ,EAAA;AAAA,OACT,CAAA;AAAA,KACH;AAAA,IACA,CAAC,iBAAiB;AAAA,GACpB;AAEA,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,IAAS,KAAwB,KAAA;AAChC,MAAkB,iBAAA,CAAA;AAAA,QAChB,QAAA,EAAU,MAAM,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,QAC1C,MAAQ,EAAA;AAAA,OACT,CAAA;AAAA,KACH;AAAA,IACA,CAAC,iBAAiB;AAAA,GACpB;AAEA,EACE,uBAAA,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,OAAS,EAAA,MAAA;AAAA,QACT,aAAe,EAAA,QAAA;AAAA,QACf,GAAK,EAAA,CAAA;AAAA,QACL,QAAU,EAAA,EAAE,EAAI,EAAA,GAAA,EAAK,IAAI,MAAO;AAAA,OAClC;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YACC,KAAM,EAAA,OAAA;AAAA,YACN,SAAU,EAAA,OAAA;AAAA,YACV,OAAS,EAAA,kBAAA;AAAA,YACT,KAAO,EAAA,UAAA;AAAA,YACP,QAAU,EAAA;AAAA;AAAA,SACZ;AAAA,wBACA,GAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YACC,KAAM,EAAA,UAAA;AAAA,YACN,SAAU,EAAA,UAAA;AAAA,YACV,OAAS,EAAA,YAAA;AAAA,YACT,KAAO,EAAA,aAAA;AAAA,YACP,QAAU,EAAA;AAAA;AAAA;AACZ;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -0,0 +1,43 @@
1
+ import { IncidentTableFieldEnum } from '../../types.esm.js';
2
+
3
+ const IncidentsListColumns = [
4
+ {
5
+ id: "incidentNumber",
6
+ title: "Incident Number",
7
+ field: IncidentTableFieldEnum.Number,
8
+ type: "string"
9
+ },
10
+ {
11
+ id: "description",
12
+ title: "Description",
13
+ field: IncidentTableFieldEnum.ShortDescription,
14
+ type: "string"
15
+ },
16
+ {
17
+ id: "created",
18
+ title: "Created",
19
+ field: IncidentTableFieldEnum.Created,
20
+ type: "string"
21
+ },
22
+ {
23
+ id: "priority",
24
+ title: "Priority",
25
+ field: IncidentTableFieldEnum.Priority,
26
+ type: "numeric"
27
+ },
28
+ {
29
+ id: "state",
30
+ title: "State",
31
+ field: IncidentTableFieldEnum.IncidentState,
32
+ type: "datetime"
33
+ },
34
+ {
35
+ id: "actions",
36
+ title: "Actions",
37
+ sorting: false,
38
+ type: "string"
39
+ }
40
+ ];
41
+
42
+ export { IncidentsListColumns };
43
+ //# sourceMappingURL=IncidentsListColumns.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncidentsListColumns.esm.js","sources":["../../../src/components/Servicenow/IncidentsListColumns.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { TableColumn } from '@backstage/core-components';\n\nimport { IncidentsData, IncidentTableFieldEnum } from '../../types';\n\nexport const IncidentsListColumns: TableColumn<IncidentsData>[] = [\n {\n id: 'incidentNumber',\n title: 'Incident Number',\n field: IncidentTableFieldEnum.Number,\n type: 'string',\n },\n {\n id: 'description',\n title: 'Description',\n field: IncidentTableFieldEnum.ShortDescription,\n type: 'string',\n },\n {\n id: 'created',\n title: 'Created',\n field: IncidentTableFieldEnum.Created,\n type: 'string',\n },\n {\n id: 'priority',\n title: 'Priority',\n field: IncidentTableFieldEnum.Priority,\n type: 'numeric',\n },\n {\n id: 'state',\n title: 'State',\n field: IncidentTableFieldEnum.IncidentState,\n type: 'datetime',\n },\n {\n id: 'actions',\n title: 'Actions',\n sorting: false,\n type: 'string',\n },\n];\n"],"names":[],"mappings":";;AAmBO,MAAM,oBAAqD,GAAA;AAAA,EAChE;AAAA,IACE,EAAI,EAAA,gBAAA;AAAA,IACJ,KAAO,EAAA,iBAAA;AAAA,IACP,OAAO,sBAAuB,CAAA,MAAA;AAAA,IAC9B,IAAM,EAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,EAAI,EAAA,aAAA;AAAA,IACJ,KAAO,EAAA,aAAA;AAAA,IACP,OAAO,sBAAuB,CAAA,gBAAA;AAAA,IAC9B,IAAM,EAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,EAAI,EAAA,SAAA;AAAA,IACJ,KAAO,EAAA,SAAA;AAAA,IACP,OAAO,sBAAuB,CAAA,OAAA;AAAA,IAC9B,IAAM,EAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,EAAI,EAAA,UAAA;AAAA,IACJ,KAAO,EAAA,UAAA;AAAA,IACP,OAAO,sBAAuB,CAAA,QAAA;AAAA,IAC9B,IAAM,EAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,EAAI,EAAA,OAAA;AAAA,IACJ,KAAO,EAAA,OAAA;AAAA,IACP,OAAO,sBAAuB,CAAA,aAAA;AAAA,IAC9B,IAAM,EAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,EAAI,EAAA,SAAA;AAAA,IACJ,KAAO,EAAA,SAAA;AAAA,IACP,OAAS,EAAA,KAAA;AAAA,IACT,IAAM,EAAA;AAAA;AAEV;;;;"}
@@ -0,0 +1,28 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import Box from '@mui/material/Box';
3
+ import TableBody from '@mui/material/TableBody';
4
+ import TableRow from '@mui/material/TableRow';
5
+ import TableCell from '@mui/material/TableCell';
6
+ import { IncidentsListColumns } from './IncidentsListColumns.esm.js';
7
+ import { IncidentsTableRow } from './IncidentsTableRow.esm.js';
8
+
9
+ const IncidentsTableBody = ({ rows }) => {
10
+ if (rows?.length > 0) {
11
+ return /* @__PURE__ */ jsx(TableBody, { "data-testid": "incidents", children: rows.map((row) => /* @__PURE__ */ jsx(IncidentsTableRow, { data: row }, row.sysId)) });
12
+ }
13
+ return /* @__PURE__ */ jsx(TableBody, { children: /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: IncidentsListColumns.length, children: /* @__PURE__ */ jsx(
14
+ Box,
15
+ {
16
+ "data-testid": "no-incidents-found",
17
+ sx: {
18
+ p: 2,
19
+ display: "flex",
20
+ justifyContent: "center"
21
+ },
22
+ children: "No records found"
23
+ }
24
+ ) }) }) });
25
+ };
26
+
27
+ export { IncidentsTableBody };
28
+ //# sourceMappingURL=IncidentsTableBody.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncidentsTableBody.esm.js","sources":["../../../src/components/Servicenow/IncidentsTableBody.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@mui/material/Box';\nimport TableBody from '@mui/material/TableBody';\nimport TableRow from '@mui/material/TableRow';\nimport TableCell from '@mui/material/TableCell';\n\nimport { IncidentsListColumns } from './IncidentsListColumns';\nimport { IncidentsTableRow } from './IncidentsTableRow';\nimport type { IncidentsData } from '../../types';\n\nexport const IncidentsTableBody = ({ rows }: { rows: IncidentsData[] }) => {\n // TODO: Add loading and error states\n\n if (rows?.length > 0) {\n return (\n <TableBody data-testid=\"incidents\">\n {rows.map(row => (\n <IncidentsTableRow key={row.sysId} data={row} />\n ))}\n </TableBody>\n );\n }\n\n return (\n <TableBody>\n <TableRow>\n <TableCell colSpan={IncidentsListColumns.length}>\n <Box\n data-testid=\"no-incidents-found\"\n sx={{\n p: 2,\n display: 'flex',\n justifyContent: 'center',\n }}\n >\n No records found\n </Box>\n </TableCell>\n </TableRow>\n </TableBody>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAyBO,MAAM,kBAAqB,GAAA,CAAC,EAAE,IAAA,EAAsC,KAAA;AAGzE,EAAI,IAAA,IAAA,EAAM,SAAS,CAAG,EAAA;AACpB,IAAA,uBACG,GAAA,CAAA,SAAA,EAAA,EAAU,aAAY,EAAA,WAAA,EACpB,eAAK,GAAI,CAAA,CAAA,GAAA,qBACP,GAAA,CAAA,iBAAA,EAAA,EAAkC,IAAM,EAAA,GAAA,EAAA,EAAjB,GAAI,CAAA,KAAkB,CAC/C,CACH,EAAA,CAAA;AAAA;AAIJ,EACE,uBAAA,GAAA,CAAC,aACC,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA,EACC,8BAAC,SAAU,EAAA,EAAA,OAAA,EAAS,qBAAqB,MACvC,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,oBAAA;AAAA,MACZ,EAAI,EAAA;AAAA,QACF,CAAG,EAAA,CAAA;AAAA,QACH,OAAS,EAAA,MAAA;AAAA,QACT,cAAgB,EAAA;AAAA,OAClB;AAAA,MACD,QAAA,EAAA;AAAA;AAAA,GAED,EACF,GACF,CACF,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,44 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import TableCell from '@mui/material/TableCell';
3
+ import TableHead from '@mui/material/TableHead';
4
+ import TableRow from '@mui/material/TableRow';
5
+ import TableSortLabel from '@mui/material/TableSortLabel';
6
+ import { IncidentsListColumns } from './IncidentsListColumns.esm.js';
7
+
8
+ const IncidentsTableHeader = ({
9
+ order,
10
+ orderBy,
11
+ onRequestSort
12
+ }) => {
13
+ const createSortHandler = (property) => (event) => {
14
+ onRequestSort(event, property);
15
+ };
16
+ return /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { sx: { marginLeft: "6px", borderBottom: "1px solid #e0e0e0" }, children: IncidentsListColumns.map((column) => /* @__PURE__ */ jsx(
17
+ TableCell,
18
+ {
19
+ align: "left",
20
+ padding: "normal",
21
+ style: {
22
+ lineHeight: "1.5rem",
23
+ fontSize: "0.875rem",
24
+ padding: "24px 16px 24px 20px",
25
+ fontWeight: "700"
26
+ },
27
+ sortDirection: orderBy === column.field ? order : "asc",
28
+ children: /* @__PURE__ */ jsx(
29
+ TableSortLabel,
30
+ {
31
+ active: orderBy === column.field,
32
+ direction: orderBy === column.field ? order : "asc",
33
+ onClick: column.sorting === false ? void 0 : createSortHandler(column.field),
34
+ disabled: column.sorting === false,
35
+ children: column.title
36
+ }
37
+ )
38
+ },
39
+ column.id
40
+ )) }) });
41
+ };
42
+
43
+ export { IncidentsTableHeader };
44
+ //# sourceMappingURL=IncidentsTableHeader.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncidentsTableHeader.esm.js","sources":["../../../src/components/Servicenow/IncidentsTableHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MouseEvent } from 'react';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableSortLabel from '@mui/material/TableSortLabel';\n\nimport { IncidentsListColumns } from './IncidentsListColumns';\nimport type { Order } from '@backstage-community/plugin-servicenow-common';\nimport { IncidentTableField } from '../../types';\n\ntype IncidentsTableHeaderProps = {\n order: Order;\n orderBy: IncidentTableField | undefined;\n onRequestSort: (\n event: MouseEvent<unknown>,\n property: IncidentTableField,\n ) => void;\n};\n\nexport const IncidentsTableHeader = ({\n order,\n orderBy,\n onRequestSort,\n}: IncidentsTableHeaderProps) => {\n const createSortHandler =\n (property: IncidentTableField) => (event: MouseEvent<unknown>) => {\n onRequestSort(event, property);\n };\n\n return (\n <TableHead>\n <TableRow sx={{ marginLeft: '6px', borderBottom: '1px solid #e0e0e0' }}>\n {IncidentsListColumns.map(column => (\n <TableCell\n key={column.id as string}\n align=\"left\"\n padding=\"normal\"\n style={{\n lineHeight: '1.5rem',\n fontSize: '0.875rem',\n padding: '24px 16px 24px 20px',\n fontWeight: '700',\n }}\n sortDirection={orderBy === column.field ? order : 'asc'}\n >\n <TableSortLabel\n active={orderBy === column.field}\n direction={orderBy === column.field ? order : 'asc'}\n onClick={\n column.sorting === false\n ? undefined\n : createSortHandler(column.field as IncidentTableField)\n }\n disabled={column.sorting === false}\n >\n {column.title}\n </TableSortLabel>\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAmCO,MAAM,uBAAuB,CAAC;AAAA,EACnC,KAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,iBACJ,GAAA,CAAC,QAAiC,KAAA,CAAC,KAA+B,KAAA;AAChE,IAAA,aAAA,CAAc,OAAO,QAAQ,CAAA;AAAA,GAC/B;AAEF,EAAA,uBACG,GAAA,CAAA,SAAA,EAAA,EACC,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA,EAAS,EAAI,EAAA,EAAE,UAAY,EAAA,KAAA,EAAO,YAAc,EAAA,mBAAA,EAC9C,EAAA,QAAA,EAAA,oBAAA,CAAqB,IAAI,CACxB,MAAA,qBAAA,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MAEC,KAAM,EAAA,MAAA;AAAA,MACN,OAAQ,EAAA,QAAA;AAAA,MACR,KAAO,EAAA;AAAA,QACL,UAAY,EAAA,QAAA;AAAA,QACZ,QAAU,EAAA,UAAA;AAAA,QACV,OAAS,EAAA,qBAAA;AAAA,QACT,UAAY,EAAA;AAAA,OACd;AAAA,MACA,aAAe,EAAA,OAAA,KAAY,MAAO,CAAA,KAAA,GAAQ,KAAQ,GAAA,KAAA;AAAA,MAElD,QAAA,kBAAA,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,MAAA,EAAQ,YAAY,MAAO,CAAA,KAAA;AAAA,UAC3B,SAAW,EAAA,OAAA,KAAY,MAAO,CAAA,KAAA,GAAQ,KAAQ,GAAA,KAAA;AAAA,UAC9C,SACE,MAAO,CAAA,OAAA,KAAY,QACf,MACA,GAAA,iBAAA,CAAkB,OAAO,KAA2B,CAAA;AAAA,UAE1D,QAAA,EAAU,OAAO,OAAY,KAAA,KAAA;AAAA,UAE5B,QAAO,EAAA,MAAA,CAAA;AAAA;AAAA;AACV,KAAA;AAAA,IAtBK,MAAO,CAAA;AAAA,GAwBf,GACH,CACF,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,54 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
3
+ import IconButton from '@mui/material/IconButton';
4
+ import TableCell from '@mui/material/TableCell';
5
+ import TableRow from '@mui/material/TableRow';
6
+ import { makeStyles } from '@mui/styles';
7
+ import Tooltip from '@mui/material/Tooltip';
8
+ import Typography from '@mui/material/Typography';
9
+ import { convertDateFormat } from '../../utils/stringUtils.esm.js';
10
+ import { getPriorityValue, getIncidentStateValue } from '../../utils/incidentUtils.esm.js';
11
+
12
+ const useStyles = makeStyles(() => ({
13
+ tableCellStyle: {
14
+ lineHeight: "1.5rem",
15
+ fontSize: "0.875rem"
16
+ }
17
+ }));
18
+ const IncidentsTableRow = ({ data }) => {
19
+ const classes = useStyles();
20
+ return /* @__PURE__ */ jsxs(
21
+ TableRow,
22
+ {
23
+ hover: true,
24
+ sx: {
25
+ fontSize: "0.875rem",
26
+ "&:last-child td, &:last-child th": { border: 0 },
27
+ borderBottom: "1px solid #e0e0e0"
28
+ },
29
+ children: [
30
+ /* @__PURE__ */ jsx(TableCell, { component: "th", scope: "row", className: classes.tableCellStyle, children: data.number }),
31
+ /* @__PURE__ */ jsx(TableCell, { align: "left", className: classes.tableCellStyle, children: /* @__PURE__ */ jsx(Tooltip, { title: data?.description, arrow: true, placement: "top", children: /* @__PURE__ */ jsx(
32
+ Typography,
33
+ {
34
+ variant: "body1",
35
+ style: {
36
+ maxWidth: 208,
37
+ whiteSpace: "nowrap",
38
+ overflow: "hidden",
39
+ textOverflow: "ellipsis"
40
+ },
41
+ children: data?.shortDescription
42
+ }
43
+ ) }) }),
44
+ /* @__PURE__ */ jsx(TableCell, { align: "left", className: classes.tableCellStyle, children: convertDateFormat(data?.sysCreatedOn) }),
45
+ /* @__PURE__ */ jsx(TableCell, { align: "left", className: classes.tableCellStyle, children: getPriorityValue(data?.priority) }),
46
+ /* @__PURE__ */ jsx(TableCell, { align: "left", className: classes.tableCellStyle, children: getIncidentStateValue(data?.incidentState) }),
47
+ /* @__PURE__ */ jsx(TableCell, { align: "left", className: classes.tableCellStyle, children: /* @__PURE__ */ jsx(IconButton, { onClick: () => window.open(data.url, "_blank"), children: /* @__PURE__ */ jsx(OpenInNewIcon, { fontSize: "small", style: { color: "inherit" } }) }) })
48
+ ]
49
+ }
50
+ );
51
+ };
52
+
53
+ export { IncidentsTableRow };
54
+ //# sourceMappingURL=IncidentsTableRow.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IncidentsTableRow.esm.js","sources":["../../../src/components/Servicenow/IncidentsTableRow.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport IconButton from '@mui/material/IconButton';\nimport TableCell from '@mui/material/TableCell';\nimport TableRow from '@mui/material/TableRow';\nimport { makeStyles } from '@mui/styles';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\n\nimport { convertDateFormat } from '../../utils/stringUtils';\nimport {\n getIncidentStateValue,\n getPriorityValue,\n} from '../../utils/incidentUtils';\nimport type { IncidentsData } from '../../types';\n\nconst useStyles = makeStyles(() => ({\n tableCellStyle: {\n lineHeight: '1.5rem',\n fontSize: '0.875rem',\n },\n}));\n\nexport const IncidentsTableRow = ({ data }: { data: IncidentsData }) => {\n const classes = useStyles();\n\n return (\n <TableRow\n hover\n sx={{\n fontSize: '0.875rem',\n '&:last-child td, &:last-child th': { border: 0 },\n borderBottom: '1px solid #e0e0e0',\n }}\n >\n <TableCell component=\"th\" scope=\"row\" className={classes.tableCellStyle}>\n {data.number}\n </TableCell>\n <TableCell align=\"left\" className={classes.tableCellStyle}>\n <Tooltip title={data?.description} arrow placement=\"top\">\n <Typography\n variant=\"body1\"\n style={{\n maxWidth: 208,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {data?.shortDescription}\n </Typography>\n </Tooltip>\n </TableCell>\n <TableCell align=\"left\" className={classes.tableCellStyle}>\n {convertDateFormat(data?.sysCreatedOn)}\n </TableCell>\n <TableCell align=\"left\" className={classes.tableCellStyle}>\n {getPriorityValue(data?.priority)}\n </TableCell>\n\n <TableCell align=\"left\" className={classes.tableCellStyle}>\n {getIncidentStateValue(data?.incidentState)}\n </TableCell>\n <TableCell align=\"left\" className={classes.tableCellStyle}>\n <IconButton onClick={() => window.open(data.url, '_blank')}>\n <OpenInNewIcon fontSize=\"small\" style={{ color: 'inherit' }} />\n </IconButton>\n </TableCell>\n </TableRow>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AA+BA,MAAM,SAAA,GAAY,WAAW,OAAO;AAAA,EAClC,cAAgB,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,QAAU,EAAA;AAAA;AAEd,CAAE,CAAA,CAAA;AAEK,MAAM,iBAAoB,GAAA,CAAC,EAAE,IAAA,EAAoC,KAAA;AACtE,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EACE,uBAAA,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAK,EAAA,IAAA;AAAA,MACL,EAAI,EAAA;AAAA,QACF,QAAU,EAAA,UAAA;AAAA,QACV,kCAAA,EAAoC,EAAE,MAAA,EAAQ,CAAE,EAAA;AAAA,QAChD,YAAc,EAAA;AAAA,OAChB;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,SAAA,EAAA,EAAU,WAAU,IAAK,EAAA,KAAA,EAAM,OAAM,SAAW,EAAA,OAAA,CAAQ,cACtD,EAAA,QAAA,EAAA,IAAA,CAAK,MACR,EAAA,CAAA;AAAA,wBACC,GAAA,CAAA,SAAA,EAAA,EAAU,KAAM,EAAA,MAAA,EAAO,WAAW,OAAQ,CAAA,cAAA,EACzC,QAAC,kBAAA,GAAA,CAAA,OAAA,EAAA,EAAQ,OAAO,IAAM,EAAA,WAAA,EAAa,KAAK,EAAA,IAAA,EAAC,WAAU,KACjD,EAAA,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAQ,EAAA,OAAA;AAAA,YACR,KAAO,EAAA;AAAA,cACL,QAAU,EAAA,GAAA;AAAA,cACV,UAAY,EAAA,QAAA;AAAA,cACZ,QAAU,EAAA,QAAA;AAAA,cACV,YAAc,EAAA;AAAA,aAChB;AAAA,YAEC,QAAM,EAAA,IAAA,EAAA;AAAA;AAAA,WAEX,CACF,EAAA,CAAA;AAAA,wBACA,GAAA,CAAC,SAAU,EAAA,EAAA,KAAA,EAAM,MAAO,EAAA,SAAA,EAAW,QAAQ,cACxC,EAAA,QAAA,EAAA,iBAAA,CAAkB,IAAM,EAAA,YAAY,CACvC,EAAA,CAAA;AAAA,wBACA,GAAA,CAAC,SAAU,EAAA,EAAA,KAAA,EAAM,MAAO,EAAA,SAAA,EAAW,QAAQ,cACxC,EAAA,QAAA,EAAA,gBAAA,CAAiB,IAAM,EAAA,QAAQ,CAClC,EAAA,CAAA;AAAA,wBAEA,GAAA,CAAC,SAAU,EAAA,EAAA,KAAA,EAAM,MAAO,EAAA,SAAA,EAAW,QAAQ,cACxC,EAAA,QAAA,EAAA,qBAAA,CAAsB,IAAM,EAAA,aAAa,CAC5C,EAAA,CAAA;AAAA,wBACA,GAAA,CAAC,SAAU,EAAA,EAAA,KAAA,EAAM,MAAO,EAAA,SAAA,EAAW,OAAQ,CAAA,cAAA,EACzC,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,OAAS,EAAA,MAAM,MAAO,CAAA,IAAA,CAAK,IAAK,CAAA,GAAA,EAAK,QAAQ,CAAA,EACvD,QAAC,kBAAA,GAAA,CAAA,aAAA,EAAA,EAAc,QAAS,EAAA,OAAA,EAAQ,KAAO,EAAA,EAAE,KAAO,EAAA,SAAA,EAAa,EAAA,CAAA,EAC/D,CACF,EAAA;AAAA;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -0,0 +1,14 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { CustomSvgIcon } from './CustomSvgIcon.esm.js';
3
+
4
+ const ModerateIcon = (props) => /* @__PURE__ */ jsx(
5
+ CustomSvgIcon,
6
+ {
7
+ viewBox: "0 0 16 16",
8
+ path: /* @__PURE__ */ jsx("path", { d: "M2.66675 11.3333V9.33332H13.3334V11.3333H2.66675ZM2.66675 6.66666V4.66666H13.3334V6.66666H2.66675Z" }),
9
+ ...props
10
+ }
11
+ );
12
+
13
+ export { ModerateIcon };
14
+ //# sourceMappingURL=ModerateIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModerateIcon.esm.js","sources":["../../../src/components/Servicenow/ModerateIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CustomSvgIcon } from './CustomSvgIcon';\n\nexport const ModerateIcon = (props: any) => (\n <CustomSvgIcon\n viewBox=\"0 0 16 16\"\n path={\n <path d=\"M2.66675 11.3333V9.33332H13.3334V11.3333H2.66675ZM2.66675 6.66666V4.66666H13.3334V6.66666H2.66675Z\" />\n }\n {...props}\n />\n);\n"],"names":[],"mappings":";;;AAkBa,MAAA,YAAA,GAAe,CAAC,KAC3B,qBAAA,GAAA;AAAA,EAAC,aAAA;AAAA,EAAA;AAAA,IACC,OAAQ,EAAA,WAAA;AAAA,IACR,IACE,kBAAA,GAAA,CAAC,MAAK,EAAA,EAAA,CAAA,EAAE,oGAAqG,EAAA,CAAA;AAAA,IAE9G,GAAG;AAAA;AACN;;;;"}