Przeglądaj źródła

Merge branch 'master' into sk-linked-files-from-project

Shane Kilkelly 8 lat temu
rodzic
commit
0cb5beb689

+ 1 - 1
services/web/app/coffee/Features/Project/ProjectController.coffee

@@ -222,7 +222,7 @@ module.exports = ProjectController =
 					else
 						viewModel.showUserDetailsArea = false
 
-					paidUser = user.features?.github # use a heuristic for paid account
+					paidUser = user.features?.github and user.features?.dropbox # use a heuristic for paid account
 					freeUserProportion = 0.10
 					sampleFreeUser = parseInt(user._id.toString().slice(-2), 16) < freeUserProportion * 255
 					showFrontWidget = paidUser or sampleFreeUser

+ 2 - 1
services/web/app/views/layout.pug

@@ -98,7 +98,8 @@ html(itemscope, itemtype='http://schema.org/Product')
 
 		- if (settings.overleaf && settings.overleaf.useOLFreeTrial)
 			script.
-				window.redirectToOLFreeTrialUrl = '!{settings.overleaf.host}/users/trial'
+				window.useV2TrialUrl = true
+
 
 	body
 		if(settings.recaptcha)

Plik diff jest za duży
+ 293 - 339
services/web/npm-shrinkwrap.json


+ 7 - 0
services/web/package.json

@@ -27,6 +27,7 @@
   "dependencies": {
     "archiver": "0.9.0",
     "async": "0.6.2",
+    "backbone": "^1.3.3",
     "base64-stream": "^0.1.2",
     "basic-auth-connect": "^1.0.0",
     "bcrypt": "1.0.1",
@@ -37,16 +38,20 @@
     "cookie": "^0.2.3",
     "cookie-parser": "1.3.5",
     "csurf": "^1.8.3",
+    "d3": "^3.5.16",
     "dateformat": "1.0.4-1.2.3",
+    "daterangepicker": "^2.1.27",
     "express": "4.13.0",
     "express-http-proxy": "^1.1.0",
     "express-session": "^1.14.2",
     "fs-extra": "^4.0.2",
     "fuse.js": "^3.0.0",
+    "handlebars": "^4.0.11",
     "heapdump": "^0.3.7",
     "helmet": "^3.8.1",
     "http-proxy": "^1.8.1",
     "jade": "~1.3.1",
+    "jquery": "^1.11.1",
     "jsonwebtoken": "^8.0.1",
     "ldapjs": "^0.7.1",
     "lodash": "^4.13.1",
@@ -65,6 +70,7 @@
     "nodemailer-mandrill-transport": "^1.2.0",
     "nodemailer-sendgrid-transport": "^0.2.0",
     "nodemailer-ses-transport": "^1.3.0",
+    "nvd3": "^1.8.6",
     "optimist": "0.6.1",
     "passport": "^0.3.2",
     "passport-ldapauth": "^0.6.0",
@@ -134,6 +140,7 @@
     "grunt-postcss": "^0.8.0",
     "grunt-sed": "^0.1.1",
     "grunt-shell": "^2.1.0",
+    "handlebars-loader": "^1.7.0",
     "karma": "^2.0.0",
     "karma-chai-sinon": "^0.1.5",
     "karma-chrome-launcher": "^2.2.0",

+ 2 - 2
services/web/public/coffee/main/account-upgrade.coffee

@@ -11,8 +11,8 @@ define [
 			w = window.open()
 			go = () ->
 				ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source)
-				if window.redirectToOLFreeTrialUrl?
-					url = window.redirectToOLFreeTrialUrl
+				if window.useV2TrialUrl
+					url = "/user/trial"
 				else
 					url = "/user/subscription/new?planCode=#{plan}&ssp=true"
 					if couponCode?

+ 0 - 28
services/web/public/coffee/main/learn.coffee

@@ -55,32 +55,4 @@ define [
 					hits = _.map response.hits, buildHitViewModel
 					updateHits hits
 
-		$scope.showMissingTemplateModal = () ->
-			modalInstance = $modal.open(
-				templateUrl: "missingWikiPageModal"
-				controller: "MissingWikiPageController"
-			)
 
-
-	App.controller 'MissingWikiPageController', ($scope, $modalInstance) ->
-		$scope.form = {}
-		$scope.sent = false
-		$scope.sending = false
-		$scope.contactUs = ->
-			if !$scope.form.message?
-				console.log "message not set"
-				return
-			$scope.sending = true
-			ticketNumber = Math.floor((1 + Math.random()) * 0x10000).toString(32)
-			params =
-				email: $scope.form.email or "support@sharelatex.com"
-				message: $scope.form.message or ""
-				subject: "new wiki page sujection - [#{ticketNumber}]"
-				labels: "support wiki"
-
-			Groove.createTicket params, (err, json)->
-				$scope.sent = true
-				$scope.$apply()
-
-		$scope.close = () ->
-			$modalInstance.close()

+ 2 - 0
services/web/public/stylesheets/_style_includes.less

@@ -47,6 +47,7 @@
 @import "components/tooltip.less";
 @import "components/popovers.less";
 @import "components/carousel.less";
+@import "components/daterange-picker";
 
 // ngTagsInput
 @import "components/tags-input.less";
@@ -79,6 +80,7 @@
 @import "app/review-features-page.less";
 @import "app/error-pages.less";
 @import "app/v1-badge.less";
+@import "app/metrics.less";
 
 // Vendor CSS
 @import	"../js/libs/pdfListView/TextLayer.css";

+ 20 - 7
services/web/public/stylesheets/app/editor.less

@@ -201,13 +201,9 @@
 	}
 }
 
-.cm-editor-wrapper {
-	height: 100%;
-
-	.CodeMirror {
-		height: 100%;
-	}
-}
+/**************************************
+Ace
+***************************************/
 
 // The internal components of the aceEditor directive
 .ace-editor-wrapper {
@@ -282,6 +278,23 @@
 	}
 }
 
+/**************************************
+CodeMirror
+***************************************/
+.cm-editor-wrapper {
+	position: relative;
+	height: 100%;
+}
+
+.cm-editor-body {
+	height: 100%;
+}
+
+// CM (for some reason) has height set to 300px in it's stylesheet
+.CodeMirror {
+	height: 100%;
+}
+
 .ui-layout-resizer when (@is-overleaf = false) {
 	width: 6px;
 	background-color: @editor-resizer-bg-color;

+ 6 - 0
services/web/public/stylesheets/app/editor/review-panel.less

@@ -775,6 +775,12 @@
 	}
 }
 
+#editor-rich-text {
+	.rp-size-expanded & {
+		right: @review-panel-width;
+	}
+}
+
 .rp-toggle {
 	display: inline-block;
 	vertical-align: middle;

+ 177 - 0
services/web/public/stylesheets/app/metrics.less

@@ -0,0 +1,177 @@
+#metrics {
+  max-width: none;
+  padding: 0 30px;
+  width: auto;
+
+  svg.nvd3-svg {
+    width: 100%;
+  }
+
+  .overbox {
+    margin: 0;
+    padding: 40px 20px;
+    background: #fff;
+    border: 1px solid #DFDFDF;
+    .box {
+      padding-bottom: 30px;
+      overflow: hidden;
+      margin-bottom: 40px;
+      border-bottom: 1px solid rgb(216, 216, 216);
+
+      .header {
+        margin-bottom: 20px;
+
+        h4 {
+          font-size: 19px;
+          margin: 0;
+        }
+      }
+    }
+  }
+
+  .print-button {
+    margin-right: 10px;
+    font-size: 20px;
+  }
+
+  .title-button {
+    margin-right: 5px;
+    font-size: 20px;
+  }
+
+  .metric-col {
+    padding: 15px;
+  }
+
+  .metric-header-container {
+    h4 {
+      margin-bottom: 0;
+    }
+  }
+
+  svg {
+    display: block;
+    height: 250px;
+    text {
+      font-family: "Open Sans", sans-serif;
+    }
+    &:not(:root) {
+      overflow: visible
+    }
+
+    &.hidden-legend-margin-fix {
+      margin-top: 15px;
+      height: 235px;
+    }
+
+    &.no-fill-opacity {
+      .nvd3 {
+        .nv-area {
+          fill-opacity: 1;
+        }
+      }
+    }
+  }
+
+  .nvtooltip {
+    z-index: 10;
+  }
+
+  .tooltip {
+    width: 150px;
+  }
+
+  // BEGIN: Metrics header
+  .metric-header-container {
+    > h4 {
+      margin-top: 0;
+      margin-bottom: 0;
+    }
+  }
+  // END: Metrics header
+
+  // BEGIN: Metrics footer
+  .metric-footer-container {
+    text-align: center;
+  }
+  // END: Metrics footer
+
+  // BEGIN: Metrics overlays
+  .metric-overlay-loading,
+  .metric-overlay-error,
+  .metric-overlay-backdrop {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    padding: 16px; /* 15px of .metric-col padding + 1px border */
+    padding-top: 56px; /* Same as above + 30px for title + 10px overbox padding*/
+  }
+
+  .metric-overlay-loading {
+    padding: 175px 20%;
+  }
+
+  .metric-overlay-error {
+    display: none;
+    text-align: center;
+    padding-top: 175px;
+  }
+
+  .metric-overlay-backdrop {
+    opacity: 0.5;
+  }
+
+  .metric-overlay-backdrop-inner {
+    background-color: #fff;
+    width: 100%;
+    height: 100%;
+  }
+  // END: Metrics overlays
+}
+
+#metrics-header {
+  @media (min-width: 1200px) {
+    margin-bottom: 30px;
+  }
+
+  .section_header {
+    margin-bottom: 0;
+  }
+
+  #filters-container {
+    text-align: right;
+
+    .by {
+      color: #989898;
+      font-style: italic;
+    }
+  }
+
+  #lags-container {
+    .dropdown-menu {
+      min-width: 0;
+    }
+  }
+
+  #dates-container {
+    display: inline-block;
+    .daterangepicker {
+      margin-right: 15px;
+    }
+  }
+}
+
+#metrics-footer {
+  margin-top: 30px;
+  text-align: center;
+}
+
+body.print-loading {
+  #metrics {
+    .metric-col {
+      opacity: 0.5;
+    }
+  }
+}

+ 610 - 0
services/web/public/stylesheets/components/daterange-picker.less

@@ -0,0 +1,610 @@
+//
+// A stylesheet for use with Bootstrap 3.x
+// @author: Dan Grossman http://www.dangrossman.info/
+// @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved.
+// @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
+// @website: https://www.improvely.com/
+//
+
+//
+// VARIABLES
+//
+
+//
+// Settings
+
+// The class name to contain everything within.
+@arrow-size:     7px;
+
+//
+// Colors
+@daterangepicker-color:                      @brand-primary;
+@daterangepicker-bg-color:                   #fff;
+
+@daterangepicker-cell-color:                 @daterangepicker-color;
+@daterangepicker-cell-border-color:          transparent;
+@daterangepicker-cell-bg-color:              @daterangepicker-bg-color;
+
+@daterangepicker-cell-hover-color:           @daterangepicker-color;
+@daterangepicker-cell-hover-border-color:    @daterangepicker-cell-border-color;
+@daterangepicker-cell-hover-bg-color:        #eee;
+
+@daterangepicker-in-range-color:             #000;
+@daterangepicker-in-range-border-color:      transparent;
+@daterangepicker-in-range-bg-color:          #ebf4f8;
+
+@daterangepicker-active-color:               #fff;
+@daterangepicker-active-bg-color:            #a93529;
+@daterangepicker-active-border-color:        transparent;
+
+@daterangepicker-unselected-color:           #999;
+@daterangepicker-unselected-border-color:    transparent;
+@daterangepicker-unselected-bg-color:        #fff;
+
+//
+// daterangepicker
+@daterangepicker-width:          278px;
+@daterangepicker-padding:        4px;
+@daterangepicker-z-index:        3000;
+
+@daterangepicker-border-size:    1px;
+@daterangepicker-border-color:   #ccc;
+@daterangepicker-border-radius:  4px;
+
+
+//
+// Calendar
+@daterangepicker-calendar-margin:              @daterangepicker-padding;
+@daterangepicker-calendar-bg-color:            @daterangepicker-bg-color;
+
+@daterangepicker-calendar-border-size:         1px;
+@daterangepicker-calendar-border-color:        @daterangepicker-bg-color;
+@daterangepicker-calendar-border-radius:       @daterangepicker-border-radius;
+
+//
+// Calendar Cells
+@daterangepicker-cell-size:           20px;
+@daterangepicker-cell-width:          @daterangepicker-cell-size;
+@daterangepicker-cell-height:         @daterangepicker-cell-size;
+
+@daterangepicker-cell-border-radius:  @daterangepicker-calendar-border-radius;
+@daterangepicker-cell-border-size:    1px;
+
+//
+// Dropdowns
+@daterangepicker-dropdown-z-index: @daterangepicker-z-index + 1;
+
+//
+// Controls
+@daterangepicker-control-height:               30px;
+@daterangepicker-control-line-height:          @daterangepicker-control-height;
+@daterangepicker-control-color:                #555;
+
+@daterangepicker-control-border-size:          1px;
+@daterangepicker-control-border-color:         #ccc;
+@daterangepicker-control-border-radius:        4px;
+
+@daterangepicker-control-active-border-size:   1px;
+@daterangepicker-control-active-border-color:  @brand-primary;
+@daterangepicker-control-active-border-radius: @daterangepicker-control-border-radius;
+
+@daterangepicker-control-disabled-color:       #ccc;
+
+//
+// Ranges
+@daterangepicker-ranges-color:                @brand-primary;
+@daterangepicker-ranges-bg-color:             daterangepicker-ranges-color;
+
+@daterangepicker-ranges-border-size:          1px;
+@daterangepicker-ranges-border-color:         @daterangepicker-ranges-bg-color;
+@daterangepicker-ranges-border-radius:        @daterangepicker-border-radius;
+
+@daterangepicker-ranges-hover-color:          #fff;
+@daterangepicker-ranges-hover-bg-color:       @daterangepicker-ranges-color;
+@daterangepicker-ranges-hover-border-size:    @daterangepicker-ranges-border-size;
+@daterangepicker-ranges-hover-border-color:   @daterangepicker-ranges-hover-bg-color;
+@daterangepicker-ranges-hover-border-radius:  @daterangepicker-border-radius;
+
+@daterangepicker-ranges-active-border-size:   @daterangepicker-ranges-border-size;
+@daterangepicker-ranges-active-border-color:  @daterangepicker-ranges-bg-color;
+@daterangepicker-ranges-active-border-radius: @daterangepicker-border-radius;
+
+//
+// STYLESHEETS
+//
+.daterangepicker {
+  position: absolute;
+  color: @daterangepicker-color;
+  background-color: @daterangepicker-bg-color;
+  border-radius: @daterangepicker-border-radius;
+  width: @daterangepicker-width;
+  padding: @daterangepicker-padding;
+  margin-top: @daterangepicker-border-size;
+
+  // TODO: Should these be parameterized??
+  // top: 100px;
+  // left: 20px;
+
+  @arrow-prefix-size: @arrow-size;
+  @arrow-suffix-size: (@arrow-size - @daterangepicker-border-size);
+
+  &:before, &:after {
+    position: absolute;
+    display: inline-block;
+
+    border-bottom-color: rgba(0, 0, 0, 0.2);
+    content: '';
+  }
+
+  &:before {
+    top: -@arrow-prefix-size;
+
+    border-right: @arrow-prefix-size solid transparent;
+    border-left: @arrow-prefix-size solid transparent;
+    border-bottom: @arrow-prefix-size solid @daterangepicker-border-color;
+  }
+
+  &:after {
+    top: -@arrow-suffix-size;
+
+    border-right: @arrow-suffix-size solid transparent;
+    border-bottom: @arrow-suffix-size solid @daterangepicker-bg-color;
+    border-left: @arrow-suffix-size solid transparent;
+  }
+
+  &.opensleft {
+    &:before {
+      // TODO: Make this relative to prefix size.
+      right: @arrow-prefix-size + 2px;
+    }
+
+    &:after {
+      // TODO: Make this relative to suffix size.
+      right: @arrow-suffix-size + 4px;
+    }
+  }
+
+  &.openscenter {
+    &:before {
+      left: 0;
+      right: 0;
+      width: 0;
+      margin-left: auto;
+      margin-right: auto;
+    }
+
+    &:after {
+      left: 0;
+      right: 0;
+      width: 0;
+      margin-left: auto;
+      margin-right: auto;
+    }
+  }
+
+  &.opensright {
+    &:before {
+      // TODO: Make this relative to prefix size.
+      left: @arrow-prefix-size + 2px;
+    }
+
+    &:after {
+      // TODO: Make this relative to suffix size.
+      left: @arrow-suffix-size + 4px;
+    }
+  }
+
+  &.dropup {
+    margin-top: -5px;
+
+    // NOTE: Note sure why these are special-cased.
+    &:before {
+      top: initial;
+      bottom: -@arrow-prefix-size;
+      border-bottom: initial;
+      border-top: @arrow-prefix-size solid @daterangepicker-border-color;
+    }
+
+    &:after {
+      top: initial;
+      bottom:-@arrow-suffix-size;
+      border-bottom: initial;
+      border-top: @arrow-suffix-size solid @daterangepicker-bg-color;
+    }
+  }
+
+  &.dropdown-menu {
+    max-width: none;
+    z-index: @daterangepicker-dropdown-z-index;
+  }
+
+  &.single {
+    .ranges, .calendar {
+      float: none;
+    }
+  }
+
+  /* Calendars */
+  &.show-calendar {
+    .calendar {
+      display: block;
+    }
+  }
+
+  .calendar {
+    display: none;
+    max-width: @daterangepicker-width - (@daterangepicker-calendar-margin * 2);
+    margin: @daterangepicker-calendar-margin;
+
+    &.single {
+      .calendar-table {
+        border: none;
+      }
+    }
+
+    th, td {
+      white-space: nowrap;
+      text-align: center;
+
+      // TODO: Should this actually be hard-coded?
+      min-width: 32px;
+    }
+  }
+
+  .calendar-table {
+    border: @daterangepicker-calendar-border-size solid @daterangepicker-calendar-border-color;
+    padding: @daterangepicker-calendar-margin;
+    border-radius: @daterangepicker-calendar-border-radius;
+    background-color: @daterangepicker-calendar-bg-color;
+  }
+
+  table {
+    width: 100%;
+    margin: 0;
+  }
+
+  td, th {
+    text-align: center;
+    width: @daterangepicker-cell-width;
+    height: @daterangepicker-cell-height;
+    border-radius: @daterangepicker-cell-border-radius;
+    border: @daterangepicker-cell-border-size solid @daterangepicker-cell-border-color;
+    white-space: nowrap;
+    cursor: pointer;
+
+    &.available {
+      &:hover {
+        background-color: @daterangepicker-cell-hover-bg-color;
+        border-color: @daterangepicker-cell-hover-border-color;
+        color: @daterangepicker-cell-hover-color;
+      }
+    }
+
+    &.week {
+      font-size: 80%;
+      color: #ccc;
+    }
+  }
+
+  td {
+    &.off {
+      &, &.in-range, &.start-date, &.end-date {
+        background-color: @daterangepicker-unselected-bg-color;
+        border-color: @daterangepicker-unselected-border-color;
+        color: @daterangepicker-unselected-color;
+      }
+    }
+
+    //
+    // Date Range
+    &.in-range {
+      background-color: @daterangepicker-in-range-bg-color;
+      border-color: @daterangepicker-in-range-border-color;
+      color: @daterangepicker-in-range-color;
+
+      // TODO: Should this be static or should it be parameterized?
+      border-radius: 0;
+    }
+
+    &.start-date {
+      border-radius: @daterangepicker-cell-border-radius 0 0 @daterangepicker-cell-border-radius;
+    }
+
+    &.end-date {
+      border-radius: 0 @daterangepicker-cell-border-radius @daterangepicker-cell-border-radius 0;
+    }
+
+    &.start-date.end-date {
+      border-radius: @daterangepicker-cell-border-radius;
+    }
+
+    &.active {
+      &, &:hover {
+        background-color: @daterangepicker-active-bg-color;
+        border-color: @daterangepicker-active-border-color;
+        color: @daterangepicker-active-color;
+      }
+    }
+  }
+
+  th {
+    &.month {
+      width: auto;
+    }
+  }
+
+  //
+  // Disabled Controls
+  //
+  td, option {
+    &.disabled {
+      color: #999;
+      cursor: not-allowed;
+      text-decoration: line-through;
+    }
+  }
+
+  select {
+    &.monthselect, &.yearselect {
+      font-size: 12px;
+      padding: 1px;
+      height: auto;
+      margin: 0;
+      cursor: default;
+    }
+
+    &.monthselect {
+      margin-right: 2%;
+      width: 56%;
+    }
+
+    &.yearselect {
+      width: 40%;
+    }
+
+    &.hourselect, &.minuteselect, &.secondselect, &.ampmselect {
+      width: 50px;
+      margin-bottom: 0;
+    }
+  }
+
+  //
+  // Text Input Controls (above calendar)
+  //
+  .input-mini {
+    border: @daterangepicker-control-border-size solid @daterangepicker-control-border-color;
+    border-radius: @daterangepicker-control-border-radius;
+    color: @daterangepicker-control-color;
+    height: @daterangepicker-control-line-height;
+    line-height: @daterangepicker-control-height;
+    display: block;
+    vertical-align: middle;
+
+    // TODO: Should these all be static, too??
+    margin: 0 0 5px 0;
+    padding: 0 6px 0 28px;
+    width: 100%;
+
+    &.active {
+      border: @daterangepicker-control-active-border-size solid @daterangepicker-control-active-border-color;
+      border-radius: @daterangepicker-control-active-border-radius;
+    }
+  }
+
+  .daterangepicker_input {
+    position: relative;
+
+    i {
+      position: absolute;
+
+      // NOTE: These appear to be eyeballed to me...
+      left: 8px;
+      top: 8px;
+    }
+  }
+  &.rtl {
+    .input-mini {
+      padding-right: 28px;
+      padding-left: 6px;
+    }
+    .daterangepicker_input i {
+      left: auto;
+      right: 8px;
+    }
+  }
+
+  //
+  // Time Picker
+  //
+  .calendar-time {
+    text-align: center;
+    margin: 5px auto;
+    line-height: @daterangepicker-control-line-height;
+    position: relative;
+    padding-left: 28px;
+
+    select {
+      &.disabled {
+        color: @daterangepicker-control-disabled-color;
+        cursor: not-allowed;
+      }
+    }
+  }
+}
+
+//
+// Predefined Ranges
+//
+
+.ranges {
+  font-size: 11px;
+  float: none;
+  margin: 4px;
+  text-align: left;
+
+  ul {
+    list-style: none;
+    margin: 0 auto;
+    padding: 0;
+    width: 100%;
+  }
+
+  li {
+    font-size: 13px;
+    background-color: @daterangepicker-ranges-bg-color;
+    border: @daterangepicker-ranges-border-size solid @daterangepicker-ranges-border-color;
+    border-radius: @daterangepicker-ranges-border-radius;
+    color: @daterangepicker-ranges-color;
+    padding: 3px 12px;
+    margin-bottom: 8px;
+    cursor: pointer;
+
+    &:hover {
+      background-color: @daterangepicker-ranges-hover-bg-color;
+      border: @daterangepicker-ranges-hover-border-size solid @daterangepicker-ranges-hover-border-color;
+      color: @daterangepicker-ranges-hover-color;
+    }
+
+    &.active {
+      background-color: @daterangepicker-ranges-hover-bg-color;
+      border: @daterangepicker-ranges-hover-border-size solid @daterangepicker-ranges-hover-border-color;
+      color: @daterangepicker-ranges-hover-color;
+    }
+  }
+}
+
+/*  Larger Screen Styling */
+@media (min-width: 564px) {
+  .daterangepicker {
+    width: auto;
+
+    .ranges {
+      ul {
+        width: 160px;
+      }
+    }
+
+    &.single {
+      .ranges {
+        ul {
+          width: 100%;
+        }
+      }
+
+      .calendar.left {
+        clear: none;
+      }
+
+      &.ltr {
+        .ranges, .calendar {
+          float:left;
+        }
+      }
+      &.rtl {
+        .ranges, .calendar {
+          float:right;
+        }
+      }
+    }
+
+    &.ltr {
+      direction: ltr;
+      text-align: left;
+      .calendar{
+        &.left {
+          clear: left;
+          margin-right: 0;
+
+          .calendar-table {
+            border-right: none;
+            border-top-right-radius: 0;
+            border-bottom-right-radius: 0;
+          }
+        }
+
+        &.right {
+          margin-left: 0;
+
+          .calendar-table {
+            border-left: none;
+            border-top-left-radius: 0;
+            border-bottom-left-radius: 0;
+          }
+        }
+      }
+
+      .left .daterangepicker_input {
+        padding-right: 12px;
+      }
+
+      .calendar.left .calendar-table {
+        padding-right: 12px;
+      }
+
+      .ranges, .calendar {
+        float: left;
+      }
+    }
+    &.rtl {
+      direction: rtl;
+      text-align: right;
+      .calendar{
+        &.left {
+          clear: right;
+          margin-left: 0;
+
+          .calendar-table {
+            border-left: none;
+            border-top-left-radius: 0;
+            border-bottom-left-radius: 0;
+          }
+        }
+
+        &.right {
+          margin-right: 0;
+
+          .calendar-table {
+            border-right: none;
+            border-top-right-radius: 0;
+            border-bottom-right-radius: 0;
+          }
+        }
+      }
+
+      .left .daterangepicker_input {
+        padding-left: 12px;
+      }
+
+      .calendar.left .calendar-table {
+        padding-left: 12px;
+      }
+
+      .ranges, .calendar {
+        text-align: right;
+        float: right;
+      }
+    }
+  }
+}
+
+@media (min-width: 730px) {
+  .daterangepicker {
+    .ranges {
+      width: auto;
+    }
+    &.ltr {
+      .ranges {
+        float: left;
+      }
+    }
+    &.rtl {
+      .ranges {
+        float: right;
+      }
+    }
+
+    .calendar.left {
+      clear: none !important;
+    }
+  }
+}

+ 1 - 0
services/web/test/unit/coffee/Project/ProjectControllerTests.coffee

@@ -310,6 +310,7 @@ describe "ProjectController", ->
 
 			it 'should show for paid users', (done) ->
 				@user.features.github = true
+				@user.features.dropbox = true
 				@res.render = (pageName, opts)=>
 					opts.frontChatWidgetRoomId.should.equal @settings.overleaf.front_chat_widget_room_id
 					done()

+ 18 - 2
services/web/webpack.config.js

@@ -62,9 +62,26 @@ module.exports = {
 					cacheDirectory: true
 				}
 			}]
+		},
+		{
+			// These options are necesary for handlebars to have access to helper
+			// methods
+			test: /\.handlebars$/,
+			loader: "handlebars-loader",
+			options: {
+				compat: true,
+				knownHelpersOnly: false,
+				runtimePath: 'handlebars/runtime',
+			}
 		}]
 	},
-
+	resolve: {
+		alias: {
+			// makes handlerbars globally accessible to backbone
+			handlebars: 'handlebars/dist/handlebars.min.js',
+			jquery: path.join(__dirname, 'node_modules/jquery/dist/jquery'),
+		}
+	},
 	plugins: [
 		new webpack.DefinePlugin({
 			// Swaps out checks for NODE_ENV with the env. This is used by various
@@ -77,4 +94,3 @@ module.exports = {
 		})
 	]
 }
-

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików