diff --git a/app/assets/stylesheets/app/_directives.scss b/app/assets/stylesheets/app/_directives.scss index 7a69224da..e9a9625bd 100644 --- a/app/assets/stylesheets/app/_directives.scss +++ b/app/assets/stylesheets/app/_directives.scss @@ -210,67 +210,6 @@ Extensions margin-top: 6px; } } - - } - } -} - -.account-data-menu { - padding: 5px !important; - - .providers { - font-size: 12px; - - .provider { - padding: 10px 10px; - padding-bottom: 8px; - margin-bottom: 10px; - - > .type { - font-weight: bold; - margin-bottom: 2px; - } - - > .key { - font-style: italic; - } - - > .url { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - // word-wrap: break-word; - margin-top: 2px; - } - - .sync-status { - font-weight: bold; - height: 30px; - } - - > .options { - margin-top: 10px; - } - } - } -} - -.account-keys-section { - .keys { - .key { - padding: 10px 10px; - padding-bottom: 8px; - margin-bottom: 8px; - - > .name { - font-size: 13px; - font-weight: bold; - margin-bottom: 2px; - } - - > .value { - word-wrap: break-word; - } } } } diff --git a/app/assets/stylesheets/app/_header.scss b/app/assets/stylesheets/app/_header.scss index 3c7153ae2..db519ee40 100644 --- a/app/assets/stylesheets/app/_header.scss +++ b/app/assets/stylesheets/app/_header.scss @@ -1,6 +1,15 @@ -.header { +.pull-left { + float: left; +} + +.pull-right { + float: right; +} + +.footer-bar { position: relative; width: 100%; + padding: 5px; background-color: #d8d7d9; height: $header-height; max-height: $header-height; @@ -10,140 +19,155 @@ border-bottom: 1px solid rgba(#979799, 0.4); a { - color: $dark-gray; - } - -} - -.header-content { - margin-bottom: 0px; - padding-top: 0px; - border-radius: 0px; - - left: 0px; - right: 0px; -} - -.panel-status-text { - margin-top: 20px; - font-style: italic; - font-size: 14px; -} - -.menu { - margin-left: 15px; - padding-top: 5px; - margin-top: 0px; - color: #515263; - z-index: 1000; - margin-bottom: 0px; - font-size: 11px; - - &.left { - float: left; - } - - &.right { - float: right; - margin-right: 10px; - } - - .login-panel .login-input { - border-radius: 0px; - } -} - -.items { - - .item { - - display: inline-block; - margin-right: 7px; - position: relative; - cursor: pointer; font-weight: bold; + cursor: pointer; + color: $blue-color; - a { - color: #515263; + &.gray { + color: $dark-gray !important; } - .panel { - position: absolute; - right: 0px; - bottom: 20px; - min-width: 300px; - z-index: 1000; - margin-top: 15px; - box-shadow: 0px 0px 15px rgba(black, 0.2); - border: none; - cursor: default; - max-height: 85vh; - overflow: auto; - background-color: white; - font-weight: normal; - - section { - margin-bottom: 10px; - } - - h3 { - font-weight: bold; - margin-top: 0px; - margin-bottom: 4px; - font-size: 16px; - width: 100%; - } - - a { - font-size: 12px; - color: $blue-color; - font-weight: bold; - } - - button.light { - font-weight: bold; - margin-bottom: 0px; - font-size: 12px; - height: 30px; - padding-top: 3px; - text-align: center; - margin-bottom: 6px; - background-color: white; - display: block; - width: 100%; - border: 1px solid rgba(gray, 0.15); - cursor: pointer; - color: $blue-color; - - &:hover { - background-color: rgba(gray, 0.10); - } - - .execution-spinner { - margin-left: auto; - margin-right: auto; - text-align: center; - margin-top: 3px; - } - } - - .storage-text { - font-size: 14px; - } - - .checkbox { - font-size: 14px; - font-weight: normal; - margin-left: auto; - margin-right: auto; - } + &.block { + display: block !important; } } + + p { + margin: 2px 0px; + font-size: 12px; + } + + label { + font-weight: bold; + margin-bottom: 4px; + } + + strong { + display: block; + } + + h3 { + font-size: 14px !important; + margin-top: 4px !important; + margin-bottom: 0px !important; + } + + h4 { + margin-bottom: 0px !important; + } + + section { + padding: 5px; + margin-top: 5px; + + &.inline-h { + padding: 5px 0px; + } + } + + input { + margin-bottom: 10px; + border-radius: 0px; + } + + .block { + display: block; + } + + .wrap { + word-wrap: break-word; + } + + .one-line-overflow { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + + .small-v-space { + height: 6px; + display: block; + } + + .medium-padding { + padding: 10px; + } + + .large-padding { + padding: 15px; + } } -.item.io { - .enc-option { - display: block; +.footer-bar-link { + font-size: 11px; + font-weight: bold; + margin-left: 8px; + color: #515263; + + z-index: 1000; + display: inline-block; + position: relative; + cursor: pointer; + + > a { + color: #515263; + } +} + +.footer-bar-link .panel { + font-weight: normal; + font-size: 12px; + + max-height: 85vh; + position: absolute; + right: 0px; + bottom: 20px; + min-width: 300px; + z-index: 1000; + margin-top: 15px; + + box-shadow: 0px 0px 15px rgba(black, 0.2); + border: none; + cursor: default; + overflow: auto; + background-color: white; + + button.light { + font-weight: bold; + margin-bottom: 0px; + font-size: 12px; + height: 30px; + padding-top: 3px; + text-align: center; + margin-bottom: 6px; + background-color: white; + display: block; + width: 100%; + border: 1px solid rgba(gray, 0.15); + cursor: pointer; + color: $blue-color; + + &:hover { + background-color: rgba(gray, 0.10); + } + + .execution-spinner { + margin-left: auto; + margin-right: auto; + text-align: center; + margin-top: 3px; + } + } + + .storage-text { + font-size: 14px; + } + + .checkbox { + font-size: 14px; + font-weight: normal; + margin-left: auto; + margin-right: auto; } } @@ -170,120 +194,26 @@ cursor: default !important; } -.item.account { +.account-panel { + width: 350px; +} - .email { - font-size: 18px; - font-weight: bold; - margin-bottom: 2px; +.import-password { + margin-top: 14px; + + > .field { + display: block; + margin: 5px 0px; } +} - .server { - margin-bottom: 10px; - } - - .links { - margin-bottom: 25px; - } - - .link-item { - margin-bottom: 8px; - - } - - input { - border-radius: 0px; - } - - .account-panel { - - padding: 12px; - padding-bottom: 6px; - - .account-items { - margin-top: 0px; +.encryption-confirmation { + position: relative; + .buttons { + .cancel { + font-weight: normal; + margin-right: 3px; } - - .account-section-content { - margin-top: 15px; - } - - .account-item { - width: 100%; - margin-bottom: 15px; - min-height: 50px; - padding: 20px 14px; - - a { - color: $blue-color; - font-weight: bold; - cursor: pointer; - } - - .meta-container { - display: block; - font-size: 10px; - } - - .action-container { - font-size: 12px; - margin-top: 6px; - - .status-title { - font-weight: bold; - } - - .subtext { - font-size: 10px; - margin-top: 2px; - } - - a { - display: block; - margin-bottom: -10px; - } - } - - .import-password { - margin-top: 14px; - - > .field { - display: block; - margin: 5px 0px; - } - } - - .encryption-confirmation { - position: relative; - .buttons { - .cancel { - font-weight: normal; - margin-right: 3px; - } - } - } - - &:last-child { - margin-bottom: 8px !important; - } - - .meta-container { - > .title { - font-size: 13px; - font-weight: bold; - } - - > .desc { - font-size: 12px; - margin-top: 3px; - } - } - } - - .membership-settings { - font-size: 14px; - } - } } @@ -291,23 +221,6 @@ a.disabled { pointer-events: none; } -.account-form { - margin-top: 10px; -} - -.registration-login { - - .login-forgot { - margin-top: 20px; - clear: both; - a { - display: block; - font-size: 13px !important; - text-align: center; - } - } -} - .spinner { height: 10px; width: 10px; diff --git a/app/assets/templates/frontend/directives/account-data-menu.html.haml b/app/assets/templates/frontend/directives/account-data-menu.html.haml index b05d2cb07..a778bdb31 100644 --- a/app/assets/templates/frontend/directives/account-data-menu.html.haml +++ b/app/assets/templates/frontend/directives/account-data-menu.html.haml @@ -1,20 +1,25 @@ .panel.panel-default.account-panel.panel-right.account-data-menu .panel-body - .account-items - %section.account-item.gray-bg{"ng-init" => "showSN = true"} - %h3{"ng-click" => "showSN = !showSN"} Standard Notes Account - %account-vendor-account-section{"ng-if" => "showSN"} - %section.account-item.gray-bg - %h3{"ng-click" => "showSync = !showSync"} Sync Locations ({{syncProviders.length}}) - %account-sync-section{"ng-if" => "showSync"} + %section.gray-bg.medium-padding{"ng-init" => "showSN = true"} + %h3{"ng-click" => "showSN = !showSN"} Standard Notes Account + .small-v-space + %account-vendor-account-section{"ng-if" => "showSN"} - %section.account-item.gray-bg - %h3{"ng-click" => "showKeys = !showKeys"} Encryption Keys ({{keys.length}}) - %account-keys-section{"ng-if" => "showKeys"} + %h4 + %a{"ng-click" => "showIO = !showIO"} Import/Export + %section.gray-bg{"ng-if" => "showIO"} + %import-export-menu{"ng-if" => "showIO"} - %section.account-item.gray-bg - %h3{"ng-click" => "showIO = !showIO"} Import/Export - %import-export-menu{"ng-if" => "showIO"} + %h4 + %a{"ng-click" => "showAdvanced = !showAdvanced"} Advanced + %div{"ng-if" => "showAdvanced"} + %section.gray-bg.medium-padding + %h3 Sync Locations ({{syncProviders.length}}) + %account-sync-section + %section.gray-bg.medium-padding + %h3 Encryption Keys ({{keys.length}}) + %account-keys-section + %h4 %a{"ng-click" => "destroyLocalData()"} Destroy all local data diff --git a/app/assets/templates/frontend/directives/account-keys-section.html.haml b/app/assets/templates/frontend/directives/account-keys-section.html.haml index a85a7a8c5..a82336b9c 100644 --- a/app/assets/templates/frontend/directives/account-keys-section.html.haml +++ b/app/assets/templates/frontend/directives/account-keys-section.html.haml @@ -1,11 +1,9 @@ -.account-keys-section.account-section-content - .keys - .key.white-bg{"ng-repeat" => "key in keys track by key.name"} - .name {{key.name}} - .value {{key.key}} +%section.white-bg{"ng-repeat" => "key in keys track by key.name"} + %label {{key.name}} + %p.wrap {{key.key}} - %a{"ng-click" => "newKeyData.showForm = !newKeyData.showForm"} Add New Key - %form{"ng-if" => "newKeyData.showForm"} - %input{"ng-model" => "newKeyData.name", "placeholder" => "Name your key"} - %input{"ng-model" => "newKeyData.key", "placeholder" => "Key"} - %button.light{"ng-click" => "submitNewKeyForm()"} Add Key +%a{"ng-click" => "newKeyData.showForm = !newKeyData.showForm"} Add New Key +%form{"ng-if" => "newKeyData.showForm"} + %input{"ng-model" => "newKeyData.name", "placeholder" => "Name your key"} + %input{"ng-model" => "newKeyData.key", "placeholder" => "Key"} + %button.light{"ng-click" => "submitNewKeyForm()"} Add Key diff --git a/app/assets/templates/frontend/directives/account-sync-section.html.haml b/app/assets/templates/frontend/directives/account-sync-section.html.haml index 270cc0beb..1e7e5f7cb 100644 --- a/app/assets/templates/frontend/directives/account-sync-section.html.haml +++ b/app/assets/templates/frontend/directives/account-sync-section.html.haml @@ -1,29 +1,27 @@ -.providers.account-section-content - .provider.white-bg{"ng-repeat" => "provider in syncProviders"} - .type {{!provider.enabled ? 'Not enabled' : (provider.primary ? 'Main' : 'Secondary')}} - .key{"ng-if" => "provider.keyName"} Using key: {{provider.keyName}} - .url {{provider.url}} - .options - %div{"ng-if" => "!provider.keyName || provider.showKeyForm"} - %p - %strong Choose encryption key: - %select{"ng-model" => "provider.formData.keyName"} - %option{"ng-repeat" => "key in keys", "ng-selected" => "{{key.name == provider.formData.keyName}}", "value" => "{{key.name}}"} - {{key.name}} - %button{"ng-click" => "saveKey(provider)"} Set +%section.white-bg{"ng-repeat" => "provider in syncProviders"} + %label {{!provider.enabled ? 'Not enabled' : (provider.primary ? 'Main' : 'Secondary')}} + %em{"ng-if" => "provider.keyName"} Using key: {{provider.keyName}} + %p {{provider.url}} + %section.inline-h + %div{"ng-if" => "!provider.keyName || provider.showKeyForm"} + %p + %strong Choose encryption key: + %select{"ng-model" => "provider.formData.keyName"} + %option{"ng-repeat" => "key in keys", "ng-selected" => "{{key.name == provider.formData.keyName}}", "value" => "{{key.name}}"} + {{key.name}} + %button{"ng-click" => "saveKey(provider)"} Set - %div{"ng-if" => "!provider.enabled"} - %button.light{"ng-click" => "enableSyncProvider(provider, true)"} Set as Main - %button.light{"ng-if" => "syncProviders.length > 1", "ng-click" => "enableSyncProvider(provider, false)"} Add as Secondary - %button.light{"ng-if" => "provider.keyName", "ng-click" => "changeEncryptionKey(provider)"} Change Encryption Key - %button.light{"ng-click" => "removeSyncProvider(provider)"} Remove Provider - .sync-status{"delay-hide" => "true", "show" => "provider.syncOpInProgress", "delay" => "1000"} - .text{"style" => "float: left;"} Syncing: {{provider.syncStatus.statusString}} - .spinner{"style" => "float: right"} + %div{"ng-if" => "!provider.enabled"} + %button.light{"ng-click" => "enableSyncProvider(provider, true)"} Set as Main + %button.light{"ng-if" => "syncProviders.length > 1", "ng-click" => "enableSyncProvider(provider, false)"} Add as Secondary + %button.light{"ng-if" => "provider.keyName", "ng-click" => "changeEncryptionKey(provider)"} Change Encryption Key + %button.light{"ng-click" => "removeSyncProvider(provider)"} Remove Provider + %div{"style" => "height: 30px;", "delay-hide" => "true", "show" => "provider.syncOpInProgress", "delay" => "1000"} + %strong{"style" => "float: left;"} Syncing: {{provider.syncStatus.statusString}} + .spinner{"style" => "float: right"} - %a{"ng-click" => "newSyncData.showAddSyncForm = !newSyncData.showAddSyncForm"} Add external sync with Secret URL - %form.sync-form{"ng-if" => "newSyncData.showAddSyncForm"} - .form-tag.has-feedback - %input.form-control{:autofocus => 'autofocus', :name => 'url', :placeholder => 'Secret URL', :required => true, :type => 'url', 'ng-model' => 'newSyncData.url'} - %button.btn.dark-button.btn-block{"ng-click" => "submitExternalSyncURL()"} - Add External Sync +%a{"ng-click" => "newSyncData.showAddSyncForm = !newSyncData.showAddSyncForm"} Add external sync with Secret URL +%form{"ng-if" => "newSyncData.showAddSyncForm"} + %input.form-control{:autofocus => 'autofocus', :name => 'url', :placeholder => 'Secret URL', :required => true, :type => 'url', 'ng-model' => 'newSyncData.url'} + %button.btn.dark-button.btn-block{"ng-click" => "submitExternalSyncURL()"} + Add External Sync diff --git a/app/assets/templates/frontend/directives/account-vendor-account-section.html.haml b/app/assets/templates/frontend/directives/account-vendor-account-section.html.haml index 9c4528909..f3dcf5993 100644 --- a/app/assets/templates/frontend/directives/account-vendor-account-section.html.haml +++ b/app/assets/templates/frontend/directives/account-vendor-account-section.html.haml @@ -1,43 +1,34 @@ -.registration-login.account-section-content +%div{"ng-if" => "user"} + %h3 {{user.email}} + %p {{serverURL}} %div{"ng-if" => "user"} - .email {{user.email}} - .server {{serverURL}} - .links{"ng-if" => "user"} - .link-item - %a{"ng-click" => "signOutPressed()"} Sign out - %p Note: Signing out does not delete your local items, extensions, and keys. - .meta-container - .title Local Encryption - .desc Notes are encrypted locally before being sent to the server. Neither the server owner nor an intrusive entity can decrypt your locally encrypted notes. - .action-container - %span.status-title Status: - {{encryptionStatusForNotes()}} - %div{"ng-if" => "!user"} - .meta-container - .title Sign in or Register (optional) - .desc Enter your Standard Notes account information. - .action-container - %form.account-form{'name' => "loginForm"} - .form-tag.has-feedback - %input.form-control{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'loginData.url'} - .form-tag.has-feedback - %input.form-control.login-input{:autofocus => 'autofocus', :name => 'email', :placeholder => 'Email', :required => true, :type => 'email', 'ng-model' => 'loginData.email'} - .form-tag.has-feedback - %input.form-control.login-input{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'loginData.user_password'} - .checkbox{"ng-if" => "localNotesCount() > 0"} - %label - %input{"type" => "checkbox", "ng-model" => "loginData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} - Merge local notes ({{localNotesCount()}} notes) - %button.btn.dark-button.half-button{"ng-click" => "loginSubmitPressed()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} - %span Sign In - %button.btn.dark-button.half-button{"ng-click" => "submitRegistrationForm()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} - %span Register - %br - .login-forgot{"style" => "padding-top: 4px;"} - %a.btn.btn-link{"ng-click" => "showResetForm = !showResetForm"} Passwords cannot be forgotten. - .panel-status-text{"ng-if" => "loginData.status", "style" => "font-size: 14px;"} {{loginData.status}} + %a{"ng-click" => "signOutPressed()"} Sign out + %p Note: Signing out does not delete your local items, extensions, and keys. + %label Local Encryption + %p Notes are encrypted locally before being sent to the server. Neither the server owner nor an intrusive entity can decrypt your locally encrypted notes. + %label Status: + {{encryptionStatusForNotes()}} +%div{"ng-if" => "!user"} + %label Sign in or Register (optional) + %p Enter your Standard Notes account information. + %form.account-form{'name' => "loginForm"} + %input.form-control{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'loginData.url'} + %input.form-control{:autofocus => 'autofocus', :name => 'email', :placeholder => 'Email', :required => true, :type => 'email', 'ng-model' => 'loginData.email'} + %input.form-control{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'loginData.user_password'} + .checkbox{"ng-if" => "localNotesCount() > 0"} + %label + %input{"type" => "checkbox", "ng-model" => "loginData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} + Merge local notes ({{localNotesCount()}} notes) + %button.btn.dark-button.half-button{"ng-click" => "loginSubmitPressed()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} + %span Sign In + %button.btn.dark-button.half-button{"ng-click" => "submitRegistrationForm()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} + %span Register + %br + .block{"style" => "margin-top: 10px; font-size: 14px; font-weight: bold; text-align: center;"} + %a.btn{"ng-click" => "showResetForm = !showResetForm"} Passwords cannot be forgotten. + %em{"ng-if" => "loginData.status", "style" => "font-size: 14px;"} {{loginData.status}} - %div{"ng-if" => "showResetForm"} - %p{"style" => "font-size: 13px; text-align: center;"} - Because notes are locally encrypted using a secret key derived from your password, there's no way to decrypt these notes if you forget your password. - For this reason, Standard Notes cannot offer a password reset option. You must make sure to store or remember your password. + %div{"ng-if" => "showResetForm"} + %p{"style" => "font-size: 13px; text-align: center;"} + Because notes are locally encrypted using a secret key derived from your password, there's no way to decrypt these notes if you forget your password. + For this reason, Standard Notes cannot offer a password reset option. You must make sure to store or remember your password. diff --git a/app/assets/templates/frontend/directives/import-export-menu.html.haml b/app/assets/templates/frontend/directives/import-export-menu.html.haml index 87b52c429..f20e60863 100644 --- a/app/assets/templates/frontend/directives/import-export-menu.html.haml +++ b/app/assets/templates/frontend/directives/import-export-menu.html.haml @@ -1,27 +1,27 @@ -.account-section-content - .options{"style" => "font-size: 12px; margin-top: 4px;"} - %label.enc-option{"ng-if" => "user"} - %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'mk'", "ng-change" => "archiveFormData.encryption_type = 'mk'"} - Encrypted with Standard File key - %label.enc-option - %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'ek'", "ng-change" => "archiveFormData.encryption_type = 'ek'"} - {{user ? 'Encrypted with custom key' : 'Encrypted' }} - %div{"ng-if" => "!user || (user && archiveFormData.encryption_type == 'ek')"} - %input{"ng-model" => "archiveFormData.ek", "placeholder" => "Encryption key"} - %label.enc-option - %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'none'", "ng-change" => "archiveFormData.encryption_type = 'none'"} - Decrypted - .action-container - %a{"ng-click" => "downloadDataArchive()"} Download Data Archive +.options{"style" => "font-size: 12px; margin-top: 4px;"} + %label{"ng-if" => "user"} + %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'mk'", "ng-change" => "archiveFormData.encryption_type = 'mk'"} + Encrypted with Standard File key + %label + %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'ek'", "ng-change" => "archiveFormData.encryption_type = 'ek'"} + {{user ? 'Encrypted with custom key' : 'Encrypted' }} + %div{"ng-if" => "!user || (user && archiveFormData.encryption_type == 'ek')"} + %input{"ng-model" => "archiveFormData.ek", "placeholder" => "Encryption key"} + %label + %input{"type" => "radio", "ng-model" => "archiveFormData.encryption_type", "ng-value" => "'none'", "ng-change" => "archiveFormData.encryption_type = 'none'"} + Decrypted - %div{"ng-if" => "!importData.loading"} - %label#import-archive - %input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"} - %a.disabled - %span - Import Data from Archive - .import-password{"ng-if" => "importData.requestPassword"} - Enter the account password associated with the import file. - %input.field{"type" => "text", "ng-model" => "importData.password"} - %button{"ng-click" => "submitImportPassword()"} Decrypt & Import - .spinner{"ng-if" => "importData.loading"} +%a{"ng-click" => "downloadDataArchive()"} Download Data Archive + +%div{"ng-if" => "!importData.loading"} + %label#import-archive + %input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"} + %a.disabled + %span + Import Data from Archive + %div{"ng-if" => "importData.requestPassword"} + Enter the account password associated with the import file. + %input{"type" => "text", "ng-model" => "importData.password"} + %button{"ng-click" => "submitImportPassword()"} Decrypt & Import + +.spinner{"ng-if" => "importData.loading"} diff --git a/app/assets/templates/frontend/header.html.haml b/app/assets/templates/frontend/header.html.haml index 0ab81a3b2..a9d7371cb 100644 --- a/app/assets/templates/frontend/header.html.haml +++ b/app/assets/templates/frontend/header.html.haml @@ -1,26 +1,24 @@ -.header - .header-content - .menu.left +.footer-bar + .pull-left + .footer-bar-link + %a{"ng-click" => "ctrl.accountMenuPressed()"} Account + %account-data-menu{"ng-if" => "ctrl.showAccountMenu"} - .items - .item.account - %a{"ng-click" => "ctrl.accountMenuPressed()"} Account - %account-data-menu{"ng-if" => "ctrl.showAccountMenu"} + .footer-bar-link + %a{"ng-click" => "ctrl.toggleExtensions()"} Extensions + %global-extensions-menu{"ng-if" => "ctrl.showExtensionsMenu"} - .item - %a{"ng-click" => "ctrl.toggleExtensions()"} Extensions - %global-extensions-menu{"ng-if" => "ctrl.showExtensionsMenu"} + .footer-bar-link + %a{"href" => "https://standardnotes.org", "target" => "_blank"} + Help - .item - %a{"href" => "https://standardnotes.org", "target" => "_blank"} - Help + .pull-right - .menu.right - .items - .item.last-refreshed{"ng-if" => "ctrl.lastSyncDate"} - %span{"ng-if" => "!ctrl.isRefreshing"} - Last refreshed {{ctrl.lastSyncDate | appDateTime}} - %span{"ng-if" => "ctrl.isRefreshing"} - .spinner - .item{"ng-click" => "ctrl.refreshData()"} - Refresh + .footer-bar-link + %div{"ng-if" => "ctrl.lastSyncDate", "style" => "float: left; font-weight: normal; margin-right: 8px;"} + %span{"ng-if" => "!ctrl.isRefreshing"} + Last refreshed {{ctrl.lastSyncDate | appDateTime}} + %span{"ng-if" => "ctrl.isRefreshing"} + .spinner{"style" => "margin-top: 2px;"} + + %a{"ng-click" => "ctrl.refreshData()"} Refresh