feat(ui): add option to sync portainer with system theme EE-1788 (#5812)

* add option to sync portainer with system theme
pull/6081/head
Richard Wei 2021-11-15 11:50:21 +13:00 committed by GitHub
parent a2886115b8
commit 9e9a4ca4cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 15 deletions

View File

@ -269,6 +269,7 @@ json-tree .branch-preview {
.panel { .panel {
border: 1px solid var(--border-panel-color); border: 1px solid var(--border-panel-color);
background-color: var(--bg-panel-body-color);
} }
.theme-information .col-sm-12 { .theme-information .col-sm-12 {

View File

@ -25,7 +25,11 @@ export default class ThemeSettingsController {
} }
setTheme(theme) { setTheme(theme) {
this.ThemeManager.setTheme(theme); if (theme === 'auto' || !theme) {
this.ThemeManager.autoTheme();
} else {
this.ThemeManager.setTheme(theme);
}
this.state.themeInProgress = true; this.state.themeInProgress = true;
} }
@ -35,7 +39,7 @@ export default class ThemeSettingsController {
userId: null, userId: null,
userTheme: '', userTheme: '',
initTheme: '', initTheme: '',
defaultTheme: 'light', defaultTheme: 'auto',
themeInProgress: false, themeInProgress: false,
}; };
@ -43,14 +47,9 @@ export default class ThemeSettingsController {
buildOption('light', 'fas fa-sun', 'Light Theme', 'Default color mode', 'light'), buildOption('light', 'fas fa-sun', 'Light Theme', 'Default color mode', 'light'),
buildOption('dark', 'fas fa-moon', 'Dark Theme', 'Dark color mode', 'dark'), buildOption('dark', 'fas fa-moon', 'Dark Theme', 'Dark color mode', 'dark'),
buildOption('highcontrast', 'fas fa-adjust', 'High Contrast', 'High contrast color mode', 'highcontrast'), buildOption('highcontrast', 'fas fa-adjust', 'High Contrast', 'High contrast color mode', 'highcontrast'),
buildOption('auto', 'fas fa-sync-alt', 'Auto', 'Sync with system theme', 'auto'),
]; ];
this.state.availableTheme = {
light: 'light',
dark: 'dark',
highContrast: 'highcontrast',
};
try { try {
this.state.userId = await this.Authentication.getUserDetails().ID; this.state.userId = await this.Authentication.getUserDetails().ID;
const data = await this.UserService.user(this.state.userId); const data = await this.UserService.user(this.state.userId);

View File

@ -88,7 +88,11 @@ angular.module('portainer.app').factory('Authentication', [
const data = await UserService.user(user.ID); const data = await UserService.user(user.ID);
// Initialize user theme base on Usertheme from database // Initialize user theme base on Usertheme from database
const userTheme = data.UserTheme; const userTheme = data.UserTheme;
ThemeManager.setTheme(userTheme); if (userTheme === 'auto' || !userTheme) {
ThemeManager.autoTheme();
} else {
ThemeManager.setTheme(userTheme);
}
} }
async function setUser(jwt) { async function setUser(jwt) {

View File

@ -5,6 +5,7 @@ angular.module('portainer.app').service('ThemeManager', ThemeManager);
export function ThemeManager(StateManager) { export function ThemeManager(StateManager) {
return { return {
setTheme, setTheme,
autoTheme,
defaultTheme, defaultTheme,
}; };
@ -13,8 +14,13 @@ export function ThemeManager(StateManager) {
document.documentElement.removeAttribute('theme'); document.documentElement.removeAttribute('theme');
} else { } else {
document.documentElement.setAttribute('theme', theme); document.documentElement.setAttribute('theme', theme);
StateManager.updateTheme(theme);
} }
StateManager.updateTheme(theme); }
function autoTheme() {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : '';
this.setTheme(systemTheme);
} }
function defaultTheme() { function defaultTheme() {

View File

@ -2,7 +2,7 @@ import angular from 'angular';
class LogoutController { class LogoutController {
/* @ngInject */ /* @ngInject */
constructor($async, $state, $transition$, $window, Authentication, StateManager, Notifications, LocalStorage, SettingsService, ThemeManager) { constructor($async, $state, $transition$, $window, Authentication, StateManager, Notifications, LocalStorage, SettingsService) {
this.$async = $async; this.$async = $async;
this.$state = $state; this.$state = $state;
this.$transition$ = $transition$; this.$transition$ = $transition$;
@ -13,7 +13,6 @@ class LogoutController {
this.Notifications = Notifications; this.Notifications = Notifications;
this.LocalStorage = LocalStorage; this.LocalStorage = LocalStorage;
this.SettingsService = SettingsService; this.SettingsService = SettingsService;
this.ThemeManager = ThemeManager;
this.logo = this.StateManager.getState().application.logo; this.logo = this.StateManager.getState().application.logo;
this.logoutAsync = this.logoutAsync.bind(this); this.logoutAsync = this.logoutAsync.bind(this);
@ -29,8 +28,6 @@ class LogoutController {
const performApiLogout = this.$transition$.params().performApiLogout; const performApiLogout = this.$transition$.params().performApiLogout;
const settings = await this.SettingsService.publicSettings(); const settings = await this.SettingsService.publicSettings();
this.ThemeManager.defaultTheme();
try { try {
await this.Authentication.logout(performApiLogout); await this.Authentication.logout(performApiLogout);
} finally { } finally {

View File

@ -4,7 +4,7 @@ angular.module('portainer.app').controller('MainController', [
'StateManager', 'StateManager',
'EndpointProvider', 'EndpointProvider',
'ThemeManager', 'ThemeManager',
function ($scope, LocalStorage, StateManager, EndpointProvider) { function ($scope, LocalStorage, StateManager, EndpointProvider, ThemeManager) {
/** /**
* Sidebar Toggle & Cookie Control * Sidebar Toggle & Cookie Control
*/ */
@ -33,5 +33,7 @@ angular.module('portainer.app').controller('MainController', [
window.onresize = function () { window.onresize = function () {
$scope.$apply(); $scope.$apply();
}; };
ThemeManager.autoTheme();
}, },
]); ]);