diff --git a/services/web/app/views/_mixins/faq_search.pug b/services/web/app/views/_mixins/faq_search.pug deleted file mode 100644 index ca51cb29c2..0000000000 --- a/services/web/app/views/_mixins/faq_search.pug +++ /dev/null @@ -1,32 +0,0 @@ -mixin faq_search(headerText, headerClass) - if (typeof(settings.algolia) != "undefined" && typeof(settings.algolia.indexes) != "undefined" && typeof(settings.algolia.indexes.wiki) != "undefined") - if headerText - div(class=headerClass, ng-non-bindable) #{headerText} - .wiki(ng-controller="SearchWikiController") - form.project-search.form-horizontal(role="search") - .form-group.has-feedback.has-feedback-left - .col-sm-12 - input.form-control(type='text', ng-model='searchQueryText', ng-keyup='search()', placeholder="Search help library…") - i.fa.fa-search.form-control-feedback-left(aria-hidden="true") - i.fa.fa-times.form-control-feedback( - ng-click="clearSearchText()", - style="cursor: pointer;", - ng-show="searchQueryText.length > 0" - aria-hidden="true" - ) - button.sr-only( - type="button" - ng-click="clearSearchText()", - ng-show="searchQueryText.length > 0" - ) #{translate('clear_search')} - - .row(role="region" aria-label="search results") - .col-md-12(ng-cloak) - span.sr-only(ng-show="searchQueryText.length > 0" aria-live="polite") - span(ng-if="hits_total > config_hits_per_page") Showing first {{hits.length}} results of {{hits_total}} for {{searchQueryText}} - span(ng-if="hits_total <= config_hits_per_page") {{hits.length}} results for {{searchQueryText}} - a(ng-href='{{hit.url}}',ng-repeat='hit in hits').search-result.card.card-thin - span(ng-bind-html='hit.name') - div.search-result-content(ng-show="hit.content != ''", ng-bind-html='hit.content') - .row-spaced-small.search-result.card.card-thin(ng-if="!processingSearch && searchQueryText.length > 1 && hits.length === 0") - p #{translate("no_search_results")} diff --git a/services/web/app/views/project/importing.pug b/services/web/app/views/project/importing.pug deleted file mode 100644 index bd8e12e349..0000000000 --- a/services/web/app/views/project/importing.pug +++ /dev/null @@ -1,21 +0,0 @@ -extends ../layout - -block vars - - var suppressNavbar = true - - var suppressFooter = true - - var suppressSkipToContent = true - - var suppressCookieBanner = true - - metadata.robotsNoindexNofollow = true - -block content - .editor(ng-controller="ImportingController").full-size - .loading-screen - .loading-screen-brand-container - .loading-screen-brand( - style="height: 20%;" - ng-style="{ 'height': state.load_progress + '%' }" - ) - h3.loading-screen-label #{translate("importing")} - span.loading-screen-ellip . - span.loading-screen-ellip . - span.loading-screen-ellip . diff --git a/services/web/frontend/js/directives/asyncForm.js b/services/web/frontend/js/directives/asyncForm.js deleted file mode 100644 index fb5c899987..0000000000 --- a/services/web/frontend/js/directives/asyncForm.js +++ /dev/null @@ -1,192 +0,0 @@ -import App from '../base' -App.directive('asyncForm', [ - '$http', - 'validateCaptcha', - 'validateCaptchaV3', - function ($http, validateCaptcha, validateCaptchaV3) { - return { - controller: [ - '$scope', - '$location', - function ($scope, $location) { - this.getEmail = () => $scope.email - this.getEmailFromQuery = () => - $location.search().email || $location.search().new_email - return this - }, - ], - link(scope, element, attrs, ctrl) { - let response - const formName = attrs.asyncForm - - scope[attrs.name].response = response = {} - scope[attrs.name].inflight = false - scope.email = - scope.email || - scope.usersEmail || - ctrl.getEmailFromQuery() || - attrs.newEmail - - const validateCaptchaIfEnabled = function (callback) { - scope.$applyAsync(() => { - scope[attrs.name].inflight = true - }) - - if (attrs.captchaActionName) { - validateCaptchaV3(attrs.captchaActionName) - } - if (attrs.captcha != null) { - validateCaptcha(callback) - } else { - callback() - } - } - - const _submitRequest = function (grecaptchaResponse) { - const formData = {} - for (const data of Array.from(element.serializeArray())) { - formData[data.name] = data.value - } - - if (grecaptchaResponse) { - formData['g-recaptcha-response'] = grecaptchaResponse - } - - // clear the response object which may be referenced downstream - Object.keys(response).forEach(field => delete response[field]) - - // for asyncForm prevent automatic redirect to /login if - // authentication fails, we will handle it ourselves - const httpRequestFn = _httpRequestFn(element.attr('method')) - return httpRequestFn(element.attr('action'), formData, { - disableAutoLoginRedirect: true, - }) - .then(function (httpResponse) { - const { data, headers } = httpResponse - scope[attrs.name].inflight = false - response.success = true - response.error = false - - const onSuccessHandler = scope[attrs.onSuccess] - if (onSuccessHandler) { - onSuccessHandler(httpResponse) - return - } - - if (data.redir) { - ga('send', 'event', formName, 'success') - return (window.location = data.redir) - } else if (data.message) { - response.message = data.message - - if (data.message.type === 'error') { - response.success = false - response.error = true - return ga('send', 'event', formName, 'failure', data.message) - } else { - return ga('send', 'event', formName, 'success') - } - } else if (scope.$eval(attrs.asyncFormDownloadResponse)) { - const blob = new Blob([data], { - type: headers('Content-Type'), - }) - location.href = URL.createObjectURL(blob) // Trigger file save - } - }) - .catch(function (httpResponse) { - const { data, status } = httpResponse - scope[attrs.name].inflight = false - response.success = false - response.error = true - response.status = status - response.data = data - - const onErrorHandler = scope[attrs.onError] - if (onErrorHandler) { - onErrorHandler(httpResponse) - return - } - - let responseMessage - if (data.message && data.message.text) { - responseMessage = data.message.text - } else { - responseMessage = data.message - } - - if (status === 400) { - // Bad Request - response.message = { - text: - responseMessage || - 'Invalid Request. Please correct the data and try again.', - type: 'error', - } - } else if (status === 403) { - // Forbidden - response.message = { - text: - responseMessage || - 'Session error. Please check you have cookies enabled. If the problem persists, try clearing your cache and cookies.', - type: 'error', - } - } else if (status === 429) { - response.message = { - text: - responseMessage || - 'Too many attempts. Please wait for a while and try again.', - type: 'error', - } - } else { - response.message = { - text: - responseMessage || - 'Something went wrong talking to the server :(. Please try again.', - type: 'error', - } - } - ga('send', 'event', formName, 'failure', data.message) - }) - } - - const submit = () => - validateCaptchaIfEnabled(response => _submitRequest(response)) - - const _httpRequestFn = (method = 'post') => { - const $HTTP_FNS = { - post: $http.post, - get: $http.get, - } - return $HTTP_FNS[method.toLowerCase()] - } - - element.on('submit', function (e) { - e.preventDefault() - submit() - }) - - if (attrs.autoSubmit) { - submit() - } - }, - } - }, -]) - -App.directive('formMessages', function () { - return { - restrict: 'E', - template: `\ -
-
-
\ -`, - transclude: true, - scope: { - form: '=for', - }, - } -}) diff --git a/services/web/frontend/js/directives/autoSubmitForm.js b/services/web/frontend/js/directives/autoSubmitForm.js deleted file mode 100644 index b1df2792be..0000000000 --- a/services/web/frontend/js/directives/autoSubmitForm.js +++ /dev/null @@ -1,8 +0,0 @@ -import App from '../base' -App.directive('autoSubmitForm', function () { - return { - link(scope, element) { - element.submit() // Runs on load - }, - } -}) diff --git a/services/web/frontend/js/directives/bookmarkableTabset.js b/services/web/frontend/js/directives/bookmarkableTabset.js deleted file mode 100644 index 851c5c2ab7..0000000000 --- a/services/web/frontend/js/directives/bookmarkableTabset.js +++ /dev/null @@ -1,71 +0,0 @@ -import _ from 'lodash' -import App from '../base' -App.directive('bookmarkableTabset', [ - '$location', - function ($location) { - return { - restrict: 'A', - require: 'tabset', - link(scope, el, attrs, tabset) { - const _makeActive = function (hash) { - if (hash && hash !== '') { - const matchingTab = _.find( - tabset.tabs, - tab => tab.bookmarkableTabId === hash - ) - if (matchingTab) { - matchingTab.select() - return el.children()[0].scrollIntoView({ behavior: 'smooth' }) - } - } - } - - scope.$applyAsync(function () { - // for page load - const hash = $location.hash() - _makeActive(hash) - - // for links within page to a tab - // this needs to be within applyAsync because there could be a link - // within a tab to another tab - const linksToTabs = document.querySelectorAll('.link-to-tab') - const _clickLinkToTab = event => { - const hash = event.currentTarget - .getAttribute('href') - .split('#') - .pop() - _makeActive(hash) - } - - if (linksToTabs) { - Array.from(linksToTabs).map(link => - link.addEventListener('click', _clickLinkToTab) - ) - } - }) - }, - } - }, -]) - -App.directive('bookmarkableTab', [ - '$location', - function ($location) { - return { - restrict: 'A', - require: 'tab', - link(scope, el, attrs, tab) { - const tabScope = el.isolateScope() - const tabId = attrs.bookmarkableTab - if (tabScope && tabId && tabId !== '') { - tabScope.bookmarkableTabId = tabId - tabScope.$watch('active', function (isActive, wasActive) { - if (isActive && !wasActive && $location.hash() !== tabId) { - return $location.hash(tabId) - } - }) - } - }, - } - }, -]) diff --git a/services/web/frontend/js/directives/equals.js b/services/web/frontend/js/directives/equals.js deleted file mode 100644 index b1cffd9da0..0000000000 --- a/services/web/frontend/js/directives/equals.js +++ /dev/null @@ -1,23 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('equals', function () { - return { - require: 'ngModel', - link(scope, elem, attrs, ctrl) { - const firstField = `#${attrs.equals}` - return elem.add(firstField).on('keyup', () => - scope.$apply(function () { - const equal = elem.val() === $(firstField).val() - return ctrl.$setValidity('areEqual', equal) - }) - ) - }, - } -}) diff --git a/services/web/frontend/js/directives/expandableTextArea.js b/services/web/frontend/js/directives/expandableTextArea.js deleted file mode 100644 index deefc5190b..0000000000 --- a/services/web/frontend/js/directives/expandableTextArea.js +++ /dev/null @@ -1,31 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('expandableTextArea', function () { - return { - restrict: 'A', - link(scope, el) { - const resetHeight = function () { - const curHeight = el.outerHeight() - const fitHeight = el.prop('scrollHeight') - // clear height if text area is empty - if (el.val() === '') { - el.css('height', 'unset') - } - // otherwise expand to fit text - else if (fitHeight > curHeight) { - scope.$emit('expandable-text-area:resize') - el.css('height', fitHeight) - } - } - - return scope.$watch(() => el.val(), resetHeight) - }, - } -}) diff --git a/services/web/frontend/js/directives/focus.js b/services/web/frontend/js/directives/focus.js deleted file mode 100644 index e40c122194..0000000000 --- a/services/web/frontend/js/directives/focus.js +++ /dev/null @@ -1,118 +0,0 @@ -/* eslint-disable - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' -App.directive('focusWhen', [ - '$timeout', - function ($timeout) { - return { - restrict: 'A', - link(scope, element, attr) { - return scope.$watch(attr.focusWhen, function (value) { - if (value) { - return $timeout(() => element.focus()) - } - }) - }, - } - }, -]) - -App.directive('focusOn', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return scope.$on(attrs.focusOn, () => element.focus()) - }, - } -}) - -App.directive('selectWhen', [ - '$timeout', - function ($timeout) { - return { - restrict: 'A', - link(scope, element, attr) { - return scope.$watch(attr.selectWhen, function (value) { - if (value) { - return $timeout(() => element.select()) - } - }) - }, - } - }, -]) - -App.directive('selectOn', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return scope.$on(attrs.selectOn, () => element.select()) - }, - } -}) - -App.directive('selectNameWhen', [ - '$timeout', - function ($timeout) { - return { - restrict: 'A', - link(scope, element, attrs) { - return scope.$watch(attrs.selectNameWhen, function (value) { - if (value) { - return $timeout(() => selectName(element)) - } - }) - }, - } - }, -]) - -App.directive('selectNameOn', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return scope.$on(attrs.selectNameOn, () => selectName(element)) - }, - } -}) - -App.directive('focus', [ - '$timeout', - function ($timeout) { - return { - scope: { - trigger: '@focus', - }, - - link(scope, element) { - return scope.$watch('trigger', function (value) { - if (value === 'true') { - return $timeout(() => element[0].focus()) - } - }) - }, - } - }, -]) - -function selectName(element) { - // Select up to last '.'. I.e. everything except the file extension - element.focus() - const name = element.val() - if (element[0].setSelectionRange != null) { - let selectionEnd = name.lastIndexOf('.') - if (selectionEnd === -1) { - selectionEnd = name.length - } - return element[0].setSelectionRange(0, selectionEnd) - } -} diff --git a/services/web/frontend/js/directives/maxHeight.js b/services/web/frontend/js/directives/maxHeight.js deleted file mode 100644 index eb9fd3de93..0000000000 --- a/services/web/frontend/js/directives/maxHeight.js +++ /dev/null @@ -1,22 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('maxHeight', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return scope.$watch(attrs.maxHeight, function (value) { - if (value != null) { - return element.css({ 'max-height': value }) - } - }) - }, - } -}) diff --git a/services/web/frontend/js/directives/onEnter.js b/services/web/frontend/js/directives/onEnter.js deleted file mode 100644 index 1dbfda8f2f..0000000000 --- a/services/web/frontend/js/directives/onEnter.js +++ /dev/null @@ -1,18 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('onEnter', function () { - return (scope, element, attrs) => - element.bind('keydown keypress', function (event) { - if (event.which === 13) { - scope.$apply(() => scope.$eval(attrs.onEnter, { event })) - return event.preventDefault() - } - }) -}) diff --git a/services/web/frontend/js/directives/rightClick.js b/services/web/frontend/js/directives/rightClick.js deleted file mode 100644 index 1677d4a2e7..0000000000 --- a/services/web/frontend/js/directives/rightClick.js +++ /dev/null @@ -1,21 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('rightClick', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return element.bind('contextmenu', function (e) { - e.preventDefault() - e.stopPropagation() - return scope.$eval(attrs.rightClick) - }) - }, - } -}) diff --git a/services/web/frontend/js/directives/scroll.js b/services/web/frontend/js/directives/scroll.js deleted file mode 100644 index 1d490e823d..0000000000 --- a/services/web/frontend/js/directives/scroll.js +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable - max-len, - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('updateScrollBottomOn', [ - '$timeout', - function ($timeout) { - return { - restrict: 'A', - link(scope, element, attrs, ctrls) { - // We keep the offset from the bottom fixed whenever the event fires - // - // ^ | ^ - // | | | scrollTop - // | | v - // | |----------- - // | | ^ - // | | | - // | | | clientHeight (viewable area) - // | | | - // | | | - // | | v - // | |----------- - // | | ^ - // | | | scrollBottom - // v | v - // \ - // scrollHeight - - let scrollBottom = 0 - element.on( - 'scroll', - e => - (scrollBottom = - element[0].scrollHeight - - element[0].scrollTop - - element[0].clientHeight) - ) - - return scope.$on(attrs.updateScrollBottomOn, () => - $timeout( - () => - element.scrollTop( - element[0].scrollHeight - element[0].clientHeight - scrollBottom - ), - 0 - ) - ) - }, - } - }, -]) diff --git a/services/web/frontend/js/directives/selectAll.js b/services/web/frontend/js/directives/selectAll.js deleted file mode 100644 index 7737350fbc..0000000000 --- a/services/web/frontend/js/directives/selectAll.js +++ /dev/null @@ -1,108 +0,0 @@ -/* eslint-disable - max-len, - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' -App.directive('selectAllList', function () { - return { - controller: [ - '$scope', - function ($scope) { - // Selecting or deselecting all should apply to all projects - this.selectAll = () => $scope.$broadcast('select-all:select') - - this.deselectAll = () => $scope.$broadcast('select-all:deselect') - - this.clearSelectAllState = () => $scope.$broadcast('select-all:clear') - }, - ], - link(scope, element, attrs) {}, - } -}) - -App.directive('selectAll', function () { - return { - require: '^selectAllList', - link(scope, element, attrs, selectAllListController) { - scope.$on('select-all:clear', () => element.prop('checked', false)) - - return element.change(function () { - if (element.is(':checked')) { - selectAllListController.selectAll() - } else { - selectAllListController.deselectAll() - } - return true - }) - }, - } -}) - -App.directive('selectIndividual', function () { - return { - require: '^selectAllList', - scope: { - ngModel: '=', - }, - link(scope, element, attrs, selectAllListController) { - let ignoreChanges = false - - scope.$watch('ngModel', function (value) { - if (value != null && !ignoreChanges) { - return selectAllListController.clearSelectAllState() - } - }) - - scope.$on('select-all:select', function () { - if (element.prop('disabled')) { - return - } - ignoreChanges = true - scope.$apply(() => (scope.ngModel = true)) - return (ignoreChanges = false) - }) - - scope.$on('select-all:deselect', function () { - if (element.prop('disabled')) { - return - } - ignoreChanges = true - scope.$apply(() => (scope.ngModel = false)) - return (ignoreChanges = false) - }) - - return scope.$on('select-all:row-clicked', function () { - if (element.prop('disabled')) { - return - } - ignoreChanges = true - scope.$apply(function () { - scope.ngModel = !scope.ngModel - if (!scope.ngModel) { - return selectAllListController.clearSelectAllState() - } - }) - return (ignoreChanges = false) - }) - }, - } -}) - -export default App.directive('selectRow', function () { - return { - scope: true, - link(scope, element, attrs) { - return element.on('click', e => - scope.$broadcast('select-all:row-clicked') - ) - }, - } -}) diff --git a/services/web/frontend/js/directives/stopPropagation.js b/services/web/frontend/js/directives/stopPropagation.js deleted file mode 100644 index c6c2ed349c..0000000000 --- a/services/web/frontend/js/directives/stopPropagation.js +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-disable - max-len, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' -App.directive('stopPropagation', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return element.bind(attrs.stopPropagation, e => e.stopPropagation()) - }, - } -}) - -export default App.directive('preventDefault', function () { - return { - restrict: 'A', - link(scope, element, attrs) { - return element.bind(attrs.preventDefault, e => e.preventDefault()) - }, - } -}) diff --git a/services/web/frontend/js/directives/videoPlayState.js b/services/web/frontend/js/directives/videoPlayState.js deleted file mode 100644 index 8cc1885145..0000000000 --- a/services/web/frontend/js/directives/videoPlayState.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable - max-len, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.directive('videoPlayState', [ - '$parse', - function ($parse) { - return { - restrict: 'A', - link(scope, element, attrs) { - const videoDOMEl = element[0] - return scope.$watch( - () => $parse(attrs.videoPlayState)(scope), - function (shouldPlay) { - if (shouldPlay) { - videoDOMEl.currentTime = 0 - return videoDOMEl.play() - } else { - return videoDOMEl.pause() - } - } - ) - }, - } - }, -]) diff --git a/services/web/frontend/js/filters/formatDate.js b/services/web/frontend/js/filters/formatDate.js deleted file mode 100644 index 411f013641..0000000000 --- a/services/web/frontend/js/filters/formatDate.js +++ /dev/null @@ -1,48 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' -import moment from 'moment' -moment.updateLocale('en', { - calendar: { - lastDay: '[Yesterday]', - sameDay: '[Today]', - nextDay: '[Tomorrow]', - lastWeek: 'ddd, Do MMM YY', - nextWeek: 'ddd, Do MMM YY', - sameElse: 'ddd, Do MMM YY', - }, -}) - -App.filter( - 'formatDate', - () => - function (date, format) { - if (!date) return 'N/A' - if (format == null) { - format = 'Do MMM YYYY, h:mm a' - } - return moment(date).format(format) - } -) - -App.filter( - 'utcDate', - () => - function (date, format) { - if (!date) return 'N/A' - if (format == null) { - format = 'D MMM YYYY, HH:mm:ss' - } - return moment(date).utc().format(format) + ' UTC' - } -) - -App.filter('relativeDate', () => date => moment(date).calendar()) - -App.filter('fromNowDate', () => date => moment(date).fromNow()) diff --git a/services/web/frontend/js/ide.js b/services/web/frontend/js/ide.js index 94f8b8df92..c293b8bdfd 100644 --- a/services/web/frontend/js/ide.js +++ b/services/web/frontend/js/ide.js @@ -32,24 +32,11 @@ import './ide/chat/index' import './ide/file-view/index' import './ide/toolbar/index' import './ide/directives/layout' -import './ide/directives/validFile' import './ide/directives/verticalResizablePanes' import './ide/services/ide' -import './directives/focus' -import './directives/scroll' -import './directives/onEnter' -import './directives/stopPropagation' -import './directives/rightClick' -import './directives/expandableTextArea' -import './directives/videoPlayState' -import './services/queued-http' -import './services/validateCaptcha' -import './services/validateCaptchaV3' -import './services/wait-for' -import './filters/formatDate' -import './main/event' -import './main/account-upgrade-angular' -import './main/system-messages' +import './services/queued-http' // used in FileTreeManager +import './main/event' // used in various controllers +import './main/system-messages' // used in project/editor import '../../modules/modules-ide' import './features/source-editor/ide' import './shared/context/controllers/root-context-controller' diff --git a/services/web/frontend/js/ide/directives/validFile.js b/services/web/frontend/js/ide/directives/validFile.js deleted file mode 100644 index 339bc99d67..0000000000 --- a/services/web/frontend/js/ide/directives/validFile.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable - max-len, - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../../base' -import SafePath from './SafePath' - -export default App.directive('validFile', function () { - return { - require: 'ngModel', - link(scope, element, attrs, ngModelCtrl) { - return (ngModelCtrl.$validators.validFile = filename => - SafePath.isCleanFilename(filename)) - }, - } -}) diff --git a/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js b/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js index e0211988a7..95f155b90d 100644 --- a/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js +++ b/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js @@ -143,10 +143,6 @@ export default App.controller('ReviewPanelController', [ ide.$scope.$broadcast('review-panel:layout', false) }) - $scope.$on('expandable-text-area:resize', event => - $timeout(() => ide.$scope.$broadcast('review-panel:layout')) - ) - $scope.$on('review-panel:sizes', (e, sizes) => { $scope.$broadcast('editor:set-scroll-size', sizes) dispatchReviewPanelEvent('sizes', sizes) diff --git a/services/web/frontend/js/main.js b/services/web/frontend/js/main.js index f57fc632ce..fbb23356a7 100644 --- a/services/web/frontend/js/main.js +++ b/services/web/frontend/js/main.js @@ -8,36 +8,16 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -import './main/token-access' -import './main/clear-sessions' -import './main/account-upgrade-angular' -import './main/plans' -import './main/scribtex-popup' -import './main/event' -import './main/bonus' -import './main/system-messages' -import './main/annual-upgrade' -import './main/subscription/team-invite-controller' -import './main/learn' -import './main/keys' -import './main/importing' -import './directives/autoSubmitForm' -import './directives/asyncForm' -import './directives/stopPropagation' -import './directives/focus' -import './directives/equals' -import './directives/eventTracking' -import './directives/onEnter' -import './directives/selectAll' -import './directives/maxHeight' -import './directives/bookmarkableTabset' -import './services/queued-http' -import './services/validateCaptcha' -import './services/validateCaptchaV3' -import './filters/formatDate' +import './main/token-access' // used in project/token/access +import './main/event' // used in various controllers +import './main/bonus' // used in referal/bonus +import './main/system-messages' // used in project/editor +import './main/annual-upgrade' // used in subscriptions/upgradeToAnnual +import './main/subscription/team-invite-controller' // used in subscriptions/team/invite +import './directives/eventTracking' // used in lots of places import './features/cookie-banner' import '../../modules/modules-main' -import './cdn-load-test' +import './cdn-load-test' // TODO: remove this? import { debugConsole } from '@/utils/debugging' angular.module('SharelatexApp').config([ '$locationProvider', diff --git a/services/web/frontend/js/main/account-upgrade-angular.js b/services/web/frontend/js/main/account-upgrade-angular.js deleted file mode 100644 index 90fed142f7..0000000000 --- a/services/web/frontend/js/main/account-upgrade-angular.js +++ /dev/null @@ -1,20 +0,0 @@ -import App from '../base' -import { startFreeTrial, upgradePlan, paywallPrompt } from './account-upgrade' - -App.controller('FreeTrialModalController', [ - '$scope', - function ($scope) { - $scope.buttonClass = 'btn-primary' - $scope.startFreeTrial = (source, version) => - startFreeTrial(source, version, $scope) - $scope.paywallPrompt = source => paywallPrompt(source) - }, -]) - -App.controller('UpgradeModalController', [ - '$scope', - function ($scope) { - $scope.buttonClass = 'btn-primary' - $scope.upgradePlan = source => upgradePlan(source, $scope) - }, -]) diff --git a/services/web/frontend/js/main/clear-sessions.js b/services/web/frontend/js/main/clear-sessions.js deleted file mode 100644 index 6ecf09d8d8..0000000000 --- a/services/web/frontend/js/main/clear-sessions.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable - max-len, - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' -import getMeta from '../utils/meta' - -export default App.controller('ClearSessionsController', [ - '$scope', - '$http', - function ($scope, $http) { - $scope.state = { - otherSessions: getMeta('ol-otherSessions'), - error: false, - success: false, - } - - return ($scope.clearSessions = function () { - return $http({ - method: 'POST', - url: '/user/sessions/clear', - headers: { 'X-CSRF-Token': window.csrfToken }, - }) - .then(function () { - $scope.state.otherSessions = [] - $scope.state.error = false - return ($scope.state.success = true) - }) - .catch(() => ($scope.state.error = true)) - }) - }, -]) diff --git a/services/web/frontend/js/main/keys.js b/services/web/frontend/js/main/keys.js deleted file mode 100644 index 41b2f55fe6..0000000000 --- a/services/web/frontend/js/main/keys.js +++ /dev/null @@ -1,23 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.constant('Keys', { - ENTER: 13, - TAB: 9, - ESCAPE: 27, - SPACE: 32, - BACKSPACE: 8, - UP: 38, - DOWN: 40, - LEFT: 37, - RIGHT: 39, - PERIOD: 190, - COMMA: 188, - END: 35, -}) diff --git a/services/web/frontend/js/main/learn.js b/services/web/frontend/js/main/learn.js deleted file mode 100644 index f6bce77255..0000000000 --- a/services/web/frontend/js/main/learn.js +++ /dev/null @@ -1,102 +0,0 @@ -import _ from 'lodash' -import App from '../base' -import '../directives/mathjax' -import '../services/algolia-search' -App.controller('SearchWikiController', [ - '$scope', - 'algoliaSearch', - function ($scope, algoliaSearch) { - $scope.hits = [] - $scope.hits_total = 0 - $scope.config_hits_per_page = 20 - $scope.processingSearch = false - - $scope.clearSearchText = function () { - $scope.searchQueryText = '' - updateHits([]) - } - - $scope.safeApply = function (fn) { - const phase = $scope.$root.$$phase - if (phase === '$apply' || phase === '$digest') { - $scope.$eval(fn) - } else { - $scope.$apply(fn) - } - } - - const buildHitViewModel = function (hit) { - const pagePath = hit.kb ? 'how-to/' : 'latex/' - const pageSlug = encodeURIComponent(hit.pageName.replace(/\s/g, '_')) - let sectionUnderscored = '' - if (hit.sectionName && hit.sectionName !== '') { - sectionUnderscored = '#' + hit.sectionName.replace(/\s/g, '_') - } - const section = hit._highlightResult.sectionName - let pageName = hit._highlightResult.pageName.value - if (section && section.value && section !== '') { - pageName += ' - ' + section.value - } - - let content = hit._highlightResult.content.value - // Replace many new lines - content = content.replace(/\n\n+/g, '\n\n') - const lines = content.split('\n') - // Only show the lines that have a highlighted match - const matchingLines = [] - for (const line of lines) { - if (!/^\[edit\]/.test(line)) { - content += line + '\n' - if (//.test(line)) { - matchingLines.push(line) - } - } - } - content = matchingLines.join('\n...\n') - const result = { - name: pageName, - url: `/learn/${pagePath}${pageSlug}${sectionUnderscored}`, - content, - } - return result - } - - const updateHits = (hits, hitsTotal = 0) => { - $scope.safeApply(() => { - $scope.hits = hits - $scope.hits_total = hitsTotal - }) - } - - $scope.search = function () { - $scope.processingSearch = true - const query = $scope.searchQueryText - if (!query || query.length === 0) { - updateHits([]) - return - } - - algoliaSearch.searchWiki( - query, - { - hitsPerPage: $scope.config_hits_per_page, - }, - function (err, response) { - if (err) { - $scope.searchError = err - } - - $scope.processingSearch = false - if (response.hits.length === 0) { - updateHits([]) - } else { - const hits = _.map(response.hits, buildHitViewModel) - updateHits(hits, response.nbHits) - } - } - ) - } - }, -]) - -export default App.controller('LearnController', function () {}) diff --git a/services/web/frontend/js/main/plans.js b/services/web/frontend/js/main/plans.js deleted file mode 100644 index 11b2b93a91..0000000000 --- a/services/web/frontend/js/main/plans.js +++ /dev/null @@ -1,340 +0,0 @@ -/* eslint-disable - camelcase, - max-len -*/ -import App from '../base' -import getMeta from '../utils/meta' - -App.factory('MultiCurrencyPricing', function () { - const currencyCode = getMeta('ol-recommendedCurrency') - - return { - currencyCode, - - plans: { - USD: { - symbol: '$', - student: { - monthly: '$9', - annual: '$89', - }, - personal: { - monthly: '$14', - annual: '$129', - }, - collaborator: { - monthly: '$21', - annual: '$199', - }, - professional: { - monthly: '$42', - annual: '$399', - }, - }, - EUR: { - symbol: '€', - student: { - monthly: '€8', - annual: '€79', - }, - personal: { - monthly: '€13', - annual: '€119', - }, - collaborator: { - monthly: '€19', - annual: '€179', - }, - professional: { - monthly: '€39', - annual: '€369', - }, - }, - GBP: { - symbol: '£', - student: { - monthly: '£7', - annual: '£69', - }, - personal: { - monthly: '£11', - annual: '£104', - }, - collaborator: { - monthly: '£17', - annual: '£159', - }, - professional: { - monthly: '£34', - annual: '£319', - }, - }, - SEK: { - symbol: 'kr', - student: { - monthly: '66 kr', - annual: '659 kr', - }, - personal: { - monthly: '104 kr', - annual: '969 kr', - }, - collaborator: { - monthly: '154 kr', - annual: '1449 kr', - }, - professional: { - monthly: '299 kr', - annual: '2869 kr', - }, - }, - CAD: { - symbol: '$', - student: { - monthly: '$10', - annual: '$99', - }, - personal: { - monthly: '$16', - annual: '$149', - }, - collaborator: { - monthly: '$25', - annual: '$229', - }, - professional: { - monthly: '$48', - annual: '$449', - }, - }, - NOK: { - symbol: 'kr', - student: { - monthly: '66 kr', - annual: '659 kr', - }, - personal: { - monthly: '104 kr', - annual: '969 kr', - }, - collaborator: { - monthly: '154 kr', - annual: '1449 kr', - }, - professional: { - monthly: '299 kr', - annual: '2869 kr', - }, - }, - DKK: { - symbol: 'kr', - student: { - monthly: '55 kr', - annual: '549 kr', - }, - personal: { - monthly: '84 kr', - annual: '799 kr', - }, - collaborator: { - monthly: '129 kr', - annual: '1199 kr', - }, - professional: { - monthly: '249 kr', - annual: '2379 kr', - }, - }, - AUD: { - symbol: '$', - student: { - monthly: '$11', - annual: '$109', - }, - personal: { - monthly: '$17', - annual: '$159', - }, - collaborator: { - monthly: '$25', - annual: '$239', - }, - professional: { - monthly: '$49', - annual: '$459', - }, - }, - NZD: { - symbol: '$', - student: { - monthly: '$11', - annual: '$109', - }, - personal: { - monthly: '$17', - annual: '$159', - }, - collaborator: { - monthly: '$25', - annual: '$239', - }, - professional: { - monthly: '$49', - annual: '$459', - }, - }, - CHF: { - symbol: 'Fr', - student: { - monthly: 'Fr 9', - annual: 'Fr 89', - }, - personal: { - monthly: 'Fr 14', - annual: 'Fr 134', - }, - collaborator: { - monthly: 'Fr 21', - annual: 'Fr 199', - }, - professional: { - monthly: 'Fr 42', - annual: 'Fr 399', - }, - }, - SGD: { - symbol: '$', - student: { - monthly: '$13', - annual: '$129', - }, - personal: { - monthly: '$18', - annual: '$169', - }, - collaborator: { - monthly: '$28', - annual: '$259', - }, - professional: { - monthly: '$55', - annual: '$519', - }, - }, - INR: { - symbol: '₹', - student: { - monthly: '₹219', - annual: '₹2199', - }, - personal: { - monthly: '₹339', - annual: '₹2999', - }, - collaborator: { - monthly: '₹499', - annual: '₹4599', - }, - professional: { - monthly: '₹999', - annual: '₹9599', - }, - }, - BRL: { - symbol: 'R$', - student: { - monthly: 'R$ 23', - annual: 'R$ 229', - }, - personal: { - monthly: 'R$ 35', - annual: 'R$ 329', - }, - collaborator: { - monthly: 'R$ 55', - annual: 'R$ 499', - }, - professional: { - monthly: 'R$ 109', - annual: 'R$ 999', - }, - }, - MXN: { - symbol: '$', - student: { - monthly: '$99', - annual: '$999', - }, - personal: { - monthly: '$149', - annual: '$1,399', - }, - collaborator: { - monthly: '$229', - annual: '$2,199', - }, - professional: { - monthly: '$459', - annual: '$4,399', - }, - }, - COP: { - symbol: '$', - student: { - monthly: '$ 12.900', - annual: '$ 129.900', - }, - personal: { - monthly: '$ 21.900', - annual: '$ 185.900', - }, - collaborator: { - monthly: '$ 29.900', - annual: '$ 285.900', - }, - professional: { - monthly: '$ 59.900', - annual: '$ 575.900', - }, - }, - CLP: { - symbol: '$', - student: { - monthly: '$3.990', - annual: '$38.990', - }, - personal: { - monthly: '$6.190', - annual: '$56.990', - }, - collaborator: { - monthly: '$9.190', - annual: '$87.990', - }, - professional: { - monthly: '$18.990', - annual: '$174.990', - }, - }, - PEN: { - symbol: 'S/', - student: { - monthly: 'S/ 16', - annual: 'S/ 159', - }, - personal: { - monthly: 'S/ 26', - annual: 'S/ 239', - }, - collaborator: { - monthly: 'S/ 39', - annual: 'S/ 369', - }, - professional: { - monthly: 'S/ 76', - annual: 'S/ 729', - }, - }, - }, - } -}) diff --git a/services/web/frontend/js/main/scribtex-popup.js b/services/web/frontend/js/main/scribtex-popup.js deleted file mode 100644 index 2f29cd22b6..0000000000 --- a/services/web/frontend/js/main/scribtex-popup.js +++ /dev/null @@ -1,17 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.controller('ScribtexPopupController', [ - '$modal', - function ($modal) { - $modal.open({ - templateUrl: 'scribtexModalTemplate', - }) - }, -]) diff --git a/services/web/frontend/js/services/validateCaptcha.js b/services/web/frontend/js/services/validateCaptcha.js deleted file mode 100644 index 7b8cbf41dc..0000000000 --- a/services/web/frontend/js/services/validateCaptcha.js +++ /dev/null @@ -1,46 +0,0 @@ -/* global grecaptcha */ - -/* eslint-disable - no-return-assign, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - */ -import App from '../base' - -export default App.factory('validateCaptcha', function () { - let _recaptchaCallbacks = [] - const onRecaptchaSubmit = function (token) { - for (const cb of _recaptchaCallbacks) { - cb(token) - } - _recaptchaCallbacks = [] - } - - let recaptchaId = null - const validateCaptcha = (callback, captchaDisabled) => { - if (callback == null) { - callback = function () {} - } - if ( - typeof grecaptcha === 'undefined' || - grecaptcha === null || - captchaDisabled - ) { - return callback() - } - const reset = () => grecaptcha.reset() - _recaptchaCallbacks.push(callback) - _recaptchaCallbacks.push(reset) - if (recaptchaId == null) { - const el = $('#recaptcha')[0] - recaptchaId = grecaptcha.render(el, { callback: onRecaptchaSubmit }) - } - return grecaptcha.execute(recaptchaId) - } - - return validateCaptcha -}) diff --git a/services/web/frontend/js/services/validateCaptchaV3.js b/services/web/frontend/js/services/validateCaptchaV3.js deleted file mode 100644 index 8283f34076..0000000000 --- a/services/web/frontend/js/services/validateCaptchaV3.js +++ /dev/null @@ -1,19 +0,0 @@ -import App from '../base' - -export default App.factory('validateCaptchaV3', function () { - const grecaptcha = window.grecaptcha - const ExposedSettings = window.ExposedSettings - return function validateCaptchaV3(actionName, callback = () => {}) { - if (!grecaptcha) { - return - } - if (!ExposedSettings || !ExposedSettings.recaptchaSiteKeyV3) { - return - } - grecaptcha.ready(function () { - grecaptcha - .execute(ExposedSettings.recaptchaSiteKeyV3, { action: actionName }) - .then(callback) - }) - } -}) diff --git a/services/web/frontend/js/services/wait-for.js b/services/web/frontend/js/services/wait-for.js deleted file mode 100644 index 5a177f2887..0000000000 --- a/services/web/frontend/js/services/wait-for.js +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable - max-len, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import App from '../base' - -export default App.factory('waitFor', [ - '$q', - function ($q) { - const waitFor = function (testFunction, timeout, pollInterval) { - if (pollInterval == null) { - pollInterval = 500 - } - const iterationLimit = Math.floor(timeout / pollInterval) - let iterations = 0 - return $q(function (resolve, reject) { - let tryIteration - return (tryIteration = function () { - if (iterations > iterationLimit) { - return reject( - new Error( - `waiting too long, ${JSON.stringify({ timeout, pollInterval })}` - ) - ) - } - iterations += 1 - const result = testFunction() - if (result != null) { - return resolve(result) - } else { - return setTimeout(tryIteration, pollInterval) - } - })() - }) - } - return waitFor - }, -])