Select folder at save bar (#1409)

* Markup changes

* Render in notification bar folders list that is provided form TS code

* Implemented getting of folders list

* Refactor addPlatformEventListener and added default selection of "No Folder"

* Pass folder id info to saveAddLogin

* Modify saveAddLogin to use folder id

* Try to fix default folder selection

* Fix styling issues found during review

* Fix review issues found by kspearrin

* Fix default selection and null handling

* Fix import order

* Applied review suggestions

* Implement checking if folderExist during saving

* Fix compile issues

* Added select folder... option

* Add internalization for select folder message

* Hide select folder element on narrow screens

* Fix lint issues

* Review fixes in notification bar

* Adjust semi-responsive layout for folder selector

* Revert style change

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
This commit is contained in:
Dmitry Chepurovskiy 2021-09-03 04:54:52 +03:00 committed by GitHub
parent 61f551087f
commit cd2f174923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 8 deletions

View File

@ -1764,5 +1764,8 @@
},
"updateMasterPasswordWarning": {
"message": "Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour."
},
"selectFolder": {
"message": "Select folder..."
}
}

View File

@ -244,7 +244,7 @@ export default class MainBackground {
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService,
this.notificationsService, this.systemService, this.vaultTimeoutService,
this.environmentService, this.policyService, this.userService, this.messagingService);
this.environmentService, this.policyService, this.userService, this.messagingService, this.folderService);
this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService,
this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService, this.appIdService,
this.platformUtilsService);

View File

@ -6,6 +6,7 @@ import { LoginView } from 'jslib-common/models/view/loginView';
import { CipherService } from 'jslib-common/abstractions/cipher.service';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
import { FolderService } from 'jslib-common/abstractions/folder.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { NotificationsService } from 'jslib-common/abstractions/notifications.service';
@ -39,7 +40,8 @@ export default class RuntimeBackground {
private notificationsService: NotificationsService,
private systemService: SystemService, private vaultTimeoutService: VaultTimeoutService,
private environmentService: EnvironmentService, private policyService: PolicyService,
private userService: UserService, private messagingService: MessagingService) {
private userService: UserService, private messagingService: MessagingService,
private folderService: FolderService) {
// onInstalled listener must be wired up before anything else, so we do it in the ctor
chrome.runtime.onInstalled.addListener((details: any) => {
@ -107,7 +109,7 @@ export default class RuntimeBackground {
this.removeTabFromNotificationQueue(sender.tab);
break;
case 'bgAddSave':
await this.saveAddLogin(sender.tab);
await this.saveAddLogin(sender.tab, msg.folder);
break;
case 'bgChangeSave':
await this.saveChangePassword(sender.tab);
@ -218,7 +220,7 @@ export default class RuntimeBackground {
this.pageDetailsToAutoFill = [];
}
private async saveAddLogin(tab: any) {
private async saveAddLogin(tab: any, folderId: string) {
if (await this.vaultTimeoutService.isLocked()) {
return;
}
@ -249,6 +251,13 @@ export default class RuntimeBackground {
model.type = CipherType.Login;
model.login = loginModel;
if (!Utils.isNullOrWhitespace(folderId)) {
const folders = await this.folderService.getAllDecrypted();
if (folders.some(x => x.id === folderId)) {
model.folderId = folderId;
}
}
const cipher = await this.cipherService.encrypt(model);
await this.cipherService.saveWithServer(cipher);
}
@ -452,6 +461,8 @@ export default class RuntimeBackground {
notificationChangeSave: this.i18nService.t('notificationChangeSave'),
notificationChangeDesc: this.i18nService.t('notificationChangeDesc'),
};
} else if (responseCommand === 'notificationBarGetFoldersList') {
responseData.folders = await this.folderService.getAllDecrypted();
}
await BrowserApi.tabSendMessageData(tab, responseCommand, responseData);

View File

@ -27,8 +27,11 @@
<tbody>
<tr>
<td class="add-text"></td>
<td align="right" class="add-buttons">
<td align="right">
<button class="never-save link"></button>
</td>
<td align="right" class="add-buttons">
<select class="select-folder"></select>
<button class="add-save"></button>
</td>
</tr>

View File

@ -17,7 +17,6 @@ document.addEventListener('DOMContentLoaded', () => {
// delay 50ms so that we get proper body dimensions
setTimeout(load, 50);
function load() {
var closeButton = document.getElementById('close-button'),
@ -34,10 +33,12 @@ document.addEventListener('DOMContentLoaded', () => {
if (bodyRect.width < 768) {
document.querySelector('#template-add .add-save').textContent = i18n.yes;
document.querySelector('#template-add .never-save').textContent = i18n.never;
document.querySelector('#template-add .select-folder').style.display = 'none';
document.querySelector('#template-change .change-save').textContent = i18n.yes;
} else {
document.querySelector('#template-add .add-save').textContent = i18n.notificationAddSave;
document.querySelector('#template-add .never-save').textContent = i18n.notificationNeverSave;
document.querySelector('#template-add .select-folder').style.display = 'initial';
document.querySelector('#template-change .change-save').textContent = i18n.notificationChangeSave;
}
@ -53,7 +54,8 @@ document.addEventListener('DOMContentLoaded', () => {
addButton.addEventListener('click', (e) => {
e.preventDefault();
sendPlatformMessage({
command: 'bgAddSave'
command: 'bgAddSave',
folder: document.getElementById("select-folder").value,
});
});
@ -63,6 +65,17 @@ document.addEventListener('DOMContentLoaded', () => {
command: 'bgNeverSave'
});
});
const responseFoldersCommand = 'notificationBarGetFoldersList';
chrome.runtime.onMessage.addListener((msg) => {
if (msg.command === responseFoldersCommand && msg.data) {
fillSelectorWithFolders(msg.data.folders);
}
});
sendPlatformMessage({
command: 'bgGetDataForTab',
responseCommand: responseFoldersCommand
});
} else if (getQueryVariable('change')) {
setContent(document.getElementById('template-change'));
var changeButton = document.querySelector('#template-change-clone .change-save');
@ -120,4 +133,13 @@ document.addEventListener('DOMContentLoaded', () => {
function sendPlatformMessage(msg) {
chrome.runtime.sendMessage(msg);
}
function fillSelectorWithFolders(folders) {
const select = document.querySelector('#template-add-clone .select-folder');
select.appendChild(new Option(chrome.i18n.getMessage('selectFolder'), null, true));
folders.forEach((folder) => {
//Select "No Folder" (id=null) folder by default
select.appendChild(new Option(folder.name, folder.id || '', false));
});
}
});

View File

@ -82,7 +82,7 @@ button.link {
}
body[class*='lang-en'] .add-buttons {
width: 175px;
width: 50px;
}
@media (min-width: 768px) {
@ -96,3 +96,4 @@ body[class*='lang-en'] .add-buttons {
display: none;
}
}