diff --git a/.github/workflows/cd-workflow.yml b/.github/workflows/cd-workflow.yml
index 439779bf..2eba135a 100644
--- a/.github/workflows/cd-workflow.yml
+++ b/.github/workflows/cd-workflow.yml
@@ -1,10 +1,26 @@
name: PagerDuty Live Continuous Deployment Pipeline (Main)
on:
+ # Runs on pushes targeting the default branch
push:
branches:
- main
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
jobs:
build-deploy:
runs-on: ubuntu-latest
@@ -48,8 +64,6 @@ jobs:
with:
target_branch: gh-pages
build_dir: build
- env:
- GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
sync-branch:
runs-on: ubuntu-latest
@@ -61,4 +75,4 @@ jobs:
type: now
from_branch: main
target_branch: develop
- github_token: ${{ secrets.GH_TOKEN }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/cypress/e2e/Settings/settings.spec.js b/cypress/e2e/Settings/settings.spec.js
index dbcca15f..cbd8cd96 100644
--- a/cypress/e2e/Settings/settings.spec.js
+++ b/cypress/e2e/Settings/settings.spec.js
@@ -14,6 +14,7 @@ import {
updateMaxRateLimit,
updateAutoAcceptIncidentQuery,
updateAutoRefreshInterval,
+ updateDarkMode,
manageIncidentTableColumns,
manageCustomAlertColumnDefinitions,
activateButton,
@@ -193,4 +194,16 @@ describe('Manage Settings', { failFast: { enabled: false } }, () => {
cy.get('.btn').contains('Clear Local Cache').click();
cy.get('.modal-title').contains('Disclaimer & License').should('be.visible');
});
+
+ it('Update dark mode', () => {
+ [true, false].forEach((darkMode) => {
+ updateDarkMode(darkMode);
+ cy.window()
+ .its('store')
+ .invoke('getState')
+ .then((state) => expect(
+ state.settings.darkMode,
+ ).to.equal(darkMode));
+ });
+ });
});
diff --git a/cypress/support/util/common.js b/cypress/support/util/common.js
index b683b5b7..c8bff941 100644
--- a/cypress/support/util/common.js
+++ b/cypress/support/util/common.js
@@ -305,6 +305,22 @@ export const updateAutoAcceptIncidentQuery = (autoAcceptIncidentsQuery = false)
cy.get('.close').click();
};
+export const updateDarkMode = (darkMode = false) => {
+ cy.get('.settings-panel-dropdown').click();
+ cy.get('.dropdown-item').contains('Settings').click();
+ cy.get('.nav-item').contains('User Profile').click();
+
+ if (darkMode) {
+ cy.get('#user-profile-dark-mode-checkbox').check({ force: true });
+ } else {
+ cy.get('#user-profile-dark-mode-checkbox').uncheck({ force: true });
+ }
+
+ cy.get('.btn').contains('Update User Profile').click();
+ checkActionAlertsModalContent('Updated user profile settings');
+ cy.get('.close').click();
+};
+
export const priorityNames = ['--', 'P5', 'P4', 'P3', 'P2', 'P1'];
/*
diff --git a/package.json b/package.json
index 9763c12f..66efe5f5 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "pd-live-react",
"homepage": "https://giranm.github.io/pd-live-react",
- "version": "0.6.0-beta.0",
+ "version": "0.7.0-beta.0",
"private": true,
"dependencies": {
"@braintree/sanitize-url": "^6.0.2",
@@ -18,7 +18,7 @@
"@testing-library/user-event": "^14.4.3",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"autoprefixer": "10.4.13",
- "axios": "^1.2.2",
+ "axios": "^1.2.4",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.6.2",
"bottleneck": "^2.19.5",
@@ -36,6 +36,7 @@
"node-sass": "^7.0.3",
"react": "^17.0.2",
"react-bootstrap": "^1.6.6",
+ "react-contextmenu": "^2.14.0",
"react-datepicker": "^4.10.0",
"react-dom": "^17.0.2",
"react-dual-listbox": "^4.0.0",
@@ -49,7 +50,7 @@
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.2.1",
- "styled-components": "^5.3.6",
+ "styled-components": "^5.3.7",
"use-debounce": "^9.0.3",
"validator": "^13.7.0",
"web-vitals": "^3.1.0"
diff --git a/src/App.js b/src/App.js
index 9cbbee7c..4bafb02e 100644
--- a/src/App.js
+++ b/src/App.js
@@ -97,6 +97,14 @@ const App = ({
}) => {
// Verify if session token is present
const token = sessionStorage.getItem('pd_access_token');
+ const {
+ autoRefreshInterval, darkMode,
+ } = state.settings;
+
+ if (darkMode) {
+ document.body.classList.add('dark-mode');
+ }
+
if (!token) {
return (
@@ -109,9 +117,6 @@ const App = ({
const {
userAuthorized, userAcceptedDisclaimer, currentUserLocale,
} = state.users;
- const {
- autoRefreshInterval,
- } = state.settings;
const {
fetchingIncidents,
fetchingIncidentNotes,
diff --git a/src/App.scss b/src/App.scss
index a5c82ee1..87d4429d 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -5,12 +5,22 @@ body {
background-color: $pd-brand-background !important;
}
+body.dark-mode {
+ background-color: $pd-brand-gray-dark !important;
+}
+
.btn-outline-secondary {
color: $pd-brand-black;
background-color: $pd-brand-white;
border-color: $pd-brand-secondary-light;
}
+body.dark-mode .btn-outline-secondary {
+ color: $pd-white;
+ background-color: $pd-brand-gray-dark;
+ border-color: $pd-brand-secondary-light;
+}
+
.btn-outline-secondary:disabled {
color: $pd-brand-secondary-light !important;
}
@@ -26,6 +36,10 @@ body {
background-color: unset !important;
}
+body.dark-mode .btn-outline-secondary:not(:disabled):not(.disabled).active {
+ background-color: $pd-brand-gray-light !important;
+}
+
.btn-outline-dark {
color: $pd-brand-gray-dark;
background-color: $pd-white;
@@ -59,3 +73,54 @@ body {
.modal-footer {
display: unset !important;
}
+
+body.dark-mode a {
+ color: $pd-brand-white;
+}
+
+body.dark-mode .modal-content {
+ background-color: $pd-brand-black !important;
+ color: $pd-white !important;
+}
+
+body.dark-mode .modal-title {
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode .modal-header .close {
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode .form-label, body.dark-mode .form-text {
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode .form-control {
+ background-color: $pd-brand-gray-dark !important;
+ color: $pd-white;
+}
+
+body.dark-mode div.react-select__control, body.dark-mode div.react-select__menu {
+ background-color: $pd-brand-gray-dark !important;
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode div.react-select__multi-value {
+ background-color: $pd-brand-gray-light !important;
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode div.react-select__single-value {
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode div.react-select__option:hover {
+ background-color: $pd-brand-secondary-light !important;
+ color: $pd-brand-white !important;
+}
+
+body.dark-mode div.react-select__option--is-focused {
+ background-color: $pd-brand-secondary-light !important;
+ color: $pd-brand-white !important;
+}
+
diff --git a/src/assets/images/pd_logo_white.svg b/src/assets/images/pd_logo_white.svg
new file mode 100644
index 00000000..1394a06d
--- /dev/null
+++ b/src/assets/images/pd_logo_white.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/src/components/AddResponderModal/AddResponderModalComponent.js b/src/components/AddResponderModal/AddResponderModalComponent.js
index 21dc4fc1..9c571c76 100644
--- a/src/components/AddResponderModal/AddResponderModalComponent.js
+++ b/src/components/AddResponderModal/AddResponderModalComponent.js
@@ -86,6 +86,7 @@ const AddResponderModalComponent = ({
{t('Responders')}
);
diff --git a/src/components/IncidentTable/IncidentTableComponent.scss b/src/components/IncidentTable/IncidentTableComponent.scss
index 3081b401..c997ce5b 100644
--- a/src/components/IncidentTable/IncidentTableComponent.scss
+++ b/src/components/IncidentTable/IncidentTableComponent.scss
@@ -7,6 +7,10 @@
top: 5px;
}
+body.dark-mode .querying-incidents {
+ color: $pd-brand-gray-light;
+}
+
/* Empty Incidents */
.empty-incidents {
height: 500px;
@@ -17,6 +21,10 @@
padding-top: 20px;
}
+body.dark-mode .empty-incidents-badge {
+ color: $pd-brand-gray-light;
+}
+
/* Table Positioning */
.incident-table {
margin-top: 10px;
@@ -142,6 +150,11 @@
border-right: 1px $pd-brand-background-3 solid;
}
+body.dark-mode .th {
+ background-color: $pd-gray;
+ color: $pd-white;
+}
+
.th-sorted {
padding: 10px !important;
background-color: white;
@@ -150,6 +163,11 @@
border-right: 1px $pd-brand-background-3 solid;
}
+body.dark-mode .th-sorted {
+ background-color: $pd-brand-secondary-dark;
+ color: $pd-white;
+}
+
.resizer {
display: inline-block;
width: 2px;
@@ -175,16 +193,32 @@
background-color: $pd-brand-background-2 !important;
}
+body.dark-mode .tr {
+ background-color: $pd-gray !important;
+ color: $pd-white;
+}
+
.tr-odd {
font-size: 14px;
background-color: $pd-brand-background-3 !important;
}
+body.dark-mode .tr-odd {
+ background-color: $pd-gray-dark !important;
+ color: $pd-white;
+}
+
.tr:hover,
.tr-odd:hover {
background-color: $pd-gray-medium !important;
}
+body.dark-mode .tr:hover,
+body.dark-mode .tr-odd:hover {
+ background-color: $pd-brand-secondary-light !important;
+ color: $pd-white;
+}
+
.td {
padding: 10px !important;
padding-left: 10px !important;
@@ -201,3 +235,9 @@
line-clamp: 2;
-webkit-box-orient: vertical;
}
+
+.react-contextmenu {
+ z-index: 1000;
+ background-color: $pd-white;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
+}
\ No newline at end of file
diff --git a/src/components/MergeModal/MergeModalComponent.js b/src/components/MergeModal/MergeModalComponent.js
index 2652053d..ad0dcbe4 100644
--- a/src/components/MergeModal/MergeModalComponent.js
+++ b/src/components/MergeModal/MergeModalComponent.js
@@ -93,6 +93,7 @@ const MergeModalComponent = ({