1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-02-20 02:01:47 +01:00

[Account Switching] Design changes to settings menu (#1244)

* Design changes to settings menu

* Remove black border on settings headers

* Pull in jslib

* Only load account related settings when authed

* Hide account related settings when not authed

* Change settings titles

* Changes discussed with Danielle
This commit is contained in:
Daniel James Smith 2022-01-20 22:56:15 +01:00 committed by GitHub
parent d1c01a2bb0
commit 37b03b09a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 419 additions and 281 deletions

12
package-lock.json generated
View File

@ -3955,9 +3955,9 @@
} }
}, },
"node_modules/electron/node_modules/@types/node": { "node_modules/electron/node_modules/@types/node": {
"version": "14.18.0", "version": "14.18.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.9.tgz",
"integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==" "integrity": "sha512-j11XSuRuAlft6vLDEX4RvhqC0KxNxx6QIyMXNb0vHHSNPXTPeiy3algESWmOOIzEtiEL0qiowPU3ewW9hHVa7Q=="
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@ -12804,9 +12804,9 @@
}, },
"dependencies": { "dependencies": {
"@types/node": { "@types/node": {
"version": "14.18.0", "version": "14.18.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.9.tgz",
"integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==" "integrity": "sha512-j11XSuRuAlft6vLDEX4RvhqC0KxNxx6QIyMXNb0vHHSNPXTPeiy3algESWmOOIzEtiEL0qiowPU3ewW9hHVa7Q=="
} }
} }
}, },

View File

@ -2,278 +2,345 @@
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-body form"> <div class="modal-body form">
<ng-container *ngIf="currentUserEmail != null">
<div class="box">
<label class="settingsTitle">{{ "settingsTitle" | i18n: currentUserEmail }} </label>
<div class="box-content box-content-padded">
<h2>
<button
type="button"
class="box-header-expandable"
(click)="showSecurity = !showSecurity"
[attr.aria-expanded]="showSecurity"
>
{{ "security" | i18n }}
<i
*ngIf="!showSecurity"
class="fa fa-chevron-down fa-sm icon"
aria-hidden="true"
></i>
<i
*ngIf="showSecurity"
class="fa fa-chevron-up fa-sm icon"
aria-hidden="true"
></i>
</button>
</h2>
<ng-container *ngIf="showSecurity">
<app-vault-timeout-input
[vaultTimeouts]="vaultTimeouts"
[formControl]="vaultTimeout"
ngDefaultControl
></app-vault-timeout-input>
<div class="form-group">
<label>{{ "vaultTimeoutAction" | i18n }}</label>
<div class="radio radio-mt-2">
<label for="vaultTimeoutActionLock">
<input
type="radio"
name="VaultTimeoutAction"
id="vaultTimeoutActionLock"
value="lock"
[(ngModel)]="vaultTimeoutAction"
(change)="saveVaultTimeoutOptions()"
/>
{{ "lock" | i18n }}
</label>
</div>
<small class="help-block">{{ "vaultTimeoutActionLockDesc" | i18n }}</small>
<div class="radio">
<label for="vaultTimeoutActionLogOut">
<input
type="radio"
name="VaultTimeoutAction"
id="vaultTimeoutActionLogOut"
value="logOut"
[(ngModel)]="vaultTimeoutAction"
(change)="saveVaultTimeoutOptions()"
/>
{{ "logOut" | i18n }}
</label>
</div>
<small class="help-block">{{ "vaultTimeoutActionLogOutDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="pin">
<input
id="pin"
type="checkbox"
name="PIN"
[(ngModel)]="pin"
(change)="updatePin()"
/>
{{ "unlockWithPin" | i18n }}
</label>
</div>
</div>
<div class="form-group" *ngIf="supportsBiometric">
<div class="checkbox">
<label for="biometric">
<input
id="biometric"
type="checkbox"
name="biometric"
[checked]="biometric"
(change)="updateBiometric()"
/>
{{ biometricText | i18n }}
</label>
</div>
</div>
<div class="form-group" *ngIf="supportsBiometric">
<div class="checkbox">
<label for="noAutoPromptBiometrics">
<input
id="noAutoPromptBiometrics"
type="checkbox"
name="noAutoPromptBiometrics"
[(ngModel)]="noAutoPromptBiometrics"
[disabled]="!biometric"
(change)="updateNoAutoPromptBiometrics()"
/>
{{ noAutoPromptBiometricsText | i18n }}
</label>
</div>
</div>
</ng-container>
</div>
</div>
<div class="box">
<div class="box-content box-content-padded">
<h2>
<button
type="button"
class="box-header-expandable"
(click)="showAccountPreferences = !showAccountPreferences"
[attr.aria-expanded]="showAccountPreferences"
>
{{ "accountPreferences" | i18n }}
<i
*ngIf="!showAccountPreferences"
class="fa fa-chevron-down fa-sm icon"
aria-hidden="true"
></i>
<i
*ngIf="showAccountPreferences"
class="fa fa-chevron-up fa-sm icon"
aria-hidden="true"
></i>
</button>
</h2>
<ng-container *ngIf="showAccountPreferences">
<div class="form-group">
<label for="clearClipboard">{{ "clearClipboard" | i18n }}</label>
<select
id="clearClipboard"
name="ClearClipboard"
[(ngModel)]="clearClipboard"
(change)="saveClearClipboard()"
>
<option *ngFor="let o of clearClipboardOptions" [ngValue]="o.value">
{{ o.name }}
</option>
</select>
<small class="help-block">{{ "clearClipboardDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="minimizeOnCopyToClipboard">
<input
id="minimizeOnCopyToClipboard"
type="checkbox"
name="MinimizeOnCopyToClipboard"
[(ngModel)]="minimizeOnCopyToClipboard"
(change)="saveMinOnCopyToClipboard()"
/>
{{ "minimizeOnCopyToClipboard" | i18n }}
</label>
</div>
<small class="help-block">{{ "minimizeOnCopyToClipboardDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="disableFavicons">
<input
id="disableFavicons"
type="checkbox"
name="DisableFavicons"
[(ngModel)]="disableFavicons"
(change)="saveFavicons()"
/>
{{ "disableFavicon" | i18n }}
</label>
</div>
<small class="help-block">{{ "disableFaviconDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="enableBrowserIntegration">
<input
id="enableBrowserIntegration"
type="checkbox"
name="EnableBrowserIntegration"
[(ngModel)]="enableBrowserIntegration"
(change)="saveBrowserIntegration()"
/>
{{ "enableBrowserIntegration" | i18n }}
</label>
</div>
<small class="help-block">{{ "enableBrowserIntegrationDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="enableBrowserIntegrationFingerprint">
<input
id="enableBrowserIntegrationFingerprint"
type="checkbox"
name="EnableBrowserIntegrationFingerprint"
[(ngModel)]="enableBrowserIntegrationFingerprint"
(change)="saveBrowserIntegrationFingerprint()"
[disabled]="!enableBrowserIntegration"
/>
{{ "enableBrowserIntegrationFingerprint" | i18n }}
</label>
</div>
<small class="help-block">{{
"enableBrowserIntegrationFingerprintDesc" | i18n
}}</small>
</div>
</ng-container>
</div>
</div>
</ng-container>
<div class="box"> <div class="box">
<div class="box-header">
{{ "security" | i18n }}
</div>
<div class="box-content box-content-padded"> <div class="box-content box-content-padded">
<app-vault-timeout-input <h2>
[vaultTimeouts]="vaultTimeouts" <button
[formControl]="vaultTimeout" type="button"
ngDefaultControl class="box-header-expandable"
></app-vault-timeout-input> (click)="showAppPreferences = !showAppPreferences"
<div class="form-group"> [attr.aria-expanded]="showAppPreferences"
<label>{{ "vaultTimeoutAction" | i18n }}</label>
<div class="radio radio-mt-2">
<label for="vaultTimeoutActionLock">
<input
type="radio"
name="VaultTimeoutAction"
id="vaultTimeoutActionLock"
value="lock"
[(ngModel)]="vaultTimeoutAction"
(change)="saveVaultTimeoutOptions()"
/>
{{ "lock" | i18n }}
</label>
</div>
<small class="help-block">{{ "vaultTimeoutActionLockDesc" | i18n }}</small>
<div class="radio">
<label for="vaultTimeoutActionLogOut">
<input
type="radio"
name="VaultTimeoutAction"
id="vaultTimeoutActionLogOut"
value="logOut"
[(ngModel)]="vaultTimeoutAction"
(change)="saveVaultTimeoutOptions()"
/>
{{ "logOut" | i18n }}
</label>
</div>
<small class="help-block">{{ "vaultTimeoutActionLogOutDesc" | i18n }}</small>
</div>
<div class="form-group">
<div class="checkbox">
<label for="pin">
<input
id="pin"
type="checkbox"
name="PIN"
[(ngModel)]="pin"
(change)="updatePin()"
/>
{{ "unlockWithPin" | i18n }}
</label>
</div>
</div>
<div class="form-group" *ngIf="supportsBiometric">
<div class="checkbox">
<label for="biometric">
<input
id="biometric"
type="checkbox"
name="biometric"
[checked]="biometric"
(change)="updateBiometric()"
/>
{{ biometricText | i18n }}
</label>
</div>
</div>
<div class="form-group" *ngIf="supportsBiometric">
<div class="checkbox">
<label for="noAutoPromptBiometrics">
<input
id="noAutoPromptBiometrics"
type="checkbox"
name="noAutoPromptBiometrics"
[(ngModel)]="noAutoPromptBiometrics"
[disabled]="!biometric"
(change)="updateNoAutoPromptBiometrics()"
/>
{{ noAutoPromptBiometricsText | i18n }}
</label>
</div>
</div>
</div>
</div>
<div class="box">
<div class="box-header">
{{ "options" | i18n }}
</div>
<div class="box-content box-content-padded">
<div class="form-group">
<label for="clearClipboard">{{ "clearClipboard" | i18n }}</label>
<select
id="clearClipboard"
name="ClearClipboard"
[(ngModel)]="clearClipboard"
(change)="saveClearClipboard()"
> >
<option *ngFor="let o of clearClipboardOptions" [ngValue]="o.value"> {{ "appPreferences" | i18n }}
{{ o.name }} <i
</option> *ngIf="!showAppPreferences"
</select> class="fa fa-chevron-down fa-sm icon"
<small class="help-block">{{ "clearClipboardDesc" | i18n }}</small> aria-hidden="true"
</div> ></i>
<div class="form-group"> <i
<div class="checkbox"> *ngIf="showAppPreferences"
<label for="minimizeOnCopyToClipboard"> class="fa fa-chevron-up fa-sm icon"
<input aria-hidden="true"
id="minimizeOnCopyToClipboard" ></i>
type="checkbox" </button>
name="MinimizeOnCopyToClipboard" </h2>
[(ngModel)]="minimizeOnCopyToClipboard" <ng-container *ngIf="showAppPreferences">
(change)="saveMinOnCopyToClipboard()" <div class="form-group">
/> <div class="checkbox">
{{ "minimizeOnCopyToClipboard" | i18n }} <label for="enableTray">
</label> <input
id="enableTray"
type="checkbox"
name="EnableTray"
[(ngModel)]="enableTray"
(change)="saveTray()"
/>
{{ enableTrayText }}
</label>
</div>
<small class="help-block">{{ enableTrayDescText }}</small>
</div> </div>
<small class="help-block">{{ "minimizeOnCopyToClipboardDesc" | i18n }}</small> <div class="form-group" *ngIf="showMinToTray">
</div> <div class="checkbox">
<div class="form-group"> <label for="enableMinToTray">
<div class="checkbox"> <input
<label for="disableFavicons"> id="enableMinToTray"
<input type="checkbox"
id="disableFavicons" name="EnableMinToTray"
type="checkbox" [(ngModel)]="enableMinToTray"
name="DisableFavicons" (change)="saveMinToTray()"
[(ngModel)]="disableFavicons" />
(change)="saveFavicons()" {{ enableMinToTrayText }}
/> </label>
{{ "disableFavicon" | i18n }} </div>
</label> <small class="help-block">{{ enableMinToTrayDescText }}</small>
</div> </div>
<small class="help-block">{{ "disableFaviconDesc" | i18n }}</small> <div class="form-group">
</div> <div class="checkbox">
<div class="form-group"> <label for="enableCloseToTray">
<div class="checkbox"> <input
<label for="enableBrowserIntegration"> id="enableCloseToTray"
<input type="checkbox"
id="enableBrowserIntegration" name="EnableCloseToTray"
type="checkbox" [(ngModel)]="enableCloseToTray"
name="EnableBrowserIntegration" (change)="saveCloseToTray()"
[(ngModel)]="enableBrowserIntegration" />
(change)="saveBrowserIntegration()" {{ enableCloseToTrayText }}
/> </label>
{{ "enableBrowserIntegration" | i18n }} </div>
</label> <small class="help-block">{{ enableCloseToTrayDescText }}</small>
</div> </div>
<small class="help-block">{{ "enableBrowserIntegrationDesc" | i18n }}</small> <div class="form-group">
</div> <div class="checkbox">
<div class="form-group"> <label for="startToTray">
<div class="checkbox"> <input
<label for="enableBrowserIntegrationFingerprint"> id="startToTray"
<input type="checkbox"
id="enableBrowserIntegrationFingerprint" name="StartToTray"
type="checkbox" [(ngModel)]="startToTray"
name="EnableBrowserIntegrationFingerprint" (change)="saveStartToTray()"
[(ngModel)]="enableBrowserIntegrationFingerprint" />
(change)="saveBrowserIntegrationFingerprint()" {{ startToTrayText }}
[disabled]="!enableBrowserIntegration" </label>
/> </div>
{{ "enableBrowserIntegrationFingerprint" | i18n }} <small class="help-block">{{ startToTrayDescText }}</small>
</label>
</div> </div>
<small class="help-block">{{ <div class="form-group">
"enableBrowserIntegrationFingerprintDesc" | i18n <div class="checkbox">
}}</small> <label for="openAtLogin">
</div> <input
<div class="form-group"> id="openAtLogin"
<div class="checkbox"> type="checkbox"
<label for="enableTray"> name="OpenAtLogin"
<input [(ngModel)]="openAtLogin"
id="enableTray" (change)="saveOpenAtLogin()"
type="checkbox" />
name="EnableTray" {{ "openAtLogin" | i18n }}
[(ngModel)]="enableTray" </label>
(change)="saveTray()" </div>
/> <small class="help-block">{{ "openAtLoginDesc" | i18n }}</small>
{{ enableTrayText }}
</label>
</div> </div>
<small class="help-block">{{ enableTrayDescText }}</small> <div class="form-group" *ngIf="showAlwaysShowDock">
</div> <div class="checkbox">
<div class="form-group" *ngIf="showMinToTray"> <label for="alwaysShowDock">
<div class="checkbox"> <input
<label for="enableMinToTray"> id="alwaysShowDock"
<input type="checkbox"
id="enableMinToTray" name="AlwaysShowDock"
type="checkbox" [(ngModel)]="alwaysShowDock"
name="EnableMinToTray" (change)="saveAlwaysShowDock()"
[(ngModel)]="enableMinToTray" />
(change)="saveMinToTray()" {{ "alwaysShowDock" | i18n }}
/> </label>
{{ enableMinToTrayText }} </div>
</label> <small class="help-block">{{ "alwaysShowDockDesc" | i18n }}</small>
</div> </div>
<small class="help-block">{{ enableMinToTrayDescText }}</small> <div class="form-group">
</div> <label for="theme">{{ "theme" | i18n }}</label>
<div class="form-group"> <select id="theme" name="Theme" [(ngModel)]="theme" (change)="saveTheme()">
<div class="checkbox"> <option *ngFor="let o of themeOptions" [ngValue]="o.value">{{ o.name }}</option>
<label for="enableCloseToTray"> </select>
<input <small class="help-block">{{ "themeDesc" | i18n }}</small>
id="enableCloseToTray"
type="checkbox"
name="EnableCloseToTray"
[(ngModel)]="enableCloseToTray"
(change)="saveCloseToTray()"
/>
{{ enableCloseToTrayText }}
</label>
</div> </div>
<small class="help-block">{{ enableCloseToTrayDescText }}</small> <div class="form-group">
</div> <label for="locale">{{ "language" | i18n }}</label>
<div class="form-group"> <select id="locale" name="Locale" [(ngModel)]="locale" (change)="saveLocale()">
<div class="checkbox"> <option *ngFor="let o of localeOptions" [ngValue]="o.value">{{ o.name }}</option>
<label for="startToTray"> </select>
<input <small class="help-block">{{ "languageDesc" | i18n }}</small>
id="startToTray"
type="checkbox"
name="StartToTray"
[(ngModel)]="startToTray"
(change)="saveStartToTray()"
/>
{{ startToTrayText }}
</label>
</div> </div>
<small class="help-block">{{ startToTrayDescText }}</small> </ng-container>
</div>
<div class="form-group">
<div class="checkbox">
<label for="openAtLogin">
<input
id="openAtLogin"
type="checkbox"
name="OpenAtLogin"
[(ngModel)]="openAtLogin"
(change)="saveOpenAtLogin()"
/>
{{ "openAtLogin" | i18n }}
</label>
</div>
<small class="help-block">{{ "openAtLoginDesc" | i18n }}</small>
</div>
<div class="form-group" *ngIf="showAlwaysShowDock">
<div class="checkbox">
<label for="alwaysShowDock">
<input
id="alwaysShowDock"
type="checkbox"
name="AlwaysShowDock"
[(ngModel)]="alwaysShowDock"
(change)="saveAlwaysShowDock()"
/>
{{ "alwaysShowDock" | i18n }}
</label>
</div>
<small class="help-block">{{ "alwaysShowDockDesc" | i18n }}</small>
</div>
<div class="form-group">
<label for="theme">{{ "theme" | i18n }}</label>
<select id="theme" name="Theme" [(ngModel)]="theme" (change)="saveTheme()">
<option *ngFor="let o of themeOptions" [ngValue]="o.value">{{ o.name }}</option>
</select>
<small class="help-block">{{ "themeDesc" | i18n }}</small>
</div>
<div class="form-group">
<label for="locale">{{ "language" | i18n }}</label>
<select id="locale" name="Locale" [(ngModel)]="locale" (change)="saveLocale()">
<option *ngFor="let o of localeOptions" [ngValue]="o.value">{{ o.name }}</option>
</select>
<small class="help-block">{{ "languageDesc" | i18n }}</small>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -65,6 +65,12 @@ export class SettingsComponent implements OnInit {
vaultTimeout: FormControl = new FormControl(null); vaultTimeout: FormControl = new FormControl(null);
showSecurity: boolean = true;
showAccountPreferences: boolean = true;
showAppPreferences: boolean = true;
currentUserEmail: string;
constructor( constructor(
private i18nService: I18nService, private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
@ -151,21 +157,36 @@ export class SettingsComponent implements OnInit {
} }
async ngOnInit() { async ngOnInit() {
// App preferences
this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop; this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop;
this.vaultTimeout.setValue(await this.stateService.getVaultTimeout());
this.vaultTimeoutAction = await this.stateService.getVaultTimeoutAction();
const pinSet = await this.vaultTimeoutService.isPinLockSet();
this.pin = pinSet[0] || pinSet[1];
this.disableFavicons = await this.stateService.getDisableFavicon();
this.enableBrowserIntegration = await this.stateService.getEnableBrowserIntegration();
this.enableBrowserIntegrationFingerprint =
await this.stateService.getEnableBrowserIntegrationFingerprint();
this.enableMinToTray = await this.stateService.getEnableMinimizeToTray(); this.enableMinToTray = await this.stateService.getEnableMinimizeToTray();
this.enableCloseToTray = await this.stateService.getEnableCloseToTray(); this.enableCloseToTray = await this.stateService.getEnableCloseToTray();
this.enableTray = await this.stateService.getEnableTray(); this.enableTray = await this.stateService.getEnableTray();
this.startToTray = await this.stateService.getEnableStartToTray(); this.startToTray = await this.stateService.getEnableStartToTray();
this.alwaysShowDock = await this.stateService.getAlwaysShowDock();
this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
this.openAtLogin = await this.stateService.getOpenAtLogin();
this.locale = await this.stateService.getLocale(); this.locale = await this.stateService.getLocale();
this.theme = await this.stateService.getTheme(); this.theme = await this.stateService.getTheme();
if ((await this.stateService.getUserId()) == null) {
return;
}
this.currentUserEmail = await this.stateService.getEmail();
// Security
this.vaultTimeout.setValue(await this.stateService.getVaultTimeout());
this.vaultTimeoutAction = await this.stateService.getVaultTimeoutAction();
const pinSet = await this.vaultTimeoutService.isPinLockSet();
this.pin = pinSet[0] || pinSet[1];
// Account preferences
this.disableFavicons = await this.stateService.getDisableFavicon();
this.enableBrowserIntegration = await this.stateService.getEnableBrowserIntegration();
this.enableBrowserIntegrationFingerprint =
await this.stateService.getEnableBrowserIntegrationFingerprint();
this.clearClipboard = await this.stateService.getClearClipboard(); this.clearClipboard = await this.stateService.getClearClipboard();
this.minimizeOnCopyToClipboard = await this.stateService.getMinimizeOnCopyToClipboard(); this.minimizeOnCopyToClipboard = await this.stateService.getMinimizeOnCopyToClipboard();
this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
@ -173,9 +194,6 @@ export class SettingsComponent implements OnInit {
this.biometricText = await this.stateService.getBiometricText(); this.biometricText = await this.stateService.getBiometricText();
this.noAutoPromptBiometrics = await this.stateService.getNoAutoPromptBiometrics(); this.noAutoPromptBiometrics = await this.stateService.getNoAutoPromptBiometrics();
this.noAutoPromptBiometricsText = await this.stateService.getNoAutoPromptBiometricsText(); this.noAutoPromptBiometricsText = await this.stateService.getNoAutoPromptBiometricsText();
this.alwaysShowDock = await this.stateService.getAlwaysShowDock();
this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
this.openAtLogin = await this.stateService.getOpenAtLogin();
} }
async saveVaultTimeoutOptions() { async saveVaultTimeoutOptions() {

View File

@ -457,9 +457,6 @@
"updateKey": { "updateKey": {
"message": "You cannot use this feature until you update your encryption key." "message": "You cannot use this feature until you update your encryption key."
}, },
"options": {
"message": "Options"
},
"editedFolder": { "editedFolder": {
"message": "Edited folder" "message": "Edited folder"
}, },
@ -1793,7 +1790,22 @@
"accountLimitReached": { "accountLimitReached": {
"message": "No more than 5 accounts may be logged in at the same time." "message": "No more than 5 accounts may be logged in at the same time."
}, },
"accountPreferences": {
"message": "Preferences"
},
"appPreferences": {
"message": "App Settings (All Accounts)"
},
"accountSwitcherLimitReached": { "accountSwitcherLimitReached": {
"message": "Account limit reached. Log out of an account to add another." "message": "Account limit reached. Log out of an account to add another."
},
"settingsTitle": {
"message": "App settings for $EMAIL$",
"placeholders": {
"email": {
"content": "$1",
"example": "jdoe@example.com"
}
}
} }
} }

View File

@ -4,6 +4,15 @@
position: relative; position: relative;
width: 100%; width: 100%;
.settingsTitle {
margin: 0 10px 5px 10px;
display: flex;
@include themify($themes) {
color: themed("headingColor");
}
}
.box-header { .box-header {
margin: 0 10px 5px 10px; margin: 0 10px 5px 10px;
text-transform: uppercase; text-transform: uppercase;
@ -33,6 +42,38 @@
} }
} }
.box-header-expandable {
border: none;
padding: 5px 0px;
text-transform: uppercase;
display: flex;
width: 100%;
box-sizing: border-box;
@include themify($themes) {
color: themed("headingColor");
background-color: themed("boxBackgroundColor");
}
&:hover,
&:focus,
&.active {
@include themify($themes) {
background-color: themed("boxBackgroundHoverColor");
}
}
.icon {
display: flex;
align-items: flex-end;
margin-left: 5px;
@include themify($themes) {
color: themed("headingColor");
}
}
}
.box-content { .box-content {
border-radius: $border-radius; border-radius: $border-radius;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12),