@oneuptime/common 14.0.2 → 14.0.3
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/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentService.ts +210 -10
- package/Server/Services/IncidentStateTimelineService.ts +24 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Permission.ts +48 -0
- package/Types/Rum/SessionReplay.ts +25 -6
- package/Types/Rum/WebVitals.ts +52 -0
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +95 -17
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Utils/PermissionGate.ts +11 -2
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentService.js +164 -12
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +66 -14
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ export const WebVitalDefinitions = [
|
|
|
3
3
|
{
|
|
4
4
|
key: "lcp",
|
|
5
5
|
label: "Largest Contentful Paint",
|
|
6
|
+
description: "How long until the biggest image or block of text on screen has rendered - roughly when the page looks loaded to the visitor.",
|
|
6
7
|
unit: "ms",
|
|
7
8
|
thresholds: { warn: 2500, danger: 4000 },
|
|
8
9
|
names: [
|
|
@@ -15,6 +16,7 @@ export const WebVitalDefinitions = [
|
|
|
15
16
|
{
|
|
16
17
|
key: "inp",
|
|
17
18
|
label: "Interaction to Next Paint",
|
|
19
|
+
description: "How quickly the page reacts to clicks, taps and key presses: the delay before the screen visibly updates, for close to the slowest interaction on the page.",
|
|
18
20
|
unit: "ms",
|
|
19
21
|
thresholds: { warn: 200, danger: 500 },
|
|
20
22
|
names: [
|
|
@@ -27,6 +29,7 @@ export const WebVitalDefinitions = [
|
|
|
27
29
|
{
|
|
28
30
|
key: "cls",
|
|
29
31
|
label: "Cumulative Layout Shift",
|
|
32
|
+
description: "How much the page jumps around while it loads - content moving under the visitor's cursor or finger. A score, not a time: lower is better and 0 means nothing moved.",
|
|
30
33
|
unit: "score",
|
|
31
34
|
thresholds: { warn: 0.1, danger: 0.25 },
|
|
32
35
|
names: [
|
|
@@ -39,6 +42,7 @@ export const WebVitalDefinitions = [
|
|
|
39
42
|
{
|
|
40
43
|
key: "fcp",
|
|
41
44
|
label: "First Contentful Paint",
|
|
45
|
+
description: "How long until the first text or image appears, so the visitor can see the page has started loading.",
|
|
42
46
|
unit: "ms",
|
|
43
47
|
thresholds: { warn: 1800, danger: 3000 },
|
|
44
48
|
names: [
|
|
@@ -51,6 +55,7 @@ export const WebVitalDefinitions = [
|
|
|
51
55
|
{
|
|
52
56
|
key: "ttfb",
|
|
53
57
|
label: "Time to First Byte",
|
|
58
|
+
description: "How long the browser waited for the first byte of the page from your server, including redirects, looking up the address and connecting.",
|
|
54
59
|
unit: "ms",
|
|
55
60
|
thresholds: { warn: 800, danger: 1800 },
|
|
56
61
|
names: [
|
|
@@ -61,4 +66,24 @@ export const WebVitalDefinitions = [
|
|
|
61
66
|
],
|
|
62
67
|
},
|
|
63
68
|
];
|
|
69
|
+
// A threshold the way a person would say it: "2.5 s", "800 ms", "0.1".
|
|
70
|
+
export function formatWebVitalThreshold(value, unit) {
|
|
71
|
+
if (unit === "score") {
|
|
72
|
+
return String(value);
|
|
73
|
+
}
|
|
74
|
+
if (value < 1000) {
|
|
75
|
+
return `${value} ms`;
|
|
76
|
+
}
|
|
77
|
+
return `${Number((value / 1000).toFixed(2))} s`;
|
|
78
|
+
}
|
|
79
|
+
/*
|
|
80
|
+
* The Good / Poor limits in words, matching how the overview rates a value:
|
|
81
|
+
* below `warn` is Good, at or above `danger` is Poor, and anything between
|
|
82
|
+
* needs work.
|
|
83
|
+
*/
|
|
84
|
+
export function describeWebVitalThresholds(definition) {
|
|
85
|
+
const warn = formatWebVitalThreshold(definition.thresholds.warn, definition.unit);
|
|
86
|
+
const danger = formatWebVitalThreshold(definition.thresholds.danger, definition.unit);
|
|
87
|
+
return `Good below ${warn}; poor at ${danger} or more.`;
|
|
88
|
+
}
|
|
64
89
|
//# sourceMappingURL=WebVitals.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebVitals.js","sourceRoot":"","sources":["../../../../Types/Rum/WebVitals.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebVitals.js","sourceRoot":"","sources":["../../../../Types/Rum/WebVitals.ts"],"names":[],"mappings":"AAcA,uEAAuE;AACvE,MAAM,CAAC,MAAM,mBAAmB,GAA8B;IAC5D;QACE,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,+HAA+H;QACjI,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QACxC,KAAK,EAAE;YACL,eAAe;YACf,kCAAkC;YAClC,0BAA0B;YAC1B,gBAAgB;SACjB;KACF;IACD;QACE,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,6JAA6J;QAC/J,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;QACtC,KAAK,EAAE;YACL,eAAe;YACf,mCAAmC;YACnC,2BAA2B;YAC3B,gBAAgB;SACjB;KACF;IACD;QACE,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,sKAAsK;QACxK,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QACvC,KAAK,EAAE;YACL,eAAe;YACf,iCAAiC;YACjC,yBAAyB;YACzB,gBAAgB;SACjB;KACF;IACD;QACE,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,sGAAsG;QACxG,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QACxC,KAAK,EAAE;YACL,eAAe;YACf,gCAAgC;YAChC,wBAAwB;YACxB,gBAAgB;SACjB;KACF;IACD;QACE,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,0IAA0I;QAC5I,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QACvC,KAAK,EAAE;YACL,gBAAgB;YAChB,4BAA4B;YAC5B,oBAAoB;YACpB,iBAAiB;SAClB;KACF;CACF,CAAC;AAEF,uEAAuE;AACvE,MAAM,UAAU,uBAAuB,CACrC,KAAa,EACb,IAAgC;IAEhC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;QACjB,OAAO,GAAG,KAAK,KAAK,CAAC;IACvB,CAAC;IAED,OAAO,GAAG,MAAM,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,UAA2D;IAE3D,MAAM,IAAI,GAAW,uBAAuB,CAC1C,UAAU,CAAC,UAAU,CAAC,IAAI,EAC1B,UAAU,CAAC,IAAI,CAChB,CAAC;IACF,MAAM,MAAM,GAAW,uBAAuB,CAC5C,UAAU,CAAC,UAAU,CAAC,MAAM,EAC5B,UAAU,CAAC,IAAI,CAChB,CAAC;IAEF,OAAO,cAAc,IAAI,aAAa,MAAM,WAAW,CAAC;AAC1D,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Link from "../Link/Link";
|
|
2
2
|
import useTranslateValue from "../../Utils/Translation";
|
|
3
|
+
import InfoTooltip from "../Tooltip/InfoTooltip";
|
|
3
4
|
import React from "react";
|
|
4
5
|
export var Size;
|
|
5
6
|
(function (Size) {
|
|
@@ -18,6 +19,7 @@ const FieldLabelElement = (props) => {
|
|
|
18
19
|
translatedTitle && (React.createElement("label", { className: `${props.size || "text-xs"} font-semibold uppercase tracking-widest ${isCardStyle ? "text-gray-500" : "text-gray-500"} flex items-center gap-2` },
|
|
19
20
|
React.createElement("span", { className: `${props.alignClassName} flex items-center gap-1.5` },
|
|
20
21
|
translatedTitle,
|
|
22
|
+
React.createElement(InfoTooltip, { label: translatedTitle, text: props.tooltip, className: "relative z-10 normal-case tracking-normal" }),
|
|
21
23
|
React.createElement("span", { className: "w-1 h-1 rounded-full bg-gray-300" })),
|
|
22
24
|
props.sideLink && translatedSideLinkText && ((_b = props.sideLink) === null || _b === void 0 ? void 0 : _b.url) && (React.createElement(Link, { to: (_c = props.sideLink) === null || _c === void 0 ? void 0 : _c.url, className: "inline-flex items-center gap-1 text-indigo-500 hover:text-indigo-600 transition-all duration-200 font-medium normal-case tracking-normal text-xs hover:underline underline-offset-2" },
|
|
23
25
|
translatedSideLinkText,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldLabel.js","sourceRoot":"","sources":["../../../../../UI/Components/Detail/FieldLabel.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,cAAc,CAAC;AAEhC,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAA0C,MAAM,OAAO,CAAC;AAE/D,MAAM,CAAN,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,0BAAkB,CAAA;IAClB,4BAAoB,CAAA;IACpB,yBAAiB,CAAA;AACnB,CAAC,EAJW,IAAI,KAAJ,IAAI,QAIf;
|
|
1
|
+
{"version":3,"file":"FieldLabel.js","sourceRoot":"","sources":["../../../../../UI/Components/Detail/FieldLabel.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,cAAc,CAAC;AAEhC,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAA0C,MAAM,OAAO,CAAC;AAE/D,MAAM,CAAN,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,0BAAkB,CAAA;IAClB,4BAAoB,CAAA;IACpB,yBAAiB,CAAA;AACnB,CAAC,EAJW,IAAI,KAAJ,IAAI,QAIf;AAaD,MAAM,iBAAiB,GAAsC,CAC3D,KAAqB,EACP,EAAE;;IAChB,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAChE,MAAM,eAAe,GAAuB,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,qBAAqB,GACzB,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,MAAM,sBAAsB,GAAuB,eAAe,CAChE,MAAA,KAAK,CAAC,QAAQ,0CAAE,IAAI,CACrB,CAAC;IACF,MAAM,WAAW,GAAY,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC;IAExD,OAAO,CACL,6BAAK,SAAS,EAAC,WAAW;QACvB,eAAe,IAAI,CAClB,+BACE,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,SAAS,4CACnC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAClC,0BAA0B;YAE1B,8BAAM,SAAS,EAAE,GAAG,KAAK,CAAC,cAAc,4BAA4B;gBACjE,eAAe;gBAChB,oBAAC,WAAW,IACV,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,KAAK,CAAC,OAAO,EACnB,SAAS,EAAC,2CAA2C,GACrD;gBACF,8BAAM,SAAS,EAAC,kCAAkC,GAAQ,CACrD;YACN,KAAK,CAAC,QAAQ,IAAI,sBAAsB,KAAI,MAAA,KAAK,CAAC,QAAQ,0CAAE,GAAG,CAAA,IAAI,CAClE,oBAAC,IAAI,IACH,EAAE,EAAE,MAAA,KAAK,CAAC,QAAQ,0CAAE,GAAG,EACvB,SAAS,EAAC,qLAAqL;gBAE9L,sBAAsB;gBACvB,6BACE,SAAS,EAAC,SAAS,EACnB,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,WAAW,EACnB,MAAM,EAAC,cAAc;oBAErB,8BACE,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,WAAW,EAAE,CAAC,EACd,CAAC,EAAC,8EAA8E,GAChF,CACE,CACD,CACR,CACK,CACT;QACA,qBAAqB,IAAI,CACxB,2BACE,SAAS,EAAE,GAAG,KAAK,CAAC,cAAc,+CAA+C,IAEhF,qBAAqB,CACpB,CACL,CACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import FieldLabelElement from "../Detail/FieldLabel";
|
|
2
2
|
import React from "react";
|
|
3
3
|
const InfoCard = (props) => {
|
|
4
|
+
var _a;
|
|
4
5
|
const isClickable = Boolean(props.onClick);
|
|
5
6
|
/*
|
|
6
7
|
* A selected card swaps its border rather than adding one: Tailwind emits
|
|
@@ -10,6 +11,26 @@ const InfoCard = (props) => {
|
|
|
10
11
|
const borderClassName = isClickable && props.isSelected
|
|
11
12
|
? "border-indigo-500 ring-1 ring-indigo-500"
|
|
12
13
|
: "border-gray-200";
|
|
14
|
+
/*
|
|
15
|
+
* A clickable card with a tooltip cannot stay a role="button" div: the (i)
|
|
16
|
+
* is a button of its own, and a button's children are presentational, so
|
|
17
|
+
* screen readers would never reach it. The card becomes a plain container
|
|
18
|
+
* with a real button laid over it, and the (i) sits above that button
|
|
19
|
+
* (FieldLabel lifts it with relative z-10). Cards without a tooltip keep
|
|
20
|
+
* the markup below, unchanged.
|
|
21
|
+
*/
|
|
22
|
+
if (isClickable && ((_a = props.tooltip) === null || _a === void 0 ? void 0 : _a.trim())) {
|
|
23
|
+
return (React.createElement("div", { className: `relative rounded-xl bg-white border ${borderClassName} shadow-sm hover:shadow-md transition-shadow duration-200 p-5 ${props.className || ""}` },
|
|
24
|
+
React.createElement("button", { type: "button", onClick: props.onClick, "aria-pressed": props.isSelected !== undefined
|
|
25
|
+
? Boolean(props.isSelected)
|
|
26
|
+
: undefined, "aria-label": props.ariaLabel ||
|
|
27
|
+
(typeof props.value === "string"
|
|
28
|
+
? `${props.title} ${props.value}`
|
|
29
|
+
: props.title), className: "absolute inset-0 rounded-xl cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2" }),
|
|
30
|
+
React.createElement("div", { className: "mb-2" },
|
|
31
|
+
React.createElement(FieldLabelElement, { title: props.title, tooltip: props.tooltip })),
|
|
32
|
+
React.createElement("div", { className: props.textClassName || "text-gray-900" }, props.value)));
|
|
33
|
+
}
|
|
13
34
|
return (React.createElement("div", { onClick: props.onClick,
|
|
14
35
|
/*
|
|
15
36
|
* Click handlers on a div are invisible to the keyboard and to screen
|
|
@@ -30,7 +51,7 @@ const InfoCard = (props) => {
|
|
|
30
51
|
}
|
|
31
52
|
: undefined, className: `rounded-xl bg-white border ${borderClassName} shadow-sm hover:shadow-md transition-shadow duration-200 p-5 ${isClickable ? "cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2" : ""} ${props.className || ""}` },
|
|
32
53
|
React.createElement("div", { className: "mb-2" },
|
|
33
|
-
React.createElement(FieldLabelElement, { title: props.title })),
|
|
54
|
+
React.createElement(FieldLabelElement, { title: props.title, tooltip: props.tooltip })),
|
|
34
55
|
React.createElement("div", { className: props.textClassName || "text-gray-900" }, props.value)));
|
|
35
56
|
};
|
|
36
57
|
export default InfoCard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfoCard.js","sourceRoot":"","sources":["../../../../../UI/Components/InfoCard/InfoCard.tsx"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAA0C,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"InfoCard.js","sourceRoot":"","sources":["../../../../../UI/Components/InfoCard/InfoCard.tsx"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAA0C,MAAM,OAAO,CAAC;AAyB/D,MAAM,QAAQ,GAAsC,CAClD,KAAqB,EACP,EAAE;;IAChB,MAAM,WAAW,GAAY,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEpD;;;;OAIG;IACH,MAAM,eAAe,GACnB,WAAW,IAAI,KAAK,CAAC,UAAU;QAC7B,CAAC,CAAC,0CAA0C;QAC5C,CAAC,CAAC,iBAAiB,CAAC;IAExB;;;;;;;OAOG;IACH,IAAI,WAAW,KAAI,MAAA,KAAK,CAAC,OAAO,0CAAE,IAAI,EAAE,CAAA,EAAE,CAAC;QACzC,OAAO,CACL,6BACE,SAAS,EAAE,uCAAuC,eAAe,iEAAiE,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE;YAEzJ,gCACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,KAAK,CAAC,OAAO,kBAEpB,KAAK,CAAC,UAAU,KAAK,SAAS;oBAC5B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;oBAC3B,CAAC,CAAC,SAAS,gBAQb,KAAK,CAAC,SAAS;oBACf,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;wBAC9B,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE;wBACjC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAElB,SAAS,EAAC,8IAA8I,GACxJ;YACF,6BAAK,SAAS,EAAC,MAAM;gBACnB,oBAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAC7D;YACN,6BAAK,SAAS,EAAE,KAAK,CAAC,aAAa,IAAI,eAAe,IACnD,KAAK,CAAC,KAAK,CACR,CACF,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,6BACE,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB;;;;WAIG;QACH,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EACxC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,kBASnC,WAAW,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;YAC3C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YAC3B,CAAC,CAAC,SAAS,gBAEH,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EACrD,SAAS,EACP,WAAW;YACT,CAAC,CAAC,CAAC,KAA0C,EAAE,EAAE;;gBAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;oBAC/C,OAAO;gBACT,CAAC;gBACD,2DAA2D;gBAC3D,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAA,KAAK,CAAC,OAAO,qDAAI,CAAC;YACpB,CAAC;YACH,CAAC,CAAC,SAAS,EAEf,SAAS,EAAE,8BAA8B,eAAe,iEAAiE,WAAW,CAAC,CAAC,CAAC,kHAAkH,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE;QAEzR,6BAAK,SAAS,EAAC,MAAM;YACnB,oBAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAC7D;QACN,6BAAK,SAAS,EAAE,KAAK,CAAC,aAAa,IAAI,eAAe,IACnD,KAAK,CAAC,KAAK,CACR,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -152,9 +152,38 @@ const BaseModelTable = (props) => {
|
|
|
152
152
|
const [tableView, setTableView] = useState(null);
|
|
153
153
|
const matchBulkSelectedItemByField = ((_a = props.bulkActions) === null || _a === void 0 ? void 0 : _a.matchBulkSelectedItemByField) || "_id";
|
|
154
154
|
const model = new props.modelType();
|
|
155
|
+
/*
|
|
156
|
+
* The header's create button, "<verb> <noun>". Translating the two words
|
|
157
|
+
* separately reads the verb out of context - "Link" comes back as the noun
|
|
158
|
+
* in many languages, and word order differs - so the whole phrase is looked
|
|
159
|
+
* up first ("Link Alert") and the word-by-word join is only the fallback
|
|
160
|
+
* for a phrase with no entry of its own. In English both are the same.
|
|
161
|
+
*/
|
|
162
|
+
const getCreateButtonTitle = () => {
|
|
163
|
+
const verb = props.createVerb || "Create";
|
|
164
|
+
const noun = props.singularName || model.singularName || "";
|
|
165
|
+
if (noun) {
|
|
166
|
+
const phrase = `${verb} ${noun}`;
|
|
167
|
+
const translatedPhrase = tx(phrase);
|
|
168
|
+
if (translatedPhrase && translatedPhrase !== phrase) {
|
|
169
|
+
return translatedPhrase;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return `${tx(verb)} ${tx(noun)}`;
|
|
173
|
+
};
|
|
155
174
|
const getActionGate = (action) => {
|
|
175
|
+
var _a, _b;
|
|
176
|
+
/*
|
|
177
|
+
* A table that calls its delete "Unlink" must not say the locked button
|
|
178
|
+
* would delete the row's noun ("permission to delete this Alert"). Keyed
|
|
179
|
+
* on deleteVerb alone: deleteButtonText is also set by tables such as
|
|
180
|
+
* "Remove from Project", which keep the default "delete" sentence.
|
|
181
|
+
*/
|
|
156
182
|
const result = PermissionGate.check(model, action, {
|
|
157
183
|
singularName: props.singularName || model.singularName || undefined,
|
|
184
|
+
verb: action === ModelAction.Delete
|
|
185
|
+
? ((_b = (_a = props.bulkActions) === null || _a === void 0 ? void 0 : _a.deleteVerb) === null || _b === void 0 ? void 0 : _b.trim()) || undefined
|
|
186
|
+
: undefined,
|
|
158
187
|
});
|
|
159
188
|
if (result.isAllowed) {
|
|
160
189
|
return { show: true, disabled: false, tooltip: undefined };
|
|
@@ -1535,7 +1564,7 @@ const BaseModelTable = (props) => {
|
|
|
1535
1564
|
createGate.show &&
|
|
1536
1565
|
showAs !== ShowAs.OrderedStatesList) {
|
|
1537
1566
|
headerbuttons.push({
|
|
1538
|
-
title:
|
|
1567
|
+
title: getCreateButtonTitle(),
|
|
1539
1568
|
buttonStyle: ButtonStyleType.NORMAL,
|
|
1540
1569
|
buttonSize: ButtonSize.Normal,
|
|
1541
1570
|
className: "",
|
|
@@ -1770,6 +1799,7 @@ const BaseModelTable = (props) => {
|
|
|
1770
1799
|
};
|
|
1771
1800
|
}, [showColumnCustomizationModal, attributeColumnKey]);
|
|
1772
1801
|
const setActionSchema = () => {
|
|
1802
|
+
var _a, _b, _c;
|
|
1773
1803
|
const permissions = PermissionUtil.getAllPermissions();
|
|
1774
1804
|
const actionsSchema = [];
|
|
1775
1805
|
if (props.showViewIdButton) {
|
|
@@ -1862,10 +1892,14 @@ const BaseModelTable = (props) => {
|
|
|
1862
1892
|
});
|
|
1863
1893
|
}
|
|
1864
1894
|
const deleteGate = getActionGate(ModelAction.Delete);
|
|
1895
|
+
/* The row action wears the same icon as the bulk one it stands for. */
|
|
1896
|
+
const rowDeleteIcon = (((_b = (_a = props.bulkActions) === null || _a === void 0 ? void 0 : _a.deleteVerb) === null || _b === void 0 ? void 0 : _b.trim()) &&
|
|
1897
|
+
((_c = props.bulkActions) === null || _c === void 0 ? void 0 : _c.deleteIcon)) ||
|
|
1898
|
+
IconProp.Trash;
|
|
1865
1899
|
if (props.isDeleteable && deleteGate.show) {
|
|
1866
1900
|
actionsSchema.push({
|
|
1867
1901
|
title: tx(props.deleteButtonText || "Delete"),
|
|
1868
|
-
icon:
|
|
1902
|
+
icon: rowDeleteIcon,
|
|
1869
1903
|
buttonStyleType: ButtonStyleType.DANGER_OUTLINE,
|
|
1870
1904
|
disabled: deleteGate.disabled,
|
|
1871
1905
|
tooltip: deleteGate.tooltip,
|
|
@@ -1936,25 +1970,35 @@ const BaseModelTable = (props) => {
|
|
|
1936
1970
|
itemsOnPage,
|
|
1937
1971
|
]);
|
|
1938
1972
|
const getDeleteBulkAction = () => {
|
|
1973
|
+
var _a, _b, _c;
|
|
1974
|
+
/*
|
|
1975
|
+
* A table that names its own verb ("Unlink") removes relationships, not
|
|
1976
|
+
* things, so its sentence drops "This action cannot be undone" - that
|
|
1977
|
+
* would say the opposite of the warning it usually appends.
|
|
1978
|
+
*/
|
|
1979
|
+
const deleteVerb = ((_b = (_a = props.bulkActions) === null || _a === void 0 ? void 0 : _a.deleteVerb) === null || _b === void 0 ? void 0 : _b.trim()) || undefined;
|
|
1980
|
+
const getItemLabel = (items) => {
|
|
1981
|
+
return items.length === 1
|
|
1982
|
+
? props.singularName || model.singularName || "item"
|
|
1983
|
+
: props.pluralName || model.pluralName || "items";
|
|
1984
|
+
};
|
|
1939
1985
|
return {
|
|
1940
|
-
title: "Delete",
|
|
1986
|
+
title: deleteVerb || "Delete",
|
|
1941
1987
|
buttonStyleType: ButtonStyleType.DANGER,
|
|
1942
|
-
icon: IconProp.Trash,
|
|
1988
|
+
icon: (deleteVerb && ((_c = props.bulkActions) === null || _c === void 0 ? void 0 : _c.deleteIcon)) || IconProp.Trash,
|
|
1943
1989
|
confirmMessage: (items) => {
|
|
1944
1990
|
var _a;
|
|
1945
|
-
const itemLabel = items
|
|
1946
|
-
? props.singularName || model.singularName || "item"
|
|
1947
|
-
: props.pluralName || model.pluralName || "items";
|
|
1991
|
+
const itemLabel = getItemLabel(items);
|
|
1948
1992
|
const warning = ((_a = props.bulkActions) === null || _a === void 0 ? void 0 : _a.deleteConfirmationWarning)
|
|
1949
1993
|
? ` ${props.bulkActions.deleteConfirmationWarning}`
|
|
1950
1994
|
: "";
|
|
1995
|
+
if (deleteVerb) {
|
|
1996
|
+
return `Are you sure you want to ${deleteVerb.toLowerCase()} ${items.length} ${itemLabel.toLowerCase()}?${warning}`;
|
|
1997
|
+
}
|
|
1951
1998
|
return `Are you sure you want to delete ${items.length} ${itemLabel}? This action cannot be undone.${warning}`;
|
|
1952
1999
|
},
|
|
1953
2000
|
confirmTitle: (items) => {
|
|
1954
|
-
|
|
1955
|
-
? props.singularName || model.singularName || "item"
|
|
1956
|
-
: props.pluralName || model.pluralName || "items";
|
|
1957
|
-
return `Delete ${items.length} ${itemLabel}`;
|
|
2001
|
+
return `${deleteVerb || "Delete"} ${items.length} ${getItemLabel(items)}`;
|
|
1958
2002
|
},
|
|
1959
2003
|
confirmButtonStyleType: ButtonStyleType.DANGER,
|
|
1960
2004
|
onClick: async ({ items, onProgressInfo, onBulkActionStart, onBulkActionEnd, }) => {
|
|
@@ -2051,7 +2095,7 @@ const BaseModelTable = (props) => {
|
|
|
2051
2095
|
: "rounded-lg border-2 border-gray-200 p-6 pt-0 pb-5", tableContainerClassName: props.cardProps ? "" : "overflow-hidden rounded", onFilterRefreshClick: async () => {
|
|
2052
2096
|
await getFilterDropdownItems();
|
|
2053
2097
|
}, bulkActions: (() => {
|
|
2054
|
-
var _a, _b;
|
|
2098
|
+
var _a, _b, _c, _d;
|
|
2055
2099
|
const bulkDeleteGate = getActionGate(ModelAction.Delete);
|
|
2056
2100
|
/*
|
|
2057
2101
|
* Whether to auto-add the default Delete still follows the model
|
|
@@ -2077,7 +2121,16 @@ const BaseModelTable = (props) => {
|
|
|
2077
2121
|
* Table derives the row checkboxes from this array being non-empty,
|
|
2078
2122
|
* so injecting a locked Delete into an otherwise empty array would
|
|
2079
2123
|
* grow a selection column onto tables that have never had one.
|
|
2124
|
+
*
|
|
2125
|
+
* A page's own button counts as the delete action when it carries
|
|
2126
|
+
* the title the default one would have: "Delete", or the table's
|
|
2127
|
+
* deleteVerb.
|
|
2080
2128
|
*/
|
|
2129
|
+
const deleteActionTitles = ["Delete"];
|
|
2130
|
+
const bulkDeleteVerb = ((_d = (_c = props.bulkActions) === null || _c === void 0 ? void 0 : _c.deleteVerb) === null || _d === void 0 ? void 0 : _d.trim()) || undefined;
|
|
2131
|
+
if (bulkDeleteVerb) {
|
|
2132
|
+
deleteActionTitles.push(bulkDeleteVerb);
|
|
2133
|
+
}
|
|
2081
2134
|
const alreadyHasDeleteAction = sourceButtons.some((action) => {
|
|
2082
2135
|
if (action === ModalTableBulkDefaultActions.Delete) {
|
|
2083
2136
|
return true;
|
|
@@ -2085,8 +2138,7 @@ const BaseModelTable = (props) => {
|
|
|
2085
2138
|
if (typeof action === "object" &&
|
|
2086
2139
|
action !== null &&
|
|
2087
2140
|
"title" in action &&
|
|
2088
|
-
action.title
|
|
2089
|
-
"Delete") {
|
|
2141
|
+
deleteActionTitles.includes(action.title)) {
|
|
2090
2142
|
return true;
|
|
2091
2143
|
}
|
|
2092
2144
|
return false;
|