diff --git a/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee b/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee index 147f2b8a25..7d7b30ff80 100644 --- a/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee +++ b/services/web/app/coffee/Features/LinkedFiles/UrlAgent.coffee @@ -8,7 +8,9 @@ module.exports = UrlAgent = { } writeIncomingFileToDisk: (project_id, data, current_user_id, callback = (error, fsPath) ->) -> - # TODO: proxy through external API + # TODO: Check it's a valid URL + # TODO: Proxy through external API + # TODO: Error unless valid status code url = data.url readStream = request.get(url) FileWriter.writeStreamToDisk project_id, readStream, callback diff --git a/services/web/app/views/project/editor/file-tree.pug b/services/web/app/views/project/editor/file-tree.pug index c4490204ac..741076c0ad 100644 --- a/services/web/app/views/project/editor/file-tree.pug +++ b/services/web/app/views/project/editor/file-tree.pug @@ -339,6 +339,52 @@ script(type='text/ng-template', id='newDocModalTemplate') span(ng-show="state.inflight") #{translate("creating")}... +script(type='text/ng-template', id='linkedFileModalTemplate') + .modal-header + h3 New file from URL + .modal-body + form(novalidate, name="newLinkedFileForm") + div.alert.alert-danger(ng-if="error") + div(ng-switch="error") + span(ng-switch-when="already exists") #{translate("file_already_exists")} + span(ng-switch-default) {{error}} + label(for="url") URL to fetch the file from + input.form-control( + type="text", + placeholder="www.example.com/my_file", + required, + ng-model="inputs.url", + focus-on="open", + on-enter="create()", + name="url" + ) + .row-spaced + label(for="name") File name in this project + input.form-control( + type="text", + placeholder="my_file", + required, + ng-model="inputs.name", + ng-change="nameChangedByUser = true" + valid-file, + on-enter="create()", + name="name" + ) + .text-danger.row-spaced-small(ng-show="newDocForm.name.$error.validFile") + | #{translate('files_cannot_include_invalid_characters')} + .modal-footer + button.btn.btn-default( + ng-disabled="state.inflight" + ng-click="cancel()" + ) #{translate("cancel")} + button.btn.btn-primary( + ng-disabled="newLinkedFileForm.$invalid || state.inflight" + ng-click="create()" + ) + span(ng-hide="state.inflight") #{translate("create")} + span(ng-show="state.inflight") #{translate("creating")}... + + script(type='text/ng-template', id='newFolderModalTemplate') .modal-header h3 #{translate("new_folder")} diff --git a/services/web/nodemon.frontend.json b/services/web/nodemon.frontend.json index fcba014929..a5897558c0 100644 --- a/services/web/nodemon.frontend.json +++ b/services/web/nodemon.frontend.json @@ -4,6 +4,7 @@ "node_modules/" ], "verbose": true, + "legacyWatch": true, "exec": "make compile", "watch": [ "public/coffee/", diff --git a/services/web/nodemon.json b/services/web/nodemon.json index 5f79257458..7f7195cbab 100644 --- a/services/web/nodemon.json +++ b/services/web/nodemon.json @@ -4,6 +4,7 @@ "node_modules/" ], "verbose": true, + "legacyWatch": true, "execMap": { "js": "npm run start" }, diff --git a/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee b/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee index 9891bd8e74..4914028120 100644 --- a/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee @@ -355,6 +355,20 @@ define [ _csrf: window.csrfToken } + createLinkedFile: (name, parent_folder = @getCurrentFolder(), provider, data) -> + # check if a doc/file/folder already exists with this name + if @existsInThisFolder parent_folder, name + return @nameExistsError() + # We'll wait for the socket.io notification to actually + # add the file for us. + return @ide.$http.post "/project/#{@ide.project_id}/linked_file", { + name: name, + parent_folder_id: parent_folder?.id + provider, + data, + _csrf: window.csrfToken + } + renameEntity: (entity, name, callback = (error) ->) -> return if entity.name == name return if name.length >= 150 diff --git a/services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee b/services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee index ba9eb8a81e..08f26862cb 100644 --- a/services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee +++ b/services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee @@ -30,6 +30,16 @@ define [ } ) + $scope.openLinkedFileModal = window.openLinkedFileModal = () -> + $modal.open( + templateUrl: "linkedFileModalTemplate" + controller: "LinkedFileModalController" + scope: $scope + resolve: { + parent_folder: () -> ide.fileTreeManager.getCurrentFolder() + } + ) + $scope.orderByFoldersFirst = (entity) -> return '0' if entity?.type == "folder" return '1' @@ -186,4 +196,47 @@ define [ $scope.cancel = () -> $modalInstance.dismiss('cancel') - ] \ No newline at end of file + ] + + App.controller "LinkedFileModalController", [ + "$scope", "ide", "$modalInstance", "$timeout", "parent_folder", + ($scope, ide, $modalInstance, $timeout, parent_folder) -> + $scope.inputs = + name: "" + url: "" + $scope.nameChangedByUser = false + $scope.state = + inflight: false + + $modalInstance.opened.then () -> + $timeout () -> + $scope.$broadcast "open" + , 200 + + $scope.$watch "inputs.url", (url) -> + if url? and url != "" and !$scope.nameChangedByUser + url = url.replace("://", "") # Ignore http:// etc + parts = url.split("/").reverse() + if parts.length > 1 # Wait for at one / + $scope.inputs.name = parts[0] + + $scope.create = () -> + {name, url} = $scope.inputs + if !name? or name.length == 0 + return + if !url? or url.length == 0 + return + $scope.state.inflight = true + ide.fileTreeManager + .createLinkedFile(name, parent_folder, 'url', {url}) + .then () -> + $scope.state.inflight = false + $modalInstance.close() + .catch (response)-> + { data } = response + $scope.error = data + $scope.state.inflight = false + + $scope.cancel = () -> + $modalInstance.dismiss('cancel') + ]