Merge branch 'i18n'

Conflicts:
	app/coffee/Features/User/UserPagesController.coffee
	app/views/layout.jade
	app/views/project/editor/dropbox.jade
	app/views/project/editor/file-tree.jade
	app/views/project/editor/pdf.jade
	app/views/project/list/project-list.jade
	app/views/user/settings.jade
This commit is contained in:
Henry Oswald 2014-08-07 14:46:17 +01:00
commit 9c6f0faff6
55 changed files with 498 additions and 484 deletions

View file

@ -18,7 +18,7 @@ module.exports = AuthenticationController =
res.statusCode = 429
return res.send
message:
text: 'This account has had too many login requests. Please wait 2 minutes before trying to log in again',
text: req.i18n.translate("to_many_login_requests_2_mins"),
type: 'error'
AuthenticationManager.authenticate email: email, password, (error, user) ->
return next(error) if error?
@ -33,7 +33,7 @@ module.exports = AuthenticationController =
AuthenticationController._recordFailedLogin()
logger.log email: email, "failed log in"
res.send message:
text: 'Your email or password were incorrect. Please try again',
text: req.i18n.translate("email_or_password_wrong_try_again"),
type: 'error'
getAuthToken: (req, res, next = (error) ->) ->

View file

@ -2,4 +2,4 @@ module.exports = ErrorController =
notFound: (req, res)->
res.statusCode = 404
res.render 'general/404',
title: "Page Not Found"
title: "page_not_found"

View file

@ -6,7 +6,7 @@ module.exports =
renderRequestResetForm: (req, res)->
res.render "user/passwordReset",
title:"Reset Password"
title:"reset_password"
requestReset: (req, res)->
email = req.body.email.trim().toLowerCase()
@ -17,7 +17,7 @@ module.exports =
throttle: 6
RateLimiter.addCount opts, (err, canCompile)->
if !canCompile
return res.send 500, { message: "Rate limit hit. Please wait a while before retrying" }
return res.send 500, { message: req.i18n.translate("rate_limit_hit_wait")}
PasswordResetHandler.generateAndEmailResetToken email, (err)->
if err?
res.send 500, {message:err?.message}
@ -26,7 +26,7 @@ module.exports =
renderSetPasswordForm: (req, res)->
res.render "user/setPassword",
title:"Set Password"
title:"set_password"
passwordResetToken:req.query.passwordResetToken
setNewUserPassword: (req, res)->

View file

@ -157,7 +157,7 @@ module.exports = ProjectController =
loadEditor: (req, res, next)->
timer = new metrics.Timer("load-editor")
if !Settings.editorIsOpen
return res.render("general/closed", {title:"updating site"})
return res.render("general/closed", {title:"updating_site"})
if req.session.user?
user_id = req.session.user._id

View file

@ -5,6 +5,6 @@ module.exports =
bonus: (req, res)->
ReferalHandler.getReferedUserIds req.session.user._id, (err, refered_users)->
res.render "referal/bonus",
title: "Bonus - Please recommend us"
title: "bonus_please_recommend_us"
refered_users: refered_users
refered_user_count: (refered_users or []).length

View file

@ -21,7 +21,7 @@ module.exports = SubscriptionController =
viewName = "subscriptions/plans"
logger.log viewName:viewName, "showing plans page"
res.render viewName,
title: "Plans and Pricing"
title: "plans_and_pricing"
plans: plans
baseUrl: baseUrl
@ -41,7 +41,7 @@ module.exports = SubscriptionController =
}, (error, signature) ->
return next(error) if error?
res.render "subscriptions/new",
title : "Subscribe"
title : "subscribe"
plan_code: req.query.planCode
recurlyConfig: JSON.stringify
currency: "USD"
@ -74,7 +74,7 @@ module.exports = SubscriptionController =
logger.log user: user, subscription:subscription, hasSubOrFreeTrial:hasSubOrFreeTrial, "showing subscription dashboard"
plans = SubscriptionViewModelBuilder.buildViewModel()
res.render "subscriptions/dashboard",
title: "Your Subscription"
title: "your_subscription"
plans: plans
subscription: subscription
subscriptionTabActive: true
@ -92,7 +92,7 @@ module.exports = SubscriptionController =
}, (error, signature) ->
return next(error) if error?
res.render "subscriptions/edit-billing-details",
title : "Update Billing Details"
title : "update_billing_details"
recurlyConfig: JSON.stringify
currency: "USD"
subdomain: Settings.apis.recurly.subdomain
@ -115,7 +115,7 @@ module.exports = SubscriptionController =
SecurityManager.getCurrentUser req, (error, user) =>
SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel user, (error, subscription) ->
res.render "subscriptions/successful_subscription",
title: "Thank you!"
title: "thank_you"
subscription:subscription
cancelSubscription: (req, res, next) ->

View file

@ -29,6 +29,6 @@ module.exports =
return res.redirect("/")
SubscriptionGroupHandler.getPopulatedListOfMembers user_id, (err, users)->
res.render "subscriptions/group_admin",
title: 'Group Admin'
title: 'group_admin'
users: users
subscription: subscription

View file

@ -10,7 +10,7 @@ module.exports = TemplatesWebController =
if err? or !data?
logger.err err:err, "something went wrong in renderTemplatesIndexPage"
return res.send 500
data.title = "LaTeX Templates"
data.title = "latex_templates"
res.render "templates/index", data
renerTemplateInTag: (req, res)->
@ -60,7 +60,7 @@ module.exports = TemplatesWebController =
if err?
logger.err err:err, user_id:user_id, "something went wrong in _renderCanonicalPage"
return res.send 500
data.title = "All Templates"
data.title = "all_templates"
res.render "templates/tag", data
_renderTagPage: (req, res)->

View file

@ -63,7 +63,11 @@ module.exports =
UserUpdater.changeEmailAddress user_id, newEmail, (err)->
if err?
logger.err err:err, user_id:user_id, newEmail:newEmail, "problem updaing users email address"
return res.send 500, {message:err?.message}
if err.message == "alread_exists"
message = req.i18n.translate("alread_exists")
else
message = req.i18n.translate("problem_changing_email_address")
return res.send 500, {message:message}
res.send(200)
logout : (req, res)->

View file

@ -16,16 +16,15 @@ module.exports =
newTemplateData.templateName = req.session.templateData.templateName
res.render 'user/register',
title: 'Register'
title: 'register'
redir: req.query.redir
sharedProjectData: sharedProjectData
newTemplateData: newTemplateData
new_email:req.query.new_email || ""
loginPage : (req, res)->
console.info req
res.render 'user/login',
title: 'Login',
title: 'login',
redir: req.query.redir
settingsPage : (req, res)->
@ -34,7 +33,7 @@ module.exports =
dropboxHandler.getUserRegistrationStatus user._id, (err, status)->
userIsRegisteredWithDropbox = !err? and status.registered
res.render 'user/settings',
title:'Account Settings',
title:'account_settings',
userHasDropboxFeature: user.features.dropbox
userIsRegisteredWithDropbox: userIsRegisteredWithDropbox
user: user,

View file

@ -19,7 +19,7 @@ module.exports = UserUpdater =
logger.log user_id:user_id, newEmail:newEmail, "updaing email address of user"
UserLocator.findByEmail newEmail, (error, user) ->
if user?
return callback({message:"User with that email already exists."})
return callback({message:"alread_exists"})
self.updateUser user_id.toString(), {
$set: { "email": newEmail},
}, (err) ->

View file

@ -51,6 +51,7 @@ module.exports = (app)->
app.use (req, res, next)->
res.locals.translate = req.i18n.translate
res.locals.currentUrl = req.originalUrl
next()
app.use (req, res, next)->

View file

@ -18,7 +18,7 @@ oneDayInMilliseconds = 86400000
ReferalConnect = require('../Features/Referal/ReferalConnect')
RedirectManager = require("./RedirectManager")
OldAssetProxy = require("./OldAssetProxy")
translations = require "translations-sharelatex"
translations = require("translations-sharelatex").setup(Settings.i18n)
metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongojs/node_modules/mongodb"), logger)
metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongoose/node_modules/mongodb"), logger)
@ -40,6 +40,8 @@ ignoreCsrfRoutes = []
app.ignoreCsrf = (method, route) ->
ignoreCsrfRoutes.push new express.Route(method, route)
app.configure () ->
if Settings.behindProxy
app.enable('trust proxy')
@ -49,10 +51,12 @@ app.configure () ->
app.use express.bodyParser(uploadDir: Settings.path.uploadFolder)
app.use express.bodyParser(uploadDir: __dirname + "/../../../data/uploads")
app.use translations.expressMiddlewear
app.use translations.setLangBasedOnDomainMiddlewear
app.use cookieParser
app.use express.session
proxy: Settings.behindProxy
cookie:
domain: Settings.cookieDomain
maxAge: cookieSessionLength
secure: Settings.secureCookie
store: sessionStore
@ -90,7 +94,7 @@ app.use (req, res, next)->
app.use (req, res, next) ->
if !Settings.editorIsOpen
res.status(503)
res.render("general/closed", {title:"Maintenance"})
res.render("general/closed", {title:"maintenance"})
else
next()

View file

@ -6,8 +6,8 @@ block content
.row
.col-md-8.col-md-offset-2.text-center
.page-header
h2 Sorry, we can't find the page you are looking for.
h2 #{translate("cant_find_page")}
p
a(href="/")
i.fa.fa-arrow-circle-o-left
| Take me home!
| #{translate("take_me_home")}

View file

@ -3,14 +3,21 @@ html(itemscope, itemtype='http://schema.org/Product')
block vars
head
-if (typeof(title) == "undefined")
title ShareLaTeX, the Online LaTeX Editor
-else
title= title + ' - ShareLaTeX, the Online LaTeX Editor'
- if (typeof(priority_title) !== "undefined" && priority_title)
title= title + ' - '+ translate("online_latex_editor")
- else
title= translate("online_latex_editor") +' ShareLaTeX - ' +translate(title)
title= translate(title) + ' - ShareLaTeX, '+
link(rel="icon", href="/favicon.ico")
link(rel='stylesheet', href='/stylesheets/style.css?fingerprint='+fingerprint('/stylesheets/style.css'))
link(href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css",rel="stylesheet")
if settings.i18n.subdomainLang
each subdomainDetails in settings.i18n.subdomainLang
link(rel="alternate", href=subdomainDetails.url+currentUrl, hreflang=subdomainDetails.lngCode)
meta(itemprop="name" ,content="ShareLaTeX - Real Time Online LaTeX Collaborative Editor in Your Browser")
meta(itemprop="description", content="Online LaTeX editor for collaborative editing, great for Maths or Sciences. You don't need to install LaTeX so it's great for beginners too.")
meta(itemprop="image", content="https://www.sharelatex.com/favicon.ico")

View file

@ -6,13 +6,14 @@ nav.navbar.navbar-default
a(href='/').navbar-brand
.navbar-collapse.collapse(collapse="navCollapsed")
ul.nav.navbar-nav.navbar-right
each item in nav.header
if ((item.only_when_logged_in && session && session.user) || (item.only_when_logged_out && (!session || !session.user)) || (!item.only_when_logged_out && !item.only_when_logged_in))
if item.dropdown
li.dropdown(class=item.class)
a.dropdown-toggle(href)
| !{item.text}
| !{translate(item.text)}
b.caret
ul.dropdown-menu
each child in item.dropdown
@ -21,14 +22,14 @@ nav.navbar.navbar-default
else
li
if child.url
a(href=child.url, class=child.class) !{child.text}
a(href=child.url, class=child.class) !{translate(child.text)}
else
| !{child.text}
| !{translate(child.text)}
else
li(class=item.class)
if item.url
a(href=item.url, class=item.class) !{item.text}
a(href=item.url, class=item.class) !{translate(item.text)}
else
| !{item.text}
| !{translate(item.text)}

View file

@ -10,30 +10,25 @@ block content
.editor(ng-controller="IdeController").full-size
.loading-screen(ng-show="state.loading")
.container
h3 Loading...
h3 #{translate("loading")}...
.progress
.progress-bar(style="width: 20%", ng-style="{'width': state.load_progress + '%'}")
.global-alerts(ng-cloak)
.alert.alert-danger.small(ng-if="connection.forced_disconnect")
strong Disconnected
| Please refresh the page to continue.
strong #{translate("disconnected")}
| #{translate("please_refresh")}
.alert.alert-warning.small(ng-if="connection.reconnection_countdown")
strong Lost Connection.
| Reconnecting in {{ connection.reconnection_countdown }} secs.
a.pull-right(href, ng-click="tryReconnectNow()") Try Now
strong #{translate("lost_connection")}.
| #{translate("reconnecting_in_x_secs", {seconds:"{{ connection.reconnection_countdown }}"})}.
a.pull-right(href, ng-click="tryReconnectNow()") #{translate("try_now")}
.alert.alert-warning.small(ng-if="connection.reconnecting")
strong Reconnecting...
strong #{translate("reconnecting")}...
.div(ng-controller="SavingNotificationController")
.alert.alert-warning.small(
ng-repeat="(doc_id, state) in docSavingStatus"
ng-if="state.unsavedSeconds > 3"
)
| Saving {{ state.doc.name }}... ({{ state.unsavedSeconds }} seconds of unsaved changes)
.alert.alert-warning.small( ng-repeat="(doc_id, state) in docSavingStatus" ng-if="state.unsavedSeconds > 3") #{translate("saving_notification_with_seconds", {docname:"{{ state.doc.name }}", seconds:"{{ state.unsavedSeconds }}"})}
include ./editor/left-menu
@ -78,7 +73,7 @@ block content
h3 {{ title }}
.modal-body {{ message }}
.modal-footer
button.btn.btn-info(ng-click="done()") OK
button.btn.btn-info(ng-click="done()") #{translate("ok")}
script(src='/socket.io/socket.io.js')

View file

@ -13,7 +13,7 @@ div.binary-file.full-size(
)
p.no-preview(
ng-if="['png', 'jpg', 'jpeg', 'gif', 'pdf', 'eps'].indexOf(extension(openFile)) == -1"
) Sorry, no preview is available.
) #{translate("no_preview_available")}
a.btn.btn-info(
ng-href="/project/{{ project_id }}/file/{{ openFile.id }}"
) Download {{ openFile.name }}
) #{translate("download")} {{ openFile.name }}

View file

@ -12,11 +12,11 @@ aside.chat(
.infinite-scroll-inner
.loading(ng-show="chat.loading")
i.fa.fa-fw.fa-spin.fa-refresh
|   Loading...
|   #{translate("loading")}...
.no-messages.text-center.small(ng-show='!chat.loading && chat.messages.length == 0')
| No messages
| #{translate("no_messages")}
.first-message.text-center(ng-show='!chat.loading && chat.messages.length == 0')
| Send your first message
| #{translate("send_first_message")}
br
i.fa.fa-arrow-down
ul.list-unstyled(
@ -27,8 +27,7 @@ aside.chat(
ng-controller="ChatMessageController"
ng-class="{'self': message.user.id == user.id }"
)
div.date(ng-if="$index == 0 || (message.timestamp - chat.messages[$index - 1].timestamp) > 5 * 60 * 1000")
{{ message.timestamp | formatDate:'h:mm a' }} {{ message.timestamp | relativeDate }}
div.date(ng-if="$index == 0 || (message.timestamp - chat.messages[$index - 1].timestamp) > 5 * 60 * 1000") {{ message.timestamp | formatDate:'h:mm a' }} {{ message.timestamp | relativeDate }}
span.avatar
img(ng-src="{{message.user.gravatar_url}}?d=mm&s=50")
div.message-wrapper

View file

@ -5,44 +5,41 @@ script(type="text/ng-template", id="dropboxModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) ×
h3 Dropbox Sync
h3 #{translate("dropbox_sync")}
.modal-body.modal-body-share
div(ng-show="dbState.gotLinkStatus")
div(ng-hide="dbState.userIsLinkedToDropbox || !dbState.hasDropboxFeature")
span(ng-hide="dbState.startedLinkProcess") Your account is not linked to dropbox
span(ng-hide="dbState.startedLinkProcess") #{translate("account_not_linked_to_dropbox")}
|    
a(ng-click="linkToDropbox()").btn.btn-info Update Dropbox Settings
a(ng-click="linkToDropbox()").btn.btn-info #{translate("update_dropbox_settings")}
p.small.text-center(ng-show="dbState.startedLinkProcess")
| Please refresh this page after starting your free trial.
| #{translate("refresh_page_after_starting_free_trial")}
div(ng-show="dbState.hasDropboxFeature && dbState.userIsLinkedToDropbox")
progressbar.progress-striped.active(value='dbState.percentageLeftTillNextPoll', type="info")
p
strong {{dbState.minsTillNextPoll}} minutes
span until Dropbox is next checked for changes.
strong {{dbState.minsTillNextPoll}} #{translate("minutes")}
span #{translate("until_db_checked_for_changes")}
p.small
| This project will appear in your Dropbox folder at
| #{translate("this_project_will_appear_in_your_dropbox_folder_at")}
strong Dropbox/sharelatex/{{ project.name }}
div.text-center(ng-hide="dbState.hasDropboxFeature")
p You need to upgrade your account to link to dropbox.
p #{translate("need_to_upgrade_for_dropbox")}
p
a.btn.btn-info(ng-click="startFreeTrial('dropbox')") Start Free Trial
a.btn.btn-info(ng-click="startFreeTrial('dropbox')") #{translate("start_free_trial")}
p.small(ng-show="startedFreeTrial")
| Please refresh this page after starting your free trial.
| #{translate("refresh_page_after_starting_free_trial")}
div(ng-hide="dbState.gotLinkStatus")
i.fa.fa-refresh.fa-spin
span.small   Checking dropbox status
span.small   #{translate("checking_dropbox_status")}
.modal-footer()
button.btn.btn-default(
ng-click="cancel()",
)
span Dismiss
span #{translate("dismiss")}

View file

@ -10,7 +10,7 @@ div.full-size(
.ui-layout-center
.loading-panel(ng-show="!editor.sharejs_doc || editor.opening")
i.fa.fa-spin.fa-refresh
|   Loading...
|   #{translate("loading")}...
#editor(
ace-editor="editor",

View file

@ -137,13 +137,13 @@ script(type='text/ng-template', id='entityListItemTemplate')
href
ng-click="startRenaming()"
right-click="startRenaming()"
) Rename
) #{translate("rename")}
li
a(
href
ng-click="openDeleteModal()"
right-click="openDeleteModal()"
) Delete
) #{translate("delete")}
div.dropdown.context-menu(
id="context-menu-{{ entity.id }}",
@ -155,13 +155,13 @@ script(type='text/ng-template', id='entityListItemTemplate')
href
ng-click="startRenaming()"
right-click="startRenaming()"
) Rename
) #{translate("rename")}
li
a(
href
ng-click="openDeleteModal()"
right-click="openDeleteModal()"
) Delete
) #{translate("delete")}
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
@ -219,32 +219,32 @@ script(type='text/ng-template', id='entityListItemTemplate')
href
ng-click="startRenaming()"
right-click="startRenaming()"
) Rename
) #{translate("rename")}
li
a(
href
ng-click="openDeleteModal()"
right-click="openDeleteModal()"
) Delete
) #{translate("delete")}
li.divider
li
a(
href
ng-click="openNewDocModal()"
right-click="openNewDocModal()"
) New File
) #{translate("new_file")}
li
a(
href
ng-click="openNewFolderModal()"
right-click="openNewFolderModal()"
) New Folder
) #{translate("new_folder")}
li
a(
href
ng-click="openUploadFileModal()"
right-click="openUploadFileModal()"
) Upload File
) #{translate("upload_file")}
.dropdown.context-menu(
ng-if="permissions.write"
@ -256,32 +256,32 @@ script(type='text/ng-template', id='entityListItemTemplate')
href
ng-click="startRenaming()"
right-click="startRenaming()"
) Rename
) #{translate("rename")}
li
a(
href
ng-click="openDeleteModal()"
right-click="openDeleteModal()"
) Delete
) #{translate("delete")}
li.divider
li
a(
href
ng-click="openNewDocModal()"
right-click="openNewDocModal()"
) New File
) #{translate("new_file")}
li
a(
href
ng-click="openNewFolderModal()"
right-click="openNewFolderModal()"
) New Folder
) #{translate("new_folder")}
li
a(
href
ng-click="openUploadFileModal()"
right-click="openUploadFileModal()"
) Upload File
) #{translate("upload_file")}
ul.list-unstyled(
ng-if="entity.type == 'folder'"
@ -298,7 +298,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
script(type='text/ng-template', id='newDocModalTemplate')
.modal-header
h3 New File
h3 #{translate("new_file")}
.modal-body
form(novalidate, name="newDocForm")
input.form-control(
@ -313,17 +313,17 @@ script(type='text/ng-template', id='newDocModalTemplate')
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="newDocForm.$invalid || state.inflight"
ng-click="create()"
)
span(ng-hide="state.inflight") Create
span(ng-show="state.inflight") Creating...
span(ng-hide="state.inflight") #{translate("create")}
span(ng-show="state.inflight") #{translate("creating")}...
script(type='text/ng-template', id='newFolderModalTemplate')
.modal-header
h3 New Folder
h3 #{translate("new_folder")}
.modal-body
form(novalidate, name="newFolderForm")
input.form-control(
@ -338,17 +338,17 @@ script(type='text/ng-template', id='newFolderModalTemplate')
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="newFolderForm.$invalid || state.inflight"
ng-click="create()"
)
span(ng-hide="state.inflight") Create
span(ng-show="state.inflight") Creating...
span(ng-hide="state.inflight") #{translate("create")}
span(ng-show="state.inflight") #{translate("creating")}...
script(type="text/ng-template", id="uploadFileModalTemplate")
.modal-header
h3 Upload File(s)
h3 #{translate("upload_files")}
.modal-body(
fine-upload
endpoint="/project/{{ project_id }}/upload"
@ -362,23 +362,23 @@ script(type="text/ng-template", id="uploadFileModalTemplate")
on-upload-callback="onUpload"
params="{'folder_id': parent_folder_id}"
)
span Upload file(s)
span #{translate("upload_files")}
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel
button.btn.btn-default(ng-click="cancel()") #{translate("cancel")}
script(type='text/ng-template', id='deleteEntityModalTemplate')
.modal-header
h3 Delete {{ entity.name }}
h3 #{translate("delete")} {{ entity.name }}
.modal-body
p Are you sure you want to permanently delete <strong>{{ entity.name }}</strong>?
p #{translate("sure_you_want_to_delete")}
.modal-footer
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-danger(
ng-disabled="state.inflight"
ng-click="delete()"
)
span(ng-hide="state.inflight") Delete
span(ng-show="state.inflight") Deleting...
span(ng-hide="state.inflight") #{translate("delete")}
span(ng-show="state.inflight") #{translate("deleting")}...

View file

@ -5,9 +5,9 @@ script(type="text/ng-template", id="hotkeysModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Hotkeys
h3 #{translate("hotkeys")}
.modal-body.modal-hotkeys
h3 Common
h3 #{translate("common")}
.row
.col-xs-6
.hotkey
@ -24,7 +24,7 @@ script(type="text/ng-template", id="hotkeysModalTemplate")
span.combination {{ctrl}} + Y
span.description Redo
h3 Navigation
h3 #{translate("navigation")}
.row
.col-xs-6
.hotkey
@ -38,7 +38,7 @@ script(type="text/ng-template", id="hotkeysModalTemplate")
span.combination {{ctrl}} + L
span.description Go To Line
h3 Editing
h3 #{translate("editing")}
.row
.col-xs-6
.hotkey
@ -63,4 +63,4 @@ script(type="text/ng-template", id="hotkeysModalTemplate")
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
) OK
) #{translate("ok")}

View file

@ -2,7 +2,7 @@ aside#left-menu.full-size(
ng-class="{ 'shown': ui.leftMenuShown }"
ng-cloak
)
h4 Download
h4 #{translate("download")}
ul.list-unstyled.nav.nav-downloads.text-center
li
@ -12,7 +12,7 @@ aside#left-menu.full-size(
)
i.fa.fa-file-archive-o.fa-2x
br
| Source
| #{translate("source")}
li
a(
ng-href="{{pdf.url}}"
@ -32,7 +32,7 @@ aside#left-menu.full-size(
| PDF
span(ng-show="!anonymous")
h4 Actions
h4 #{translate("Actions")}
ul.list-unstyled.nav
li(ng-controller="CloneProjectController")
a(
@ -40,26 +40,26 @@ aside#left-menu.full-size(
ng-click="openCloneProjectModal()"
)
i.fa.fa-fw.fa-copy
| &nbsp;&nbsp;Copy Project
| &nbsp;&nbsp;#{translate("copy_project")}
li(ng-controller="TemplatesController", ng-show="permissions.admin")
a(ng-click="openPublishTemplateModal()")
i.fa.fa-external-link.fa-fw
| &nbsp;&nbsp;Publish as Template
| &nbsp;&nbsp; #{translate("publish_as_template")}
span(ng-controller="DropboxController", ng-show="permissions.admin")
h4() Sync
h4() #{translate("sync")}
ul.list-unstyled.nav()
li
a(ng-click="openDropboxModal()")
i.fa.fa-dropbox.fa-fw
| &nbsp;&nbsp; Dropbox
h4(ng-show="!anonymous") Settings
h4(ng-show="!anonymous") #{translate("settings")}
form.settings(ng-controller="SettingsController", ng-show="!anonymous")
.containter-fluid
.form-controls(ng-show="permissions.write")
label(for="compiler") Compiler
label(for="compiler") #{translate("compiler")}
select(
name="compiler"
ng-model="project.compiler"
@ -70,7 +70,7 @@ aside#left-menu.full-size(
option(value='lualatex') LuaLaTeX
.form-controls(ng-show="permissions.write")
label(for="rootDoc_id") Main document
label(for="rootDoc_id") #{translate("main_document")}
select(
name="rootDoc_id",
ng-model="project.rootDoc_id",
@ -78,12 +78,12 @@ aside#left-menu.full-size(
)
.form-controls
label(for="spellCheckLanguage") Spell Check
label(for="spellCheckLanguage") #{translate("spell_check")}
select(
name="spellCheckLanguage"
ng-model="project.spellCheckLanguage"
)
option(value="") Off
option(value="") #{translate("off")}
optgroup(label="Language")
for language in languages
option(
@ -91,7 +91,7 @@ aside#left-menu.full-size(
)= language.name
.form-controls
label(for="autoComplete") Auto-Complete
label(for="autoComplete") #{translate("auto_complete")}
select(
name="autoComplete"
ng-model="settings.autoComplete"
@ -99,7 +99,7 @@ aside#left-menu.full-size(
)
.form-controls
label(for="theme") Theme
label(for="theme") #{translate("theme")}
select(
name="theme"
ng-model="settings.theme"
@ -108,7 +108,7 @@ aside#left-menu.full-size(
option(value=theme) #{theme.replace(/_/g, ' ')}
.form-controls(ng-show="!anonymous")
label(for="mode") Keybindings
label(for="mode") #{translate("keybindings")}
select(
name="mode"
ng-model="settings.mode"
@ -118,7 +118,7 @@ aside#left-menu.full-size(
option(value='emacs') Emacs
.form-controls
label(for="fontSize") Font Size
label(for="fontSize") #{translate("font_size")}
select(
name="fontSize"
ng-model="settings.fontSize"
@ -127,20 +127,20 @@ aside#left-menu.full-size(
option(value=size) #{size}px
.form-controls
label(for="pdfViewer") PDF Viewer
label(for="pdfViewer")
select(
name="pdfViewer"
ng-model="settings.pdfViewer"
)
option(value="pdfjs") Built-In
option(value="native") Native
option(value="pdfjs") #{translate("built_in")}
option(value="native") #{translate("native")}
h4 Hotkeys
h4 #{translate("hotkeys")}
ul.list-unstyled.nav
li(ng-controller="HotkeysController")
a(ng-click="openHotkeysModal()")
i.fa.fa-keyboard-o.fa-fw
| &nbsp;&nbsp; Show Hotkeys
| &nbsp;&nbsp; #{translate("show_hotkeys")}
#left-menu-mask(
ng-show="ui.leftMenuShown",
@ -150,11 +150,11 @@ aside#left-menu.full-size(
script(type='text/ng-template', id='cloneProjectModalTemplate')
.modal-header
h3 Copy Project
h3 #{translate("copy_project")}
.modal-body
form(name="cloneProjectForm", novalidate)
.form-group
label New Name
label #{translate("new_name")}
input.form-control(
type="text",
placeholder="New Project Name",
@ -167,10 +167,10 @@ script(type='text/ng-template', id='cloneProjectModalTemplate')
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="cloneProjectForm.$invalid || state.inflight"
ng-click="clone()"
)
span(ng-hide="state.inflight") Copy
span(ng-show="state.inflight") Copying...
span(ng-hide="state.inflight") #{translate("copy")}
span(ng-show="state.inflight") #{translate("copying")}...

View file

@ -9,8 +9,8 @@ div.full-size.pdf(ng-controller="PdfController")
ng-class="{'fa-spin': pdf.compiling }"
)
| &nbsp;&nbsp;
span(ng-show="!pdf.compiling") Recompile
span(ng-show="pdf.compiling") Compiling...
span(ng-show="!pdf.compiling") #{translate("recompile")}
span(ng-show="pdf.compiling") #{translate("compiling")}...
a.log-btn(
href
ng-click="toggleLogs()"
@ -76,29 +76,28 @@ div.full-size.pdf(ng-controller="PdfController")
.pdf-uncompiled(ng-show="pdf.uncompiled && !pdf.compiling")
| &nbsp;
i.fa.fa-level-up.fa-flip-horizontal.fa-2x
| &nbsp;&nbsp;Click here to preview your work as a PDF.
| &nbsp;&nbsp;#{translate("click_here_to_preview_pdf")}
.pdf-errors(ng-show="pdf.timedout || pdf.error")
.alert.alert-danger(ng-show="pdf.error")
strong Server Error.
span Sorry, something went wrong and your project could not be compiled. Please try again in a few moments.
strong #{translate("server_error")}
span #{translate("somthing_went_wrong_compiling")}
.alert.alert-danger(ng-show="pdf.timedout")
.alert.alert-danger(ng-show="pdf.timedout")
p
strong Your compile timed out.
| Sorry, your compile was taking too long and timed out.
| This may be due to a problem with your LaTeX code, or too many high-res images.
strong #{translate("timedout")}.
span #{translate("proj_timed_out_reason")}
p
a.text-info(href="https://www.sharelatex.com/learn/Debugging_Compilation_timeout_errors", target="_blank")
| Please see our help guide for more information.
| #{translate("please_see_help_for_more_info")}
.pdf-logs(ng-show="(pdf.view == 'logs' || pdf.failure) && !pdf.error && !pdf.timeout && !pdf.uncompiled")
.alert.alert-success(ng-show="pdf.logEntries.all.length == 0")
| No errors, good job!
| #{translate("no_errors_good_job")}
.alert.alert-danger(ng-show="pdf.failure")
strong Compile Error.
span Sorry, your LaTeX code couldn't compile for some reason. Please check the errors below for details, or view the raw log.
strong #{translate("compile_error")}.
span #{translate("generic_failed_compile_message")}.
div(ng-repeat="entry in pdf.logEntries.all", ng-controller="PdfLogEntryController")
.alert(
@ -131,7 +130,7 @@ div.full-size.pdf(ng-controller="PdfController")
href
dropdown-toggle
)
| Other logs &amp; files
| #{translate("other_logs_and_files")}
span.caret
ul.dropdown-menu.dropdown-menu-right
li(ng-repeat="file in pdf.outputFiles")
@ -141,26 +140,25 @@ div.full-size.pdf(ng-controller="PdfController")
ng-click="openOutputFile(file)"
) {{ file.name }}
a.btn.btn-info.btn-sm(href, ng-click="toggleRawLog()")
span(ng-show="!pdf.showRawLog") View Raw Logs
span(ng-show="pdf.showRawLog") Hide Raw Logs
span(ng-show="!pdf.showRawLog") #{translate("view_raw_logs")}
span(ng-show="pdf.showRawLog") #{translate("hide_raw_logs")}
pre(ng-bind="pdf.rawLog", ng-show="pdf.showRawLog")
script(type='text/ng-template', id='clearCacheModalTemplate')
.modal-header
h3 Clear cache?
h3 #{translate("clear_cache")}?
.modal-body
p This will clear all hidden LaTeX files (.aux, .bbl, etc) from our compile server.
| You generally don't need to do this unless you're having trouble with references.
p Your project files will not be deleted or changed.
p #{translate("clear_cache_explanation")}
p #{translate("clear_cache_is_safe")}
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
ng-disabled="state.inflight"
) Cancel
) #{translate("cancel")}
button.btn.btn-info(
ng-click="clear()"
ng-disabled="state.inflight"
)
span(ng-show="!state.inflight") Clear cache
span(ng-show="state.inflight") Clearing...
span(ng-show="!state.inflight") #{translate("clear_cache")}
span(ng-show="state.inflight") #{translate("clearing")}...

View file

@ -5,11 +5,11 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Publish as Template
h3 #{translate("publish_as_template")}
.modal-body.modal-body-share
span(ng-hide="problemTalkingToTemplateApi")
form()
label(for='Description') Template Description
label(for='Description') #{translate("template_description")}
.form-group
textarea.form-control(
rows=5,
@ -19,11 +19,11 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate")
value=""
)
div(ng-show="templateDetails.exists").text-center.templateDetails
| Your project was last published at
| #{translate("project_last_published_at")}
strong {{templateDetails.publishedDate}}.
a(ng-href="{{templateDetails.canonicalUrl}}") View it in template gallery.
a(ng-href="{{templateDetails.canonicalUrl}}") #{translate("view_in_template_gallery")}.
span(ng-show="problemTalkingToTemplateApi") There is a problem with our publishing service, please try again in a few minutes.
span(ng-show="problemTalkingToTemplateApi") #{translate("problem_talking_to_publishing_service")}.
@ -33,20 +33,20 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate")
ng-click="cancel()",
ng-disabled="state.publishInflight || state.unpublishInflight"
)
span Cancel
span #{translate("cancel")}
button.btn.btn-info(
ng-click="unpublishTemplate()",
ng-disabled="state.publishInflight || state.unpublishInflight"
ng-show="templateDetails.exists"
)
span(ng-show="!state.unpublishInflight") Unpublish
span(ng-show="state.unpublishInflight") Unpublishing...
span(ng-show="!state.unpublishInflight") #{translate("unpublish")}
span(ng-show="state.unpublishInflight") #{translate("unpublishing")}...
button.btn.btn-primary(
ng-click="publishTemplate()",
ng-disabled="state.publishInflight || state.unpublishInflight"
)
span(ng-show="!state.publishInflight && !templateDetails.exists") Publish
span(ng-show="!state.publishInflight && templateDetails.exists") Republish
span(ng-show="state.publishInflight") Publishing...
span(ng-show="!state.publishInflight && !templateDetails.exists") #{translate("publish")}
span(ng-show="!state.publishInflight && templateDetails.exists") #{translate("republish")}
span(ng-show="state.publishInflight") #{translate("publishing")}...

View file

@ -5,26 +5,26 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Share Project
h3 #{translate("share_project")}
.modal-body.modal-body-share
.container-fluid
.row.public-access-level(ng-show="project.publicAccesLevel == 'private'")
.col-xs-12.text-center
| This project is private and can only be accessed by the people below.
| #{translate("this_project_is_private")}
| &nbsp;&nbsp;
a(
href
ng-click="openMakePublicModal()"
) Make Public
) #{translate("make_public")}
.row.public-access-level(ng-show="project.publicAccesLevel != 'private'")
.col-xs-12.text-center
strong(ng-if="project.publicAccesLevel == 'readAndWrite'") This project is public and can be edited by anyone with the URL.
strong(ng-if="project.publicAccesLevel == 'readOnly'") This project is public and can be viewed by anyone with the URL.
strong(ng-if="project.publicAccesLevel == 'readAndWrite'") #{translate("this_project_is_public")}
strong(ng-if="project.publicAccesLevel == 'readOnly'") #{translate("this_project_is_public")}
| &nbsp;&nbsp;
a(
href
ng-click="openMakePrivateModal()"
) Make Private
) #{translate("make_private")}
.row.project-member
.col-xs-8 {{ project.owner.email }}
.text-right(
@ -33,8 +33,8 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
.row.project-member(ng-repeat="member in project.members")
.col-xs-8 {{ member.email }}
.col-xs-3.text-right
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
span(ng-show="member.privileges == 'readOnly'") Read Only
span(ng-show="member.privileges == 'readAndWrite'") #{translate("can_edit")}
span(ng-show="member.privileges == 'readOnly'") #{translate("read_only")}
.col-xs-1
a(
href
@ -45,7 +45,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
i.fa.fa-times
.row.invite-controls
form(ng-show="canAddCollaborators")
.small Share with your collaborators
.small #{translate("share_with_your_collabs")}
.form-group
input.form-control(
type="email"
@ -59,19 +59,19 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
ng-model="inputs.privileges"
name="privileges"
)
option(value="readAndWrite") Can Edit
option(value="readOnly") Read Only
option(value="readAndWrite") #{translate("can_edit")}
option(value="readOnly") #{translate("read_only")}
| &nbsp;&nbsp;
button.btn.btn-info(
type="submit"
ng-click="addMember()"
) Share
) #{translate("share")}
div.text-center(ng-hide="canAddCollaborators")
p You need to upgrade your account to add more collaborators.
p #{translate("need_to_upgrade_for_more_collabs")}.
p
a.btn.btn-info(href, ng-click="startFreeTrial('projectMembers')") Start Free Trial
a.btn.btn-info(href, ng-click="startFreeTrial('projectMembers')") #{translate("start_free_trial")}
p.small(ng-show="startedFreeTrial")
| Please refresh this page after starting your free trial.
| #{translate("refresh_page_after_starting_free_trial")}.
.modal-footer
.modal-footer-left
@ -79,7 +79,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
span.text-danger.error(ng-show="state.error") {{ state.error }}
button.btn.btn-primary(
ng-click="done()"
) Done
) #{translate("done")}
script(type="text/ng-template", id="makePublicModalTemplate")
.modal-header
@ -88,23 +88,23 @@ script(type="text/ng-template", id="makePublicModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Make project public?
h3 #{translate("make_project_public")}?
.modal-body.modal-body-share
p If you make your project public then anyone with the URL will be able to access it.
p #{translate("make_project_public_consequences")}
p
select.form-control(
ng-model="inputs.privileges"
name="privileges"
)
option(value="readAndWrite") Allow public editing
option(value="readOnly") Allow public read only access
option(value="readAndWrite") #{translate("allow_public_editing")}
option(value="readOnly") #{translate("allow_public_read_only")}
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-info(
ng-click="makePublic()"
) Make public
) #{translate("make_public")}
script(type="text/ng-template", id="makePrivateModalTemplate")
.modal-header
@ -113,13 +113,13 @@ script(type="text/ng-template", id="makePrivateModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Make project private?
h3 #{translate("make_project_private")}?
.modal-body.modal-body-share
p If you make your project private then only the people you choose to share it with will have access.
p #{translate("make_project_private_consequences")}
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-info(
ng-click="makePrivate()"
) Make private
) #{translate("make_private")}

View file

@ -1,15 +1,15 @@
div#trackChanges(ng-show="ui.view == 'track-changes'")
.upgrade-prompt(ng-show="!project.features.versioning")
.message(ng-show="project.owner._id == user.id")
p You need to upgrade your account to use the History feature.
p #{translate("need_to_upgrade_for_history")}
p
a.btn.btn-info(
href
ng-click="startFreeTrial('track-changes')"
) Start Free Trial
p.small(ng-show="startedFreeTrial") Please refresh the page after starting your free trial.
) #{translate("start_free_trial")}
p.small(ng-show="startedFreeTrial") #{translate("refresh_page_after_starting_free_trial")}
.message(ng-show="project.owner._id != user.id")
p Please ask the project owner to upgrade to use the History feature.
p #{translate("ask_proj_owner_to_upgrade_for_history")}
aside.change-list(
ng-controller="TrackChangesListController"
@ -73,11 +73,11 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
.name(ng-if="update_user.id == user.id") You
div.user(ng-if="update.meta.users.length == 0")
.color-square(style="background-color: hsl(100, 100%, 50%)")
span Anonymous
span #{translate("anonymous")}
.loading(ng-show="trackChanges.loading")
i.fa.fa-spin.fa-refresh
| &nbsp;&nbsp;Loading...
| &nbsp;&nbsp; #{translate("loading")}...
.diff-panel.full-size(ng-controller="TrackChangesDiffController")
.diff(
@ -98,7 +98,7 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
a.btn.btn-danger.btn-sm(
href,
ng-click="openRestoreDiffModal()"
) Restore to before these changes
) #{translate("restore_to_before_these_changes")}
.diff-editor.hide-ace-cursor(
ace-editor="track-changes",
theme="settings.theme",
@ -112,17 +112,18 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
.diff-deleted.text-centered(
ng-show="trackChanges.diff.deleted"
)
p.text-serif {{ trackChanges.diff.doc.name }} has been deleted.
p.text-serif #{translate("file_has_been_deleted", {filename:"{{ trackChanges.diff.doc.name }} "})}
p
a.btn.btn-primary.btn-lg(
href,
ng-click="restoreDeletedDoc()"
) Restore
) #{translate("restore")}
.loading-panel(ng-show="trackChanges.diff.loading")
i.fa.fa-spin.fa-refresh
| &nbsp;&nbsp;Loading...
| &nbsp;&nbsp;#{translate("loading")}...
.error-panel(ng-show="trackChanges.diff.error")
.alert.alert-danger Sorry, something went wrong :(
.alert.alert-danger #{translate("generic_something_went_wrong")}
script(type="text/ng-template", id="trackChangesRestoreDiffModalTemplate")
.modal-header
@ -131,17 +132,17 @@ script(type="text/ng-template", id="trackChangesRestoreDiffModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Restore {{diff.doc.name}}
h3 #{translate("restore")} {{diff.doc.name}}
.modal-body.modal-body-share
p Are you sure you want to restore <strong>{{diff.doc.name}}</strong> to before the changes on {{diff.start_ts | formatDate}}?
p #{translate("sure_you_want_to_restore_before", {filename:"<strong>{{diff.doc.name}}</strong>", date:"{{diff.start_ts | formatDate}}"})}
.modal-footer
button.btn.btn-default(
ng-click="cancel()",
ng-disabled="state.inflight"
) Cancel
) #{translate("cancel")}
button.btn.btn-danger(
ng-click="restore()",
ng-disabled="state.inflight"
)
span(ng-show="!state.inflight") Restore
span(ng-show="state.inflight") Restoring...
span(ng-show="!state.inflight") #{translate("restore")}
span(ng-show="state.inflight") #{translate("restoring")} ...

View file

@ -3,6 +3,9 @@ extends ../layout
block content
//- We need to do .replace(/\//g, '\\/') do that '</script>' -> '<\/script>'
//- and doesn't prematurely end the script tag.
script(type="text/javascript").
window.data = {
projects: !{JSON.stringify(projects).replace(/\//g, '\\/')},

View file

@ -5,7 +5,7 @@ script(type='text/ng-template', id='newTagModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Create New Folder
h3 #{translate("create_new_folder")}
.modal-body
form(name="newTagForm", novalidate)
input.form-control(
@ -23,12 +23,12 @@ script(type='text/ng-template', id='newTagModalTemplate')
button.btn.btn-default(
ng-click="cancel()"
stop-propagation="click"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="newTagForm.$invalid"
ng-click="create()"
stop-propagation="click"
) Create
) #{translate("create")}
script(type='text/ng-template', id='renameProjectModalTemplate')
.modal-header
@ -37,7 +37,7 @@ script(type='text/ng-template', id='renameProjectModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Rename Project
h3 #{translate("rename_project")}
.modal-body
form(name="renameProjectForm", novalidate)
input.form-control(
@ -49,11 +49,11 @@ script(type='text/ng-template', id='renameProjectModalTemplate')
focus-on="open"
)
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel
button.btn.btn-default(ng-click="cancel()") #{translate("cancel")}
button.btn.btn-primary(
ng-click="rename()",
ng-disabled="renameProjectForm.$invalid"
) Rename
) #{translate("rename")}
script(type='text/ng-template', id='cloneProjectModalTemplate')
.modal-header
@ -62,11 +62,11 @@ script(type='text/ng-template', id='cloneProjectModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Copy Project
h3 #{translate("copy_project")}
.modal-body
form(name="cloneProjectForm", novalidate)
.form-group
label New Name
label #{translate("new_name")}
input.form-control(
type="text",
placeholder="New Project Name",
@ -79,13 +79,13 @@ script(type='text/ng-template', id='cloneProjectModalTemplate')
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="cloneProjectForm.$invalid || state.inflight"
ng-click="clone()"
)
span(ng-hide="state.inflight") Copy
span(ng-show="state.inflight") Copying...
span(ng-hide="state.inflight") #{translate("copy")}
span(ng-show="state.inflight") #{translate("copying")} ...
script(type='text/ng-template', id='newProjectModalTemplate')
.modal-header
@ -94,7 +94,7 @@ script(type='text/ng-template', id='newProjectModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 New Project
h3 #{translate("new_project")}
.modal-body
form(novalidate, name="newProjectForm")
input.form-control(
@ -109,13 +109,13 @@ script(type='text/ng-template', id='newProjectModalTemplate')
button.btn.btn-default(
ng-disabled="state.inflight"
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-primary(
ng-disabled="newProjectForm.$invalid || state.inflight"
ng-click="create()"
)
span(ng-hide="state.inflight") Create
span(ng-show="state.inflight") Creating...
span(ng-hide="state.inflight") #{translate("create")}
span(ng-show="state.inflight") #{translate("creating")} ...
script(type='text/ng-template', id='deleteProjectsModalTemplate')
.modal-header
@ -124,22 +124,22 @@ script(type='text/ng-template', id='deleteProjectsModalTemplate')
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 {{action}} Projects
h3 {{action}} #{translate("projects")}
.modal-body
div(ng-show="projectsToDelete.length > 0")
p You are about to delete the following projects:
p #{translate("about_to_delete_projects")}
ul
li(ng-repeat="project in projectsToDelete | orderBy:'name'")
strong {{project.name}}
div(ng-show="projectsToLeave.length > 0")
p You are about to leave the following projects:
p #{translate("about_to_leave_projects")}
ul
li(ng-repeat="project in projectsToLeave | orderBy:'name'")
strong {{project.name}}
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-danger(
ng-click="delete()"
) {{action}}
@ -151,7 +151,7 @@ script(type="text/ng-template", id="uploadProjectModalTemplate")
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Upload Zipped Project
h3 #{translate("upload_zipped_project")}
.modal-body(
fine-upload
endpoint="/project/new/upload"
@ -163,9 +163,9 @@ script(type="text/ng-template", id="uploadProjectModalTemplate")
allowed-extensions="['zip']"
on-complete-callback="onComplete"
)
span Upload a zipped project
span #{translate("upload_a_zipped_project")}
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel
button.btn.btn-default(ng-click="cancel()") #{translate("cancel")}
script(type="text/ng-template", id="userProfileModalTemplate")
.modal-header
@ -174,12 +174,12 @@ script(type="text/ng-template", id="userProfileModalTemplate")
data-dismiss="modal"
ng-click="done()"
) &times;
h3 Your Profile
h3 #{translate("your_profile")}
.modal-body
form(enctype='multipart/form-data', method='post')
.form-group
label(for="first_name") First Name
label(for="first_name") #{translate("first_name")}
input.form-control(
type='text',
name='first_name',
@ -189,7 +189,7 @@ script(type="text/ng-template", id="userProfileModalTemplate")
)
.form-group
label(for="last_name") Last Name
label(for="last_name") #{translate("last_name")}
input.form-control(
type='text',
name='last_name',
@ -198,7 +198,7 @@ script(type="text/ng-template", id="userProfileModalTemplate")
)
.form-group.user_details_auto_complete
label(for="institution") Institution
label(for="institution") #{translate("institution")}
autocomplete(
ng-model="userInfoForm.institution",
name="institution",
@ -209,7 +209,7 @@ script(type="text/ng-template", id="userProfileModalTemplate")
)
.form-group.user_details_auto_complete
label(for="role") Role
label(for="role") #{translate("role")}
autocomplete(
ng-model="userInfoForm.role",
name="role",
@ -220,4 +220,4 @@ script(type="text/ng-template", id="userProfileModalTemplate")
.modal-footer
button.btn.btn-info(ng-click="done()") Done
button.btn.btn-info(ng-click="done()") #{translate("done")}

View file

@ -52,7 +52,7 @@
role="menu"
ng-controller="TagListController"
)
li.dropdown-header Add to folder
li.dropdown-header #{translate("add_to_folder")}
li(
ng-repeat="tag in tags | filter:nonEmpty | orderBy:'name'",
ng-controller="TagDropdownItemController"
@ -68,25 +68,25 @@
| {{tag.name}}
li.divider
li
a(href="#", ng-click="openNewTagModal()", stop-propagation="click") Create New Folder
a(href="#", ng-click="openNewTagModal()", stop-propagation="click") #{translate("create_new_folder")}
.btn-group(ng-hide="selectedProjects.length != 1").dropdown
a.btn.btn-default.dropdown-toggle(
href='#',
data-toggle="dropdown"
) More
) #{translate("more")}
span.caret
ul.dropdown-menu.dropdown-menu-right(role="menu")
li(ng-show="getFirstSelectedProject().accessLevel == 'owner'")
a(
href='#',
ng-click="openRenameProjectModal()"
) Rename
) #{translate("rename")}
li
a(
href='#',
ng-click="openCloneProjectModal()"
) Make a copy
) #{translate("make_copy")}
.btn-toolbar(ng-show="filter == 'archived'")
.btn-group(ng-hide="selectedProjects.length < 1")
@ -96,7 +96,7 @@
data-toggle="tooltip",
data-placement="bottom",
ng-click="restoreSelectedProjects()"
) Restore
) #{translate("restore")}
.btn-group(ng-hide="selectedProjects.length < 1")
a.btn.btn-danger(
@ -105,7 +105,7 @@
data-toggle="tooltip",
data-placement="bottom",
ng-click="openDeleteProjectsModal()"
) Delete Forever
) #{translate("delete_forever")}
.row.row-spaced
.col-xs-12
@ -123,13 +123,13 @@
select-all,
type="checkbox"
)
span.header.clickable(ng-click="changePredicate('name')") Title
span.header.clickable(ng-click="changePredicate('name')") #{translate("title")}
i.tablesort.fa(ng-class="getSortIconClass('name')")
.col-xs-2
span.header.clickable(ng-click="changePredicate('accessLevel')") Owner
span.header.clickable(ng-click="changePredicate('accessLevel')") #{translate("owner")}
i.tablesort.fa(ng-class="getSortIconClass('accessLevel')")
.col-xs-4
span.header.clickable(ng-click="changePredicate('lastUpdated')") Last Modified
span.header.clickable(ng-click="changePredicate('lastUpdated')") #{translate("last_modified")}
i.tablesort.fa(ng-class="getSortIconClass('lastUpdated')")
li.project_entry.container-fluid(
ng-repeat="project in visibleProjects | orderBy:predicate:reverse",
@ -162,13 +162,13 @@
)
.row
.col-xs-12.text-centered
small No projects
small #{translate("no_projects")}
div.welcome.text-centered(ng-if="projects.length == 0", ng-cloak)
h2 Welcome to ShareLaTeX!
p New to LaTeX? Start by having a look at our
a(href="/templates") templates
| or
a(href="/learn") help guides
h2 #{translate("welcome_to_sl")}
p #{translate("new_to_latex_look_at")}
a(href="/templates") #{translate("templates").toLowerCase()}
| #{translate("or")}
a(href="/learn") #{translate("latex_help_guide")}
| ,
br
| or create your first project on the left.
| #{translate("or_create_project_left")}

View file

@ -2,54 +2,56 @@
a.btn.btn-primary.dropdown-toggle(
href="#",
data-toggle="dropdown"
) New Project
)
| #{translate("new_project")}
ul.dropdown-menu(role="menu")
li
a(
href,
ng-click="openCreateProjectModal()"
) Blank Project
) #{translate("blank_project")}
li
a(
href,
ng-click="openCreateProjectModal('example')"
) Example Project
) #{translate("example_project")}
li
a(
href,
ng-click="openUploadProjectModal()"
) Upload Project
) #{translate("upload_project")}
li.divider
li.dropdown-header Templates
li.dropdown-header #{translate("templates")}
li
a.menu-indent(href="/templates/cv") CV or Resume
a.menu-indent(href="/templates/cv") #{translate("cv_or_resume")}
li
a.menu-indent(href="/templates/cover-letters") Cover Letter
a.menu-indent(href="/templates/cover-letters") #{translate("cover_letter")}
li
a.menu-indent(href="/templates/journals") Journal Article
a.menu-indent(href="/templates/journals") #{translate("journal_article")}
li
a.menu-indent(href="/templates/presentations") Presentation
a.menu-indent(href="/templates/presentations") #{translate("presentation")}
li
a.menu-indent(href="/templates/thesis") Thesis
a.menu-indent(href="/templates/thesis") #{translate("thesis")}
li
a.menu-indent(href="/templates/bibliographies") Bibliographies
a.menu-indent(href="/templates/bibliographies") #{translate("bibliographies")}
li
a.menu-indent(href="/templates") View All »
a.menu-indent(href="/templates") #{translate("view_all")} »
.row-spaced(ng-if="projects.length > 0", ng-cloak)
ul.list-unstyled.folders-menu(
ng-controller="TagListController"
)
li(ng-class="{active: (filter == 'all')}")
a(href, ng-click="filterProjects('all')") All projects
a(href, ng-click="filterProjects('all')") #{translate("all_projects")}
li(ng-class="{active: (filter == 'owned')}")
a(href, ng-click="filterProjects('owned')") Your projects
a(href, ng-click="filterProjects('owned')") #{translate("your_projects")}
li(ng-class="{active: (filter == 'shared')}")
a(href, ng-click="filterProjects('shared')") Shared with you
a(href, ng-click="filterProjects('shared')") #{translate("shared_with_you")}
li(ng-class="{active: (filter == 'archived')}")
a(href, ng-click="filterProjects('archived')") Deleted projects
a(href, ng-click="filterProjects('archived')") #{translate("deleted_projects")}
li
h2 Folders
h2 #{translate("folders")}
li(
ng-repeat="tag in tags | filter:nonEmpty",
ng-class="{active: tag.selected}",
@ -67,14 +69,14 @@
li(ng-cloak)
a.tag(href, ng-click="openNewTagModal()")
i.fa.fa-fw.fa-plus
span.name New Folder
span.name #{translate("new_folder")}
.row-spaced(ng-if="projects.length == 0", ng-cloak)
.first-project
div
i.fa.fa-arrow-up.fa-2x
div
strong Create your first project!
strong #{translate("create_your_first_project")}
- if (showUserDetailsArea)
.row-spaced#userProfileInformation(ng-if="projects.length > 0", ng-cloak)
@ -84,22 +86,19 @@
.progress
.progress-bar.progress-bar-info(ng-style="{'width' : (percentComplete+'%')}")
p.small
| Your profile is
strong {{percentComplete}}%
| complete
p.small #{translate("profile_complete_percentage_test", {percentval:"{{percentComplete}}"})}
button#completeUserProfileInformation.btn.btn-info(
ng-hide="formVisable",
ng-click="openUserProfileModal()"
) Complete
) #{translate("complete")}
-if (settings.enableSubscriptions && !hasSubscription)
.row-spaced(ng-if="projects.length > 0", ng-cloak).text-centered
hr
p.small You are using the free version of ShareLaTeX.
p.small #{translate("on_free_sl")}
p
a(href="/user/subscription/plans").btn.btn-primary Upgrade
a(href="/user/subscription/plans").btn.btn-primary #{translate("upgrade")}
p.small
| or unlock some free bonus features by
a(href="/user/bonus") sharing ShareLaTeX.
| #{translate("or_unlock_features_bonus")}
a(href="/user/bonus") #{translate("sharing_sl")} .

View file

@ -10,12 +10,12 @@ block content
.row
.col-md-12
.page-header
h1 Help us spread the word about ShareLaTeX.
h1 #{translate("help_us_spread_word")}.
.row
.col-md-10.col-md-offset-1
h2 Share ShareLaTeX with your friends and colleagues and unlock the rewards below
h2 #{translate("share_sl_to_get_rewards")}
.row
.col-md-8.col-md-offset-2.bonus-banner
@ -29,31 +29,31 @@ block content
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='#', onclick='postToFeed(); return false;').facebook Post on Facebook
a(href='#', onclick='postToFeed(); return false;').facebook #{translate("post_on_facebook")}
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl('gp'))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus Share us on Google+
a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl('gp'))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus #{translate("share_us_on_googleplus")}
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email Email us to your friends
a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email #{translate("email_us_to_your_friends")}
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='#link-modal', data-toggle="modal", ng-click="openLinkToUsModal()").link Link to us from your website
a(href='#link-modal', data-toggle="modal", ng-click="openLinkToUsModal()").link #{translate("link_to_us")}
.row
.col-md-10.col-md-offset-1.bonus-banner
h2.direct-link Direct Link
h2.direct-link #{translate("direct_link")}
pre.text-centered #{buildReferalUrl("d")}
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner
p.thanks When someone starts using ShareLaTeX after your recommendation we'll give you some <strong>free stuff</strong> to say thanks! Check your progress below.
p.thanks #{translate("sl_gives_you_free_stuff_see_progress_below")}
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 30px; margin-top: 20px;")
- for (var i = 0; i <= 10; i++) {
@ -67,24 +67,24 @@ block content
.col-md-10.col-md-offset-1.bonus-banner
.progress
- if (refered_user_count == 0)
div(style="text-align: center; padding: 4px;") Spread the word and fill this bar up
div(style="text-align: center; padding: 4px;") #{translate("spread_the_word_and_fill_bar")}
.progress-bar.progress-bar-info(style="width: #{refered_user_count}0%")
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 70px;")
.perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") One free collaborator
.perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") Three free collaborators
.perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") Free Dropbox and History
.perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") Free Professional account
.perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") #{translate("one_free_collab")}
.perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") #{translate("three_free_collab")}
.perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") #{translate("free_dropbox_and_history")}
.perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") #{translate("free_prof_account")}
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner
- if (refered_user_count == 0)
p.thanks You've not introduced anyone to ShareLaTeX yet. Get sharing!
p.thanks #{translate("you_not_introed_anyone_to_sl")}
- else if (refered_user_count == 1)
p.thanks You've introduced <strong>#{refered_user_count}</strong> person to ShareLaTeX. Good job, but can you get some more?
p.thanks #{translate("you_introed_small_number", {numberOfPeople:"<strong>#{refered_user_count}</strong>"})}
- else
p.thanks You've introduced <strong>#{refered_user_count}</strong> people to ShareLaTeX. Good job!
p.thanks #{translate("you_introed_high_number", {numberOfPeople:"<strong>#{refered_user_count}</strong>"})}
script(type="text/ng-template", id="BonusLinkToUsModal")
.modal-header
@ -93,22 +93,22 @@ block content
data-dismiss="modal"
ng-click="cancel()"
) &times;
h3 Link to ShareLaTeX
h3 #{translate("link_to_sl")}
.modal-body.modal-body-share.link-modal
p You can link to ShareLaTeX with the following HTML:
p #{translate("can_link_to_sl_with_html")}
p
textarea.col-md-12(readonly=true)
<a href="#{buildReferalUrl("d")}">Online LaTeX Editor ShareLaTeX</a>
p Thanks!
p #{translate("thanks")}!
.modal-footer()
button.btn.btn-default(
ng-click="cancel()",
)
span Close
span #{translate("close")}

View file

@ -9,14 +9,14 @@ mixin printPlan(plan)
strong #{plan.name}
td
-if (plan.annual)
| $#{plan.price / 100} / year
| $#{plan.price / 100} / #{translate("year")}
-else
| $#{plan.price / 100} / month
| $#{plan.price / 100} / #{translate("month")}
td
-if (subscription.state == "free-trial")
a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-success Subscribe to this plan
a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-success #{translate("subscribe_to_this_plan")}
-else if (plan.planCode == subscription.planCode)
button.btn.disabled Your plan
button.btn.disabled #{translate("your_plan")}
-else
form(action="/user/subscription/update",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
@ -34,44 +34,44 @@ block content
.col-md-8.col-md-offset-2
.card
.page-header
h1 Your Subscription
h1 #{translate("your_subscription")}
case subscription.state
when "free-trial"
p You are currently using a free trial which expires on <strong>#{subscription.expiresAt}</strong>.
p Choose a plan below to subscribe to.
p #{translate("on_free_trial_expiring_at", {expiresAt:"<strong>#{subscription.expiresAt}</strong>"})}
p #{translate("choose_a_plan_below")}
when "active"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
a(href, ng-click="changePlan = true") Change Plan.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>
p #{translate("currently_subscribed_to_plan", {planName:"<strong>#{subscription.name}</strong>"})}
a(href, ng-click="changePlan = true") #{translate("change_plan")}.
p #{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"<strong>#{subscription.price}</strong>", collectionDate:"<strong>#{subscription.nextPaymentDueAt}</strong>"})}
p.pull-right
p: form(action="/user/subscription/cancel",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
a(href="/user/subscription/billing-details/edit").btn.btn-info Update your billing details
a(href="/user/subscription/billing-details/edit").btn.btn-info #{translate("update_your_billing_details")}
| &nbsp;
input(type="submit", value="Cancel your subscription").btn.btn-primary#cancelSubscription
when "canceled"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
p Your subscription has been canceled and will terminate on <strong>#{subscription.nextPaymentDueAt}</strong>. No further payments will be taken.
p #{translate("currently_subscribed_to_plan", {planName:"<strong>#{subscription.name}</strong>"})}
p #{translate("subscription_canceled_and_terminate_on_x", {terminateDate:"<strong>#{subscription.nextPaymentDueAt}</strong>"})}
p: form(action="/user/subscription/reactivate",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
input(type="submit",value="Reactivate your subscription").btn.btn-success
when "expired"
p Your subscription has expired.
a(href="/user/subscription/plans") Create New Subscription
p #{translate("your_subscription_has_expired")}
a(href="/user/subscription/plans") #{translate("create_new_subscription")}
default
p There is a problem with your subscription. Please contact us for more information.
p #{translate("problem_with_subscription_contact_us")}
-if(subscription.groupPlan)
a(href="/subscription/group").btn.btn-success Manage Group
a(href="/subscription/group").btn.btn-success #{translate("manage_group")}
div(ng-show="changePlan", ng-cloak)
hr
h2 Change plan
h2 #{translate("change_plan")}
p: table.table
tr
th Name
th Price
th #{translate("name")}
th #{translate("price")}
th
mixin printPlans(plans.studentAccounts)
mixin printPlans(plans.individualMonthlyPlans)

View file

@ -11,8 +11,8 @@ block content
.col-md-6.col-md-offset-3
.card
.page-header
h1.text-centered Update Your Billing Details
#billingDetailsForm Loading billing details form...
h1.text-centered #{translate("update_your_billing_details")}
#billingDetailsForm #{translate("loading_billing_form")}...
script(type="text/javascript").

View file

@ -8,13 +8,13 @@ block content
.card(ng-controller="GroupMembersController")
.page-header
.pull-right(ng-cloak)
small(ng-show="selectedUsers.length == 0") You have added <strong>{{ users.length }}</strong> of <strong>{{ groupSize }}</strong> available members
small(ng-show="selectedUsers.length == 0") #{translate("you_have_added_x_of_group_size_y", {addedUsersSize:"<strong>{{ users.length }}</strong>", groupSize:"<strong>{{ groupSize }}</strong>"})}
a.btn.btn-danger(
href,
ng-show="selectedUsers.length > 0"
ng-click="removeMembers()"
) Remove from group
h1 Group Account
) #{translate("remove_from_group")}
h1 #{translate("group_account")}
.row-spaced-small
ul.list-unstyled.structured-list(
@ -28,11 +28,11 @@ block content
select-all,
type="checkbox"
)
span.header Email
span.header #{translate("email")}
.col-md-5
span.header Name
span.header #{translate("name")}
.col-md-2
span.header Registered
span.header #{translate("registered")}
li.container-fluid(
ng-repeat="user in users | orderBy:'email':true",
ng-controller="GroupMemberListItemController"
@ -57,12 +57,12 @@ block content
)
.row
.col-md-12.text-centered
small No members
small #{translate("no_members")}
div(ng-if="users.length < groupSize", ng-cloak)
hr
p
.small Add more members
.small #{translate("add_more_members")}
form.form
.row
.col-xs-6
@ -74,7 +74,7 @@ block content
on-enter="addMembers()"
)
.col-xs-6
button.btn.btn-primary(ng-click="addMembers()") Add
button.btn.btn-primary(ng-click="addMembers()") #{translate("add")}
script(type="text/javascript").
window.users = !{JSON.stringify(users)};

View file

@ -11,8 +11,8 @@ block content
.col-md-6.col-md-offset-3
.card
.page-header
h1.text-centered New Subscription
#subscribeForm Loading subscription form...
h1.text-centered #{translate("new_subscription")}
#subscribeForm #{translate("loading_billing_form")}...
script(type="text/javascript")
ga('send', 'event', 'pageview', 'payment_form', "#{plan_code}")

View file

@ -7,11 +7,11 @@ block content
.row
.col-md-12
.page-header.centered.plans-header.text-centered
h1 Start Your 30-Day Free Trial Today!
h1 #{translate("start_30_day_trial")}
.row
.col-md-8.col-md-offset-2
p.text-centered ShareLaTeX is the world's easiest to use LaTeX editor. Stay up to date with your collaborators, keep track of all changes to your work, and use our LaTeX environment from anywhere in the world.
p.text-centered #{translate("sl_benefits_plans")}
.row(ng-cloak)
.col-md-12
@ -20,55 +20,55 @@ block content
a(
href,
ng-click="switchToMonthly()"
) Monthly
) #{translate("monthly")}
li(ng-class="{'active': ui.view == 'annual'}")
a(
href
ng-click="switchToAnnual()"
) Annual
) #{translate("annual")}
li(ng-class="{'active': ui.view == 'student'}")
a(
href,
ng-click="switchToStudent()"
) Half Price Student Plans
) #{translate("half_price_student")}
.row(ng-cloak)
.col-md-12
.card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
.card
.card-header
h2 Personal
.circle Free
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li Only one collaborator
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(href="/register") Sign up now
a.btn.btn-info(href="/register") #{translate("sign_up_now")}
.card.highlighted
.card-header
h2 Collaborator
h2 #{translate("collaborator")}
.circle
span(ng-if="ui.view == 'monthly'")
| $15
span.small /mo
span(ng-if="ui.view == 'annual'")
| $180
span.small/yr
span.small /yr
ul.list-unstyled
li
strong 10 collaborators per project
li Full document history
li Sync to Dropbox
strong #{translate("collabs_per_proj", {collabcount:10})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '-annual' || ''}}_free_trial", ng-click="signUpNowClicked('collaborator')"
) Start Free Trial!
) #{translate("start_free_trial")}
.card
.card-header
h2 Professional
h2 #{translate("professional")}
.circle
span(ng-if="ui.view == 'monthly'")
| $30
@ -78,91 +78,91 @@ block content
span.small /yr
ul.list-unstyled
li
strong Unlimited collaborators
li Full document history
li Sync to Dropbox
strong #{translate("unlimited_collabs")}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || ''}}_free_trial", ng-click="signUpNowClicked('professional')"
) Start Free Trial!
) #{translate("start_free_trial")}
.card-group.text-centered(ng-if="ui.view == 'student'")
.card
.card-header
h2 Personal
.circle Free
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li Only one collaborator
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(href="/register") Sign up now
a.btn.btn-info(href="/register") #{translate("sign_up_now")}
.card.highlighted
.card-header
h2 Student
h2 #{translate("student")}
.circle
span
| $8
span.small /mo
ul.list-unstyled
li
strong 6 collaborators per project
li Full document history
li Sync to Dropbox
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=student_free_trial", ng-click="signUpNowClicked('student')"
) Start Free Trial!
) #{translate("start_free_trial")}
.card
.card-header
h2 Student (Annual)
h2 #{translate("student")} (#{translate("annual")})
.circle
span
| $80
span.small /yr
ul.list-unstyled
li
strong 6 collaborators per project
li Full document history
li Sync to Dropbox
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=stud-ann_free_trial", ng-click="signUpNowClicked('student')"
) Start Free Trial!
) #{translate("start_free_trial")}
.row(ng-cloak)
p.text-centered Choose the plan that works for you with our 30-day free trial. Cancel at any time.
p.text-centered #{translate("start_free_trial")} #{translate("choose_plan_works_for_you")}
.row(ng-cloak)
.col-md-8.col-md-offset-2
.alert.alert-info.text-centered
| Interested in using ShareLaTeX with a group, team or department wide account?
| #{translate("interested_in_group_licence")}
br
a(href, ng-click="openGroupPlanModal()") Get in touch for details!
a(href, ng-click="openGroupPlanModal()") #{translate("get_in_touch_for_details")}
script(type="text/ng-template", id="groupPlanModalTemplate")
.modal-header
h3 Group Plan Enquiry
h3 #{translate("group_plan_enquiry")}
.modal-body
form(name='form1', autocomplete='off', enctype='multipart/form-data', method='post', novalidate='', action='https://sharelatex.wufoo.com/forms/z7x3p3/#public', _lpchecked='1')
.form-group
label(for='Field9') Name
label(for='Field9') #{translate("name")}
input.form-control(name='Field9', type='text', value='', maxlength='255', tabindex='1', onkeyup='')
.form-group
label(for='Field11') Email
label(for='Field11') #{translate("email")}
input.form-control(name='Field11', type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
.form-group
label(for='Field12') University
label(for='Field12') #{translate("university")}
input.form-control(name='Field12', type='text', value='', maxlength='255', tabindex='3', onkeyup='')
.form-group
label(for='Field13') Position
label(for='Field13') #{translate("position")}
input.form-control(name='Field13', type='text', value='', maxlength='255', tabindex='4', onkeyup='')
.form-group
@ -176,19 +176,19 @@ block content
.row
.col-md-12
.page-header.plans-header.plans-subheader.text-centered
h2 Enjoy all of these great features
h2 #{translate("enjoy_these_features")}
.col-md-4
.card.features.text-centered
i.fa.fa-file-text-o.fa-5x
h4 Unlimited projects
p Create as many projects as you need.
h4 #{translate("unlimited_projects")}
p #{translate("create_unlimited_projects")}
.col-md-4
.card.features.text-centered
i.fa.fa-clock-o.fa-5x
h4 Full document history
p Never lose a step, we've got your back.
h4 #{translate("full_doc_history")}
p #{translate("never_loose_work")}
.col-md-4
.card.features.text-centered
i.fa.fa-dropbox.fa-5x
h4 Sync to Dropbox
p Access your projects everywhere.
h4 #{translate("sync_to_dropbox")}
p #{translate("access_projects_anywhere")}

View file

@ -7,23 +7,22 @@ block content
.col-md-8.col-md-offset-2
.card
.page-header
h2 Thanks for subscribing!
h2 #{translate("thanks_for_subscribing")}
.alert.alert-success
p Your card will be charged soon.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>.
p If you do not want to be charged again
a(href="/user/subscription") click here to cancel.
p #{translate("your_card_will_be_charged_soon")}
p #{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"<strong>#{subscription.price}</strong>", collectionDate:"<strong>#{subscription.nextPaymentDueAt}</strong>"})}
p #{translate("if_you_dont_want_to_be_charged")}
a(href="/user/subscription") #{translate("click_here_to_cancel")}.
p
- if (subscription.groupPlan == true)
a.btn.btn-success.btn-large(href="/subscription/group") Add your first group members now
a.btn.btn-success.btn-large(href="/subscription/group") #{translate("add_your_first_group_member_now")}
p.letter-from-founders
p Thank you for subscribing to the #{subscription.name} plan. It's support from people like yourself that allows ShareLaTeX to continue to grow and improve.
p If there is anything you ever need please feel free to contact us directly at
p #{translate("thanks_for_subscribing_you_help_sl", {planName:subscription.name})}
p #{translate("need_anything_contact_us_at")}
a(href='mailto:support@sharelatex.com') support@sharelatex.com
| . It goes straight to both our inboxes.
p Regards,
| . #{translate("goes_straight_to_our_inboxes")}.
p #{translate("regards")},
br
| Henry and James
.portraits
@ -33,4 +32,4 @@ block content
span.img-circle
img(src="/img/about/james_allen.jpg")
p
a.btn.btn-primary(href="/project") &lt; Back to your projects
a.btn.btn-primary(href="/project") &lt; #{translate("back_to_your_projects")}

View file

@ -7,7 +7,7 @@ block content
.col-md-2
h2
a(href="/templates") Templates
a(href="/templates") #{translate("templates")}
.col-md-8
form.project-search.form-horizontal(role="form")
.form-group.has-feedback.has-feedback-left.col-md-12

View file

@ -6,7 +6,7 @@ block content
.row
.page-header
h2
a(href="/templates") Templates
a(href="/templates") #{translate("templates")}
|
a(href=tag.tagPagePath) #{tag.name}
.row

View file

@ -6,7 +6,7 @@ block content
.row
.page-header
h2
a(href="/templates") Templates
a(href="/templates") #{translate("templates")}
|
- if(tag)
a(href=tag.tagPagePath) #{tag.name}
@ -22,7 +22,7 @@ block content
.col-md-6
.template-details-section
h3 About
h3 #{translate("about")}
div !{template.description}
div(ng-controller="openInSlController").download-buttons
a.btn.btn-primary.btn-large(href=template.open_in_sharelatex_url, ng-click='open()', ng-disabled="isDisabled", rel='nofollow') {{openInSlText}}
@ -47,7 +47,7 @@ block content
a.addthis_button_compact
script(type='text/javascript', src='//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-517c16586439faa7')
h3 Comment
h3 #{translate("comment")}
#disqus_thread
script(type='text/javascript').
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */

View file

@ -7,7 +7,7 @@ block content
.col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4
.card
.page-header
h1 Log In
h1 #{translate("log_in")}
form(async-form="login", name="loginForm", action='/login', ng-cloak)
input(name='_csrf', type='hidden', value=csrfToken)
input(name='redir', type='hidden', value=redir)
@ -23,7 +23,7 @@ block content
focus="true"
)
span.small.text-primary(ng-show="loginForm.email.$invalid && loginForm.email.$dirty")
| Must be an email address
| #{translate("must_be_email_address")}
.form-group
input.form-control(
type='password',
@ -33,12 +33,12 @@ block content
ng-model="password"
)
span.small.text-primary(ng-show="loginForm.password.$invalid && loginForm.password.$dirty")
| Required
| #{translate("required")}
.actions
button.btn-primary.btn(
type='submit',
ng-disabled="loginForm.inflight"
)
span(ng-show="!loginForm.inflight") Login
span(ng-show="loginForm.inflight") Logging in...
a.pull-right(href='/user/password/reset') Forgot your password?
span(ng-show="!loginForm.inflight") #{translate("login")}
span(ng-show="loginForm.inflight") #{translate("logging_in")}...
a.pull-right(href='/user/password/reset') #{translate("forgot_your_password")}?

View file

@ -7,7 +7,7 @@ block content
.col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4
.card
.page-header
h1 Password Reset
h1 #{translate("password_reset")}
.messageArea
form(
async-form="password-reset-request",
@ -18,9 +18,9 @@ block content
input(type="hidden", name="_csrf", value=csrfToken)
form-messages(for="passwordResetForm")
.alert.alert-success(ng-show="passwordResetForm.response.success")
| You have been sent an email to complete your password reset.
| #{translate("password_reset_email_sent")}
.form-group
label(for='email') Please enter your email address
label(for='email') #{translate("please_enter_email")}
input.form-control(
type='email',
name='email',
@ -31,9 +31,9 @@ block content
)
span.small.text-primary(
ng-show="passwordResetForm.email.$invalid && passwordResetForm.email.$dirty"
) Must be a valid email address
) #{translate("must_be_email_address")}
.actions
button.btn.btn-primary(
type='submit',
ng-disabled="passwordResetForm.$invalid"
) Request password reset
) #{translate("request_password_reset")}

View file

@ -6,24 +6,25 @@ block content
.row
.registration_message
if sharedProjectData.user_first_name !== undefined
h1 #{sharedProjectData.user_first_name} would like you to view '#{sharedProjectData.project_name}'
div Join ShareLaTeX to view this project
h1 #{translate("user_wants_you_to_see_project", {username:sharedProjectData.user_first_name, projectname:sharedProjectData.project_name})}
div #{translate("join_sl_to_view_project")}
else if newTemplateData.templateName !== undefined
h1 Please register to edit the '#{newTemplateData.templateName}' template
div Already have a ShareLaTeX account?
a(href="/login") Login here
h1 #{translate("register_to_edit_template", {templatename:newTemplateData.templateName})}
div #{translate("already_have_sl_account")}
a(href="/login") #{translate("login_here")}
.row
.col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4
.card
.page-header
h1 Register
h1 #{translate("register")}
form(async-form="register", name="registerForm", action="/register", ng-cloak)
input(name='_csrf', type='hidden', value=csrfToken)
input(name='redir', type='hidden', value=redir)
form-messages(for="registerForm")
.form-group
label(for='email') Email
label(for='email') #{translate("email")}
input.form-control(
type='email',
name='email',
@ -35,9 +36,9 @@ block content
focus="true"
)
span.small.text-primary(ng-show="registerForm.email.$invalid && registerForm.email.$dirty")
| Must be an email address
| #{translate("must_be_email_address")}
.form-group
label(for='password') Password
label(for='password') #{translate("password")}
input.form-control(
type='password',
name='password',
@ -46,11 +47,11 @@ block content
ng-model="password"
)
span.small.text-primary(ng-show="registerForm.password.$invalid && registerForm.password.$dirty")
| Required
| #{translate("required")}
.actions
button.btn-primary.btn(
type='submit'
ng-disabled="registerForm.inflight"
)
span(ng-show="!registerForm.inflight") Register
span(ng-show="registerForm.inflight") Registering...
span(ng-show="!registerForm.inflight") #{translate("register")}
span(ng-show="registerForm.inflight") #{translate("registering")}...

View file

@ -6,8 +6,8 @@ block content
.row
.col-md-8.col-md-offset-2.text-center
.page-header
h2 Restricted, sorry you don't have permission to load this page.
h2 #{translate("restricted_no_permission")}
p
a(href="/")
i.fa.fa-arrow-circle-o-left
| Take me home!
| #{translate("take_me_home")}

View file

@ -7,7 +7,7 @@ block content
.col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4
.card
.page-header
h1 Reset your password
h1 #{translate("reset_your_password")}
form(
async-form="password-reset",
name="passwordResetForm",
@ -17,8 +17,8 @@ block content
input(type="hidden", name="_csrf", value=csrfToken)
form-messages(for="passwordResetForm")
.alert.alert-success(ng-show="passwordResetForm.response.success")
| Your password has been reset.
a(href='/login') Login here
| #{translate("password_has_been_reset")}
a(href='/login') #{translate("login_here")}
.form-group
input.form-control(
@ -31,7 +31,7 @@ block content
)
span.small.text-primary(
ng-show="passwordResetForm.password.$invalid && passwordResetForm.password.$dirty"
) Required
) #{translate("required")}
input(
type="hidden",
name="passwordResetToken",
@ -41,4 +41,4 @@ block content
button.btn.btn-primary(
type='submit',
ng-disabled="passwordResetForm.$invalid"
) Set new password
) #{translate("set_new_password")}

View file

@ -7,20 +7,20 @@ block content
.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
.card
.page-header
h1 Account Settings
h1 #{translate("account_settings")}
.account-settings(ng-controller="AccountSettingsController", ng-cloak)
form-messages(for="settingsForm")
.alert.alert-success(ng-show="settingsForm.response.success")
| Thanks, your settings have been updated.
| #{translate("thanks_settings_updated")}
form-messages(for="changePasswordForm")
.container-fluid
.row
.col-md-5
h3 Update Account Info
h3 #{translate("update_account_info")}
form(async-form="settings", name="settingsForm", action="/user/settings", novalidate)
input(type="hidden", name="_csrf", value=csrfToken)
.form-group
label(for='email') Email
label(for='email') #{translate("email")}
input.form-control(
type='email',
name='email',
@ -31,16 +31,16 @@ block content
ng-model-options="{ updateOn: 'blur' }"
)
span.small.text-primary(ng-show="settingsForm.email.$invalid && settingsForm.email.$dirty")
| Must be an email address
| #{translate("must_be_email_address")}
.form-group
label(for='firstName').control-label First Name
label(for='firstName').control-label #{translate("first_name")}
input.form-control(
type='text',
name='first_name',
value=user.first_name
)
.form-group
label(for='lastName').control-label Last Name
label(for='lastName').control-label #{translate("last_name")}
input.form-control(
type='text',
name='last_name',
@ -50,14 +50,14 @@ block content
button.btn.btn-primary(
type='submit',
ng-disabled="settingsForm.$invalid"
) Update
) #{translate("update")}
.col-md-5.col-md-offset-1
h3 Change Password
h3 #{translate("change_password")}
form(async-form="changepassword", name="changePasswordForm", action="/user/password/update", novalidate)
input(type="hidden", name="_csrf", value=csrfToken)
.form-group
label(for='currentPassword') Current Password
label(for='currentPassword') #{translate("current_password")}
input.form-control(
type='password',
name='currentPassword',
@ -66,9 +66,9 @@ block content
required
)
span.small.text-primary(ng-show="changePasswordForm.currentPassword.$invalid && changePasswordForm.currentPassword.$dirty")
| Required
| #{translate("required")}
.form-group
label(for='newPassword1') New Password
label(for='newPassword1') #{translate("new_password")}
input.form-control(
id='newPassword1',
type='password',
@ -78,9 +78,9 @@ block content
required
)
span.small.text-primary(ng-show="changePasswordForm.newPassword1.$invalid && changePasswordForm.newPassword1.$dirty")
| Required
| #{translate("required")}
.form-group
label(for='newPassword2') Confirm New Password
label(for='newPassword2') #{translate("confirm_new_password")}
input.form-control(
type='password',
name='newPassword2',
@ -89,60 +89,57 @@ block content
equals="newPassword1"
)
span.small.text-primary(ng-show="changePasswordForm.newPassword2.$invalid && changePasswordForm.newPassword2.$dirty")
| Doesn't match
| #{translate("doesnt_match")}
.actions
button.btn.btn-primary(
type='submit',
ng-disabled="changePasswordForm.$invalid"
) Change
) #{translate("change")}
hr.soften
h3 Dropbox Integration
h3 #{translate("dropbox_integration")}
span.small
a(href='/help/kb/dropbox-2') (Learn more)
a(href='/help/kb/dropbox-2') (#{translate("learn_more")})
- if(!userHasDropboxFeature)
.alert.alert-info Dropbox sync is a premium feature &nbsp; &nbsp;
a.btn.btn-info(href='/user/subscription/plans') Upgrade
.alert.alert-info #{translate("dropbox_is_premium")} &nbsp; &nbsp;
a.btn.btn-info(href='/user/subscription/plans') #{translate("upgrade")}
- else if(userIsRegisteredWithDropbox)
.alert.alert-success Account is linked!
.alert.alert-success #{translate("account_is_linked")}
row
a(href='/dropbox/unlink').btn Unlink Dropbox
a(href='/dropbox/unlink').btn #{translate("unlink_dropbox")}
- else
a.btn.btn-info(href='/dropbox/beginAuth') Link to dropbox
a.btn.btn-info(href='/dropbox/beginAuth') #{translate("link_to_dropbox")}
hr.soften
p.small
| Every few months we send a newsletter out summarizing the new features available.
| If you would prefer not to receive this email then you can unsubscribe at any time:
| #{translate("newsletter_info_and_unsubscribe")}
a(
href,
ng-click="unsubscribe()",
ng-show="subscribed && !unsubscribing"
) Unsubscribe
) #{translate("unsubscribe")}
span(
ng-show="unsubscribing"
)
i.fa.fa-spin.fa-refresh
| Unsubscribing
i.fa.fa-spin.fa-refresh
| #{translate("unsubscribing")}
span.text-success(
ng-show="!subscribed"
)
i.fa.fa-check
| Unsubscribed
| #{translate("unsubscribed")}
p Need to leave?
a(href, ng-click="deleteAccount()") Delete your account
p #{translate("need_to_leave")}
a(href, ng-click="deleteAccount()") #{translate("delete_your_account")}
script(type='text/ng-template', id='deleteAccountModalTemplate')
.modal-header
h3 Delete Account
h3 #{translate("delete_account")}
.modal-body
p
| You are about to permanently <strong>delete all of your account data</strong>, including your projects
| and settings. Please type DELETE into the box below to proceed.
p !{translate("delete_account_warning_message")}
form(novalidate, name="deleteAccountForm")
input.form-control(
type="text",
@ -154,11 +151,11 @@ block content
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
) Cancel
) #{translate("cancel")}
button.btn.btn-danger(
ng-disabled="!state.isValid || state.inflight"
ng-click="delete()"
)
span(ng-hide="state.inflight") Delete
span(ng-show="state.inflight") Deleting...
span(ng-hide="state.inflight") #{translate("delete")}
span(ng-show="state.inflight") #{translate("deleting")}...

View file

@ -107,6 +107,11 @@ module.exports =
# that are sent out, generated links, etc.
siteUrl : 'http://localhost:3000'
# cooke domain
# use full domain for cookies to only be accesabble from that domain,
# replace subdomain with dot to have them accessable on all subdomains
# cookieDomain: ".sharelatex.dev"
# Same, but with http auth credentials.
httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000'
@ -134,6 +139,13 @@ module.exports =
features: defaultFeatures
}]
# i18n
# ------
#
i18n:
defaultLng:"en-US"
# Spelling languages
# ------------------
#

View file

@ -18,6 +18,5 @@ define [
"directives/selectAll"
"directives/maxHeight"
"filters/formatDate"
], () ->
angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -1,7 +1,9 @@
define [
"base"
], (App) ->
App.factory "queuedHttp", ["$http", "$q", ($http, $q) ->
App.factory "queuedHttp", ($http, $q) ->
pendingRequests = []
inflight = false
@ -48,8 +50,6 @@ define [
return queuedHttp
]
App.controller "ProjectPageController", ($scope, $modal, $q, $window, queuedHttp, event_tracking, $timeout) ->
$scope.projects = window.data.projects
$scope.tags = window.data.tags

View file

@ -96,10 +96,11 @@ describe "AuthenticationController", ->
@AuthenticationController.login(@req, @res)
it "should return an error", ->
expect(@res.body).to.deep.equal
message:
text: 'Your email or password were incorrect. Please try again',
type: 'error'
# @res.body.should.exist
expect(@res.body.message).to.exist
# message:
# text: 'Your email or password were incorrect. Please try again',
# type: 'error'
it "should not establish a session", ->
@AuthenticationController._establishUserSession.called.should.equal false

View file

@ -30,6 +30,8 @@ describe "PasswordResetController", ->
email:@email
passwordResetToken:@token
password:@password
i18n:
translate:->
@res = {}

View file

@ -78,7 +78,6 @@ describe "Subscription controller sanboxed", ->
it "should set the correct variables for the template", ->
should.exist @res.renderedVariables.signature
@res.renderedVariables.title.should.equal "Update Billing Details"
@res.renderedVariables.successURL.should.equal "#{Settings.siteUrl}/user/subscription/update"
@res.renderedVariables.user.id.should.equal @user.id
@ -137,9 +136,6 @@ describe "Subscription controller sanboxed", ->
@res.callback = done
@SubscriptionController.successful_subscription @req, @res
it "should render the thank you page", ->
@res.renderedVariables.title.should.equal "Thank you!"
describe "userSubscriptionPage", ->
describe "with a user without a subscription", ->
beforeEach (done) ->
@ -164,7 +160,6 @@ describe "Subscription controller sanboxed", ->
done()
it "should set the correct subscription details", ->
@res.renderedVariables.title.should.equal "Your Subscription"
@res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription
describe "with a user with a free trial", ->
@ -175,11 +170,9 @@ describe "Subscription controller sanboxed", ->
@SubscriptionController.userSubscriptionPage @req, @res
it "should render the dashboard", ->
@res.rendered.should.equal true
@res.renderedTemplate.should.equal "subscriptions/dashboard"
it "should set the correct subscription details", ->
@res.renderedVariables.title.should.equal "Your Subscription"
@res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription
describe "createSubscription", ->

View file

@ -5,6 +5,8 @@ class MockRequest
params: {}
query: {}
i18n:
translate:->
module.exports = MockRequest