Skip to content

Commit e94b80b

Browse files
authored
Merge pull request #475 from PagerDuty/release/0.13.1-beta.0
2 parents 7a2793d + 8d3726f commit e94b80b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1732
-1834
lines changed

.eslintrc.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ module.exports = {
3434
'react-refresh',
3535
],
3636
rules: {
37-
'max-len': [WARN, { code: 120, ignorePattern: '^import\\W.*', ignoreTrailingComments: true }],
37+
'max-len': [WARN, { code: 180, ignorePattern: '^import\\W.*', ignoreTrailingComments: true }],
3838
'object-curly-newline': [
3939
WARN,
4040
{ ObjectPattern: { multiline: true, minProperties: 1 }, ImportDeclaration: 'always' },
4141
],
4242
'react/prop-types': OFF, // To be done in another refactor
43-
// 'react/jsx-filename-extension': [ERROR, { extensions: ['.js', '.jsx'] }],
43+
'react/jsx-filename-extension': [ERROR, { extensions: ['.js', '.jsx'] }],
4444
'no-param-reassign': [ERROR, { props: true, ignorePropertyModificationsFor: ['draft'] }],
4545
'no-use-before-define': [ERROR, { functions: false }],
4646
'no-plusplus': [ERROR, { allowForLoopAfterthoughts: true }],
47-
'react-refresh/only-export-components': OFF, // To be done in another refactor
4847
'react-hooks/exhaustive-deps': OFF, // To be done in another refactor
4948
'react-hooks/rules-of-hooks': OFF, // To be done in another refactor
5049
},

cypress/e2e/Settings/settings.spec.js

Lines changed: 108 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
updateDarkMode,
1313
updateRelativeDates,
1414
manageIncidentTableColumns,
15-
manageCustomAlertColumnDefinitions,
15+
manageCustomColumnDefinitions,
1616
checkIncidentCellContentAllRows,
1717
checkActionAlertsModalContent,
1818
} from '../../support/util/common';
@@ -141,28 +141,117 @@ describe('Manage Settings', { failFast: { enabled: true } }, () => {
141141
});
142142

143143
it('Add valid custom alert column to incident table', () => {
144-
const customAlertColumnDefinitions = ['Quote:details.quote'];
145-
manageCustomAlertColumnDefinitions(customAlertColumnDefinitions);
146-
customAlertColumnDefinitions.forEach((columnName) => {
147-
const header = columnName.split(':')[0];
148-
cy.get(`[data-column-name="${header}"]`).scrollIntoView().should('be.visible');
149-
cy.get(`[data-incident-header="${header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
150-
// eslint-disable-next-line no-unused-expressions
151-
expect($el.text()).to.exist;
152-
});
144+
const customColumnDefinitions = [
145+
{ header: 'Quote', accessorPath: 'details.quote', expression: '' },
146+
];
147+
manageCustomColumnDefinitions(customColumnDefinitions);
148+
customColumnDefinitions.forEach((column) => {
149+
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
150+
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(
151+
($el) => {
152+
// eslint-disable-next-line no-unused-expressions
153+
expect($el.text()).to.exist;
154+
// Quote exists in the alert body, so it should not be empty
155+
expect($el.text()).to.not.equal('--');
156+
expect($el.text().length).to.be.greaterThan(20);
157+
},
158+
);
153159
});
154160
});
155161

156162
it('Add valid custom alert column with JSON path containing spaces to incident table', () => {
157-
const customAlertColumnDefinitions = ["Fav Flavour:details.['favorite ice cream flavor']"];
158-
manageCustomAlertColumnDefinitions(customAlertColumnDefinitions);
159-
customAlertColumnDefinitions.forEach((columnName) => {
160-
const header = columnName.split(':')[0];
161-
cy.get(`[data-column-name="${header}"]`).scrollIntoView().should('be.visible');
162-
cy.get(`[data-incident-header="${header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
163-
// eslint-disable-next-line no-unused-expressions
164-
expect($el.text()).to.exist;
165-
});
163+
const customColumnDefinitions = [
164+
{
165+
header: 'Fav Flavour',
166+
accessorPath: "details.['favorite ice cream flavor']",
167+
expression: '',
168+
},
169+
];
170+
manageCustomColumnDefinitions(customColumnDefinitions);
171+
customColumnDefinitions.forEach((column) => {
172+
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
173+
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(
174+
($el) => {
175+
// eslint-disable-next-line no-unused-expressions
176+
expect($el.text()).to.exist;
177+
// Fav Flavour doesn't exist in the alert body, so it should be empty
178+
expect($el.text()).to.equal('--');
179+
},
180+
);
181+
});
182+
});
183+
184+
it('Add valid custom computed column to incident table', () => {
185+
const customColumnDefinitions = [
186+
{
187+
header: 'CI',
188+
accessorPath: 'first_trigger_log_entry.channel.details',
189+
expression: '(.*.example.com)',
190+
},
191+
];
192+
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
193+
customColumnDefinitions.forEach((column) => {
194+
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
195+
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(
196+
($el) => {
197+
// eslint-disable-next-line no-unused-expressions
198+
expect($el.text()).to.exist;
199+
// CI doesn't exist in the alert body, so it should be empty
200+
expect($el.text()).to.equal('--');
201+
},
202+
);
203+
});
204+
});
205+
206+
it('Add two valid custom computed column to incident table with different expressions', () => {
207+
const customColumnDefinitions = [
208+
{
209+
header: 'CI',
210+
accessorPath: 'first_trigger_log_entry.channel.details',
211+
expression: '(.*.example.com)',
212+
},
213+
{
214+
header: 'Category',
215+
accessorPath: 'first_trigger_log_entry.channel.details',
216+
expression: 'Category(.*)',
217+
},
218+
];
219+
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
220+
customColumnDefinitions.forEach((column) => {
221+
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
222+
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(
223+
($el) => {
224+
// eslint-disable-next-line no-unused-expressions
225+
expect($el.text()).to.exist;
226+
// CI or Category don't exist in the alert body, so it should be empty
227+
expect($el.text()).to.equal('--');
228+
},
229+
);
230+
});
231+
});
232+
233+
it('Add valid quote custom computed column to incident table', () => {
234+
const customColumnDefinitions = [
235+
{
236+
header: 'QuoteRegex',
237+
accessorPath: 'first_trigger_log_entry.channel.details',
238+
expression: '{"quote":"(.*)"}',
239+
},
240+
];
241+
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
242+
customColumnDefinitions.forEach((column) => {
243+
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
244+
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(
245+
($el) => {
246+
// eslint-disable-next-line no-unused-expressions
247+
expect($el.text()).to.exist;
248+
// Quote does exist in the alert body, so it should not be empty and also shouldn't
249+
// contain the custom details JSON with quote key, just the quote value
250+
expect($el.text()).to.not.equal('--');
251+
expect($el.text()).to.not.contain('"quote"');
252+
expect($el.text().length).to.be.greaterThan(20);
253+
},
254+
);
166255
});
167256
});
168257

cypress/e2e/app.spec.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,9 @@ describe('PagerDuty Live', { failFast: { enabled: true } }, () => {
114114
});
115115

116116
it('Application correctly renders the catastrophe modal', () => {
117-
cy
118-
.window()
119-
.its('store')
120-
.invoke('dispatch', { type: 'CATASTROPHE' });
117+
cy.window().its('store').invoke('dispatch', { type: 'CATASTROPHE' });
121118

122-
cy.get('header').contains('Catastrophic Error');
119+
cy.get('header').contains('Unexpected Error');
123120
cy.get('p').contains('The application will restart');
124121
});
125122
});

cypress/support/util/common.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,22 +255,35 @@ export const manageIncidentTableColumns = (desiredState = 'add', columns = []) =
255255
checkActionAlertsModalContent('Incident table columns saved');
256256
};
257257

258-
export const manageCustomAlertColumnDefinitions = (customAlertColumnDefinitions) => {
258+
export const manageCustomColumnDefinitions = (customColumnDefinitions, type = 'alert') => {
259259
cy.get('.settings-panel-dropdown').click();
260260
cy.get('.dropdown-item').contains('Columns').click();
261261

262262
cy.get('#custom-columns-card-body .chakra-icon').each(($el) => {
263263
cy.wrap($el).click();
264264
});
265265

266-
customAlertColumnDefinitions.forEach((customAlertColumnDefinition) => {
267-
const [header, accessorPath] = customAlertColumnDefinition.split(':');
268-
cy.get('input[placeholder="Header"]').type(header);
269-
cy.get('input[placeholder="JSON Path"]').type(accessorPath);
266+
customColumnDefinitions.forEach((customColumnDefinition) => {
267+
const {
268+
header, accessorPath, expression,
269+
} = customColumnDefinition;
270+
cy.get('#column-type-select').select(type);
271+
cy.get('input[placeholder="Header"]').clear().type(header);
272+
cy.get('input[placeholder="JSON Path"]').clear().type(accessorPath);
273+
if (type === 'computed') {
274+
cy.get('input[placeholder="Regex"]')
275+
.clear()
276+
.type(expression, { parseSpecialCharSequences: false });
277+
}
270278
cy.get('button[aria-label="Add custom column"]').click();
271279
// Need to escape special characters in accessorPath
272280
// https://docs.cypress.io/faq/questions/using-cypress-faq#How-do-I-use-special-characters-with-cyget
273-
cy.get(`#column-${Cypress.$.escapeSelector(accessorPath)}-add-icon`).click();
281+
const columnId = Cypress.$.escapeSelector(
282+
[header, accessorPath, expression.replace(/:/g, '\\:')]
283+
.filter((value) => value !== '')
284+
.join(':'),
285+
);
286+
cy.get(`#column-${columnId}-add-icon`).click();
274287
});
275288
cy.get('#save-columns-button').click();
276289
checkActionAlertsModalContent('Incident table columns saved');

package.json

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "pd-live-react",
33
"homepage": "https://pagerduty.github.io/pd-live-react",
4-
"version": "0.13.0-beta.0",
4+
"version": "0.13.1-beta.0",
55
"private": true,
66
"dependencies": {
77
"@chakra-ui/icons": "^2.1.1",
88
"@chakra-ui/react": "^2.8.0",
99
"@datadog/browser-rum": "^5.14.0",
10-
"@datadog/datadog-ci": "^2.37.0",
10+
"@datadog/datadog-ci": "^2.40.1",
1111
"@emotion/react": "^11.11.1",
12-
"@emotion/styled": "^11.11.0",
12+
"@emotion/styled": "^11.13.0",
1313
"@fortawesome/fontawesome-svg-core": "^6.4.2",
1414
"@fortawesome/free-brands-svg-icons": "^6.4.2",
1515
"@fortawesome/free-regular-svg-icons": "^6.5.1",
@@ -27,11 +27,11 @@
2727
"date-fns": "^2.29.3",
2828
"font-awesome": "^4.7.0",
2929
"framer-motion": "^10.16.2",
30-
"fuse.js": "^6.6.2",
30+
"fuse.js": "^7.0.0",
3131
"i18next": "^23.7.6",
32-
"i18next-browser-languagedetector": "^7.1.0",
32+
"i18next-browser-languagedetector": "^8.0.0",
3333
"immer": "^10.0.2",
34-
"jsonpath-plus": "^7.2.0",
34+
"jsonpath-plus": "^9.0.0",
3535
"linkify-react": "^4.1.3",
3636
"linkifyjs": "^4.1.3",
3737
"lodash": "^4.17.21",
@@ -49,15 +49,15 @@
4949
"react-icons": "^5.2.1",
5050
"react-minimal-pie-chart": "^8.4.0",
5151
"react-redux": "^9.1.2",
52-
"react-select": "^5.7.7",
52+
"react-select": "^5.8.0",
5353
"react-table": "^7.8.0",
54-
"react-window": "^1.8.8",
54+
"react-window": "^1.8.10",
5555
"redux": "^4.2.1",
5656
"redux-persist": "^6.0.0",
5757
"redux-saga": "^1.2.1",
5858
"styled-components": "^6.0.4",
5959
"use-debounce": "^9.0.3",
60-
"validator": "^13.11.0",
60+
"validator": "^13.12.0",
6161
"web-vitals": "^3.5.2"
6262
},
6363
"scripts": {
@@ -106,47 +106,47 @@
106106
"@faker-js/faker": "^8.0.2",
107107
"@testing-library/dom": "^9.3.4",
108108
"@testing-library/jest-dom": "^6.1.4",
109-
"@testing-library/react": "^14.1.2",
109+
"@testing-library/react": "^15.0.7",
110110
"@testing-library/react-hooks": "^8.0.1",
111111
"@testing-library/user-event": "^14.4.3",
112112
"@vitejs/plugin-react": "^4.2.1",
113-
"@welldone-software/why-did-you-render": "^7.0.1",
113+
"@welldone-software/why-did-you-render": "^8.0.3",
114114
"babel-jest": "^29.6.3",
115-
"cypress": "^13.5.1",
115+
"cypress": "^13.13.1",
116116
"cypress-fail-fast": "^7.1.0",
117117
"cypress-real-events": "^1.11.0",
118-
"dotenv": "^16.4.4",
118+
"dotenv": "^16.4.5",
119119
"eslint": "^8.43.0",
120120
"eslint-config-airbnb": "^18.2.1",
121121
"eslint-config-prettier": "^9.0.0",
122122
"eslint-config-react-app": "^7.0.1",
123123
"eslint-import-resolver-alias": "^1.1.2",
124-
"eslint-plugin-cypress": "^2.15.1",
124+
"eslint-plugin-cypress": "^3.4.0",
125125
"eslint-plugin-import": "^2.29.0",
126126
"eslint-plugin-jsx": "^0.1.0",
127127
"eslint-plugin-jsx-a11y": "^6.8.0",
128128
"eslint-plugin-prettier": "^4.2.1",
129129
"eslint-plugin-react": "^7.33.2",
130-
"eslint-plugin-react-hooks": "^4.6.0",
130+
"eslint-plugin-react-hooks": "^4.6.2",
131131
"eslint-plugin-react-refresh": "^0.4.3",
132-
"eslint-plugin-styled-components-a11y": "^2.1.31",
132+
"eslint-plugin-styled-components-a11y": "^2.1.35",
133133
"genversion": "^3.1.1",
134134
"gh-pages": "^6.1.1",
135-
"i18next-parser": "^8.12.0",
135+
"i18next-parser": "^9.0.0",
136136
"identity-obj-proxy": "^3.0.0",
137137
"jest": "^29.7.0",
138138
"jest-canvas-mock": "^2.5.2",
139139
"jest-environment-jsdom": "^29.7.0",
140140
"jest-environment-node": "^29.7.0",
141-
"jest-location-mock": "^1.0.10",
141+
"jest-location-mock": "^2.0.0",
142142
"jest-transformer-svg": "^2.0.1",
143143
"prettier": "^3.1.0",
144144
"prettier-eslint": "^16.1.2",
145145
"prettier-eslint-cli": "^8.0.1",
146146
"redux-mock-store": "^1.5.4",
147147
"redux-saga-test-plan": "^4.0.6",
148148
"sass": "^1.77.5",
149-
"string.prototype.replaceall": "^1.0.6",
149+
"string.prototype.replaceall": "^1.0.10",
150150
"vite": "^4.5.3",
151151
"vite-plugin-environment": "^1.1.3",
152152
"vite-plugin-eslint": "^1.8.1",

src/App.jsx

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ import {
7777
} from 'src/redux/monitoring/actions';
7878

7979
import {
80-
PD_USER_TOKEN,
81-
PD_OAUTH_CLIENT_ID,
82-
PD_OAUTH_CLIENT_SECRET,
80+
PD_USER_TOKEN, PD_OAUTH_CLIENT_ID, PD_OAUTH_CLIENT_SECRET,
8381
} from 'src/config/constants';
8482

8583
import 'src/App.scss';
@@ -108,9 +106,10 @@ const App = () => {
108106
);
109107

110108
const {
111-
status: connectionStatus,
112-
connectionStatusMessage,
113-
} = useSelector((state) => state.connection);
109+
status: connectionStatus, connectionStatusMessage,
110+
} = useSelector(
111+
(state) => state.connection,
112+
);
114113
const [catastrophe, setCatastrophe] = useState(false);
115114
useEffect(() => {
116115
if (connectionStatus === CATASTROPHE) {
@@ -163,17 +162,10 @@ const App = () => {
163162
}, []);
164163

165164
if (catastrophe) {
166-
return (
167-
<CatastropheModal
168-
errorMessage={connectionStatusMessage}
169-
/>
170-
);
165+
return <CatastropheModal errorMessage={connectionStatusMessage} />;
171166
}
172167

173-
if (
174-
!PD_USER_TOKEN
175-
&& (typeof token !== 'string' || !token.startsWith('pd'))
176-
) {
168+
if (!PD_USER_TOKEN && (typeof token !== 'string' || !token.startsWith('pd'))) {
177169
return (
178170
<div className="App">
179171
<AuthComponent clientId={PD_OAUTH_CLIENT_ID} clientSecret={PD_OAUTH_CLIENT_SECRET} />
@@ -201,13 +193,12 @@ const App = () => {
201193

202194
return (
203195
<div className="App">
204-
<ErrorBoundary fallbackRender={
205-
(details) => {
206-
RealUserMonitoring.trackError(details.error);
207-
dispatchCatastrophe(`UI Render error: ${details.error.message}`);
208-
return null;
209-
}
210-
}
196+
<ErrorBoundary
197+
fallbackRender={(details) => {
198+
RealUserMonitoring.trackError(details.error);
199+
dispatchCatastrophe(`UI Render error: ${details.error.message}`);
200+
return null;
201+
}}
211202
>
212203
<Box position="fixed" w="100%" h="100%" overflow="hidden">
213204
<Box as="header" top={0} w="100%" pb={1}>

0 commit comments

Comments
 (0)