}]);
- ngApp.controller('PageAttachmentController', ['$scope', '$http', '$attrs',
- function ($scope, $http, $attrs) {
-
- const pageId = $scope.uploadedTo = $attrs.pageId;
- let currentOrder = '';
- $scope.files = [];
- $scope.editFile = false;
- $scope.file = getCleanFile();
- $scope.errors = {
- link: {},
- edit: {}
- };
-
- function getCleanFile() {
- return {
- page_id: pageId
- };
- }
-
- // Angular-UI-Sort options
- $scope.sortOptions = {
- handle: '.handle',
- items: '> tr',
- containment: "parent",
- axis: "y",
- stop: sortUpdate,
- };
-
- /**
- * Event listener for sort changes.
- * Updates the file ordering on the server.
- * @param event
- * @param ui
- */
- function sortUpdate(event, ui) {
- let newOrder = $scope.files.map(file => {return file.id}).join(':');
- if (newOrder === currentOrder) return;
-
- currentOrder = newOrder;
- $http.put(window.baseUrl(`/attachments/sort/page/${pageId}`), {files: $scope.files}).then(resp => {
- events.emit('success', resp.data.message);
- }, checkError('sort'));
- }
-
- /**
- * Used by dropzone to get the endpoint to upload to.
- * @returns {string}
- */
- $scope.getUploadUrl = function (file) {
- let suffix = (typeof file !== 'undefined') ? `/${file.id}` : '';
- return window.baseUrl(`/attachments/upload${suffix}`);
- };
-
- /**
- * Get files for the current page from the server.
- */
- function getFiles() {
- let url = window.baseUrl(`/attachments/get/page/${pageId}`);
- $http.get(url).then(resp => {
- $scope.files = resp.data;
- currentOrder = resp.data.map(file => {return file.id}).join(':');
- }, checkError('get'));
- }
- getFiles();
-
- /**
- * Runs on file upload, Adds an file to local file list
- * and shows a success message to the user.
- * @param file
- * @param data
- */
- $scope.uploadSuccess = function (file, data) {
- $scope.$apply(() => {
- $scope.files.push(data);
- });
- events.emit('success', trans('entities.attachments_file_uploaded'));
- };
-
- /**
- * Upload and overwrite an existing file.
- * @param file
- * @param data
- */
- $scope.uploadSuccessUpdate = function (file, data) {
- $scope.$apply(() => {
- let search = filesIndexOf(data);
- if (search !== -1) $scope.files[search] = data;
-
- if ($scope.editFile) {
- $scope.editFile = angular.copy(data);
- data.link = '';
- }
- });
- events.emit('success', trans('entities.attachments_file_updated'));
- };
-
- /**
- * Delete a file from the server and, on success, the local listing.
- * @param file
- */
- $scope.deleteFile = function(file) {
- if (!file.deleting) {
- file.deleting = true;
- return;
- }
- $http.delete(window.baseUrl(`/attachments/${file.id}`)).then(resp => {
- events.emit('success', resp.data.message);
- $scope.files.splice($scope.files.indexOf(file), 1);
- }, checkError('delete'));
- };
-
- /**
- * Attach a link to a page.
- * @param file
- */
- $scope.attachLinkSubmit = function(file) {
- file.uploaded_to = pageId;
- $http.post(window.baseUrl('/attachments/link'), file).then(resp => {
- $scope.files.push(resp.data);
- events.emit('success', trans('entities.attachments_link_attached'));
- $scope.file = getCleanFile();
- }, checkError('link'));
- };
-
- /**
- * Start the edit mode for a file.
- * @param file
- */
- $scope.startEdit = function(file) {
- $scope.editFile = angular.copy(file);
- $scope.editFile.link = (file.external) ? file.path : '';
- };
-
- /**
- * Cancel edit mode
- */
- $scope.cancelEdit = function() {
- $scope.editFile = false;
- };
-
- /**
- * Update the name and link of a file.
- * @param file
- */
- $scope.updateFile = function(file) {
- $http.put(window.baseUrl(`/attachments/${file.id}`), file).then(resp => {
- let search = filesIndexOf(resp.data);
- if (search !== -1) $scope.files[search] = resp.data;
-
- if ($scope.editFile && !file.external) {
- $scope.editFile.link = '';
- }
- $scope.editFile = false;
- events.emit('success', trans('entities.attachments_updated_success'));
- }, checkError('edit'));
- };
-
- /**
- * Get the url of a file.
- */
- $scope.getFileUrl = function(file) {
- return window.baseUrl('/attachments/' + file.id);
- };
-
- /**
- * Search the local files via another file object.
- * Used to search via object copies.
- * @param file
- * @returns int
- */
- function filesIndexOf(file) {
- for (let i = 0; i < $scope.files.length; i++) {
- if ($scope.files[i].id == file.id) return i;
- }
- return -1;
- }
-
- /**
- * Check for an error response in a ajax request.
- * @param errorGroupName
- */
- function checkError(errorGroupName) {
- $scope.errors[errorGroupName] = {};
- return function(response) {
- if (typeof response.data !== 'undefined' && typeof response.data.error !== 'undefined') {
- events.emit('error', response.data.error);
- }
- if (typeof response.data !== 'undefined' && typeof response.data.validation !== 'undefined') {
- $scope.errors[errorGroupName] = response.data.validation;
- console.log($scope.errors[errorGroupName])
- }
- }
- }
-
- }]);
-
// Controller used to reply to and add new comments
ngApp.controller('CommentReplyController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
const MarkdownIt = require("markdown-it");
"use strict";
-const DropZone = require("dropzone");
const MarkdownIt = require("markdown-it");
const mdTasksLists = require('markdown-it-task-lists');
const code = require('./code');
module.exports = function (ngApp, events) {
- /**
- * Common tab controls using simple jQuery functions.
- */
- ngApp.directive('tabContainer', function() {
- return {
- restrict: 'A',
- link: function (scope, element, attrs) {
- const $content = element.find('[tab-content]');
- const $buttons = element.find('[tab-button]');
-
- if (attrs.tabContainer) {
- let initial = attrs.tabContainer;
- $buttons.filter(`[tab-button="${initial}"]`).addClass('selected');
- $content.hide().filter(`[tab-content="${initial}"]`).show();
- } else {
- $content.hide().first().show();
- $buttons.first().addClass('selected');
- }
-
- $buttons.click(function() {
- let clickedTab = $(this);
- $buttons.removeClass('selected');
- $content.hide();
- let name = clickedTab.addClass('selected').attr('tab-button');
- $content.filter(`[tab-content="${name}"]`).show();
- });
- }
- };
- });
-
- /**
- * Sub form component to allow inner-form sections to act like their own forms.
- */
- ngApp.directive('subForm', function() {
- return {
- restrict: 'A',
- link: function (scope, element, attrs) {
- element.on('keypress', e => {
- if (e.keyCode === 13) {
- submitEvent(e);
- }
- });
-
- element.find('button[type="submit"]').click(submitEvent);
-
- function submitEvent(e) {
- e.preventDefault();
- if (attrs.subForm) scope.$eval(attrs.subForm);
- }
- }
- };
- });
-
- /**
- * DropZone
- * Used for uploading images
- */
- ngApp.directive('dropZone', [function () {
- return {
- restrict: 'E',
- template: `
- <div class="dropzone-container">
- <div class="dz-message">{{message}}</div>
- </div>
- `,
- scope: {
- uploadUrl: '@',
- eventSuccess: '=',
- eventError: '=',
- uploadedTo: '@',
- },
- link: function (scope, element, attrs) {
- scope.message = attrs.message;
- if (attrs.placeholder) element[0].querySelector('.dz-message').textContent = attrs.placeholder;
- let dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
- url: scope.uploadUrl,
- init: function () {
- let dz = this;
- dz.on('sending', function (file, xhr, data) {
- let token = window.document.querySelector('meta[name=token]').getAttribute('content');
- data.append('_token', token);
- let uploadedTo = typeof scope.uploadedTo === 'undefined' ? 0 : scope.uploadedTo;
- data.append('uploaded_to', uploadedTo);
- });
- if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
- dz.on('success', function (file, data) {
- $(file.previewElement).fadeOut(400, function () {
- dz.removeFile(file);
- });
- });
- if (typeof scope.eventError !== 'undefined') dz.on('error', scope.eventError);
- dz.on('error', function (file, errorMessage, xhr) {
- console.log(errorMessage);
- console.log(xhr);
- function setMessage(message) {
- $(file.previewElement).find('[data-dz-errormessage]').text(message);
- }
-
- if (xhr.status === 413) setMessage(trans('errors.server_upload_limit'));
- if (errorMessage.file) setMessage(errorMessage.file[0]);
-
- });
- }
- });
- }
- };
- }]);
-
/**
* TinyMCE
* An angular wrapper around the tinyMCE editor.
return basePath + '/' + path;
};
+// Global Event System
+class EventManager {
+ constructor() {
+ this.listeners = {};
+ }
+
+ emit(eventName, eventData) {
+ if (typeof this.listeners[eventName] === 'undefined') return this;
+ let eventsToStart = this.listeners[eventName];
+ for (let i = 0; i < eventsToStart.length; i++) {
+ let event = eventsToStart[i];
+ event(eventData);
+ }
+ return this;
+ }
+
+ listen(eventName, callback) {
+ if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
+ this.listeners[eventName].push(callback);
+ return this;
+ }
+}
+
+window.Events = new EventManager();
+
const Vue = require("vue");
const axios = require("axios");
'baseURL': window.baseUrl('')
}
});
+axiosInstance.interceptors.request.use(resp => {
+ return resp;
+}, err => {
+ if (typeof err.response === "undefined" || typeof err.response.data === "undefined") return Promise.reject(err);
+ if (typeof err.response.data.error !== "undefined") window.Events.emit('error', err.response.data.error);
+ if (typeof err.response.data.message !== "undefined") window.Events.emit('error', err.response.data.message);
+});
window.$http = axiosInstance;
+
Vue.prototype.$http = axiosInstance;
+Vue.prototype.$events = window.Events;
// AngularJS - Create application and load components
let translator = new Translations(window.translations);
window.trans = translator.get.bind(translator);
-// Global Event System
-class EventManager {
- constructor() {
- this.listeners = {};
- }
-
- emit(eventName, eventData) {
- if (typeof this.listeners[eventName] === 'undefined') return this;
- let eventsToStart = this.listeners[eventName];
- for (let i = 0; i < eventsToStart.length; i++) {
- let event = eventsToStart[i];
- event(eventData);
- }
- return this;
- }
-
- listen(eventName, callback) {
- if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
- this.listeners[eventName].push(callback);
- return this;
- }
-}
-
-window.Events = new EventManager();
-Vue.prototype.$events = window.Events;
require("./vues/vues");
require("./components");
--- /dev/null
+const draggable = require('vuedraggable');
+const dropzone = require('./components/dropzone');
+
+function mounted() {
+ this.pageId = this.$el.getAttribute('page-id');
+ this.file = this.newFile();
+
+ this.$http.get(window.baseUrl(`/attachments/get/page/${this.pageId}`)).then(resp => {
+ this.files = resp.data;
+ }).catch(err => {
+ this.checkValidationErrors('get', err);
+ });
+}
+
+let data = {
+ pageId: null,
+ files: [],
+ fileToEdit: null,
+ file: {},
+ tab: 'list',
+ editTab: 'file',
+ errors: {link: {}, edit: {}, delete: {}}
+};
+
+const components = {dropzone, draggable};
+
+let methods = {
+
+ newFile() {
+ return {page_id: this.pageId};
+ },
+
+ getFileUrl(file) {
+ return window.baseUrl(`/attachments/${file.id}`);
+ },
+
+ fileSortUpdate() {
+ this.$http.put(window.baseUrl(`/attachments/sort/page/${this.pageId}`), {files: this.files}).then(resp => {
+ this.$events.emit('success', resp.data.message);
+ }).catch(err => {
+ this.checkValidationErrors('sort', err);
+ });
+ },
+
+ startEdit(file) {
+ this.fileToEdit = Object.assign({}, file);
+ this.fileToEdit.link = file.external ? file.path : '';
+ this.editTab = file.external ? 'link' : 'file';
+ },
+
+ deleteFile(file) {
+ if (!file.deleting) return file.deleting = true;
+
+ this.$http.delete(window.baseUrl(`/attachments/${file.id}`)).then(resp => {
+ this.$events.emit('success', resp.data.message);
+ this.files.splice(this.files.indexOf(file), 1);
+ }).catch(err => {
+ this.checkValidationErrors('delete', err)
+ });
+ },
+
+ uploadSuccess(upload) {
+ this.files.push(upload.data);
+ this.$events.emit('success', trans('entities.attachments_file_uploaded'));
+ },
+
+ uploadSuccessUpdate(upload) {
+ let fileIndex = this.filesIndex(upload.data);
+ if (fileIndex === -1) {
+ this.files.push(upload.data)
+ } else {
+ this.files.splice(fileIndex, 1, upload.data);
+ }
+
+ if (this.fileToEdit && this.fileToEdit.id === upload.data.id) {
+ this.fileToEdit = Object.assign({}, upload.data);
+ }
+ this.$events.emit('success', trans('entities.attachments_file_updated'));
+ },
+
+ checkValidationErrors(groupName, err) {
+ console.error(err);
+ if (typeof err.response.data === "undefined" && typeof err.response.data.validation === "undefined") return;
+ this.errors[groupName] = err.response.data.validation;
+ console.log(this.errors[groupName]);
+ },
+
+ getUploadUrl(file) {
+ let url = window.baseUrl(`/attachments/upload`);
+ if (typeof file !== 'undefined') url += `/${file.id}`;
+ return url;
+ },
+
+ cancelEdit() {
+ this.fileToEdit = null;
+ },
+
+ attachNewLink(file) {
+ file.uploaded_to = this.pageId;
+ this.$http.post(window.baseUrl('/attachments/link'), file).then(resp => {
+ this.files.push(resp.data);
+ this.file = this.newFile();
+ this.$events.emit('success', trans('entities.attachments_link_attached'));
+ }).catch(err => {
+ this.checkValidationErrors('link', err);
+ });
+ },
+
+ updateFile(file) {
+ $http.put(window.baseUrl(`/attachments/${file.id}`), file).then(resp => {
+ let search = this.filesIndex(resp.data);
+ if (search === -1) {
+ this.files.push(resp.data);
+ } else {
+ this.files.splice(search, 1, resp.data);
+ }
+
+ if (this.fileToEdit && !file.external) this.fileToEdit.link = '';
+ this.fileToEdit = false;
+
+ this.$events.emit('success', trans('entities.attachments_updated_success'));
+ }).catch(err => {
+ this.checkValidationErrors('edit', err);
+ });
+ },
+
+ filesIndex(file) {
+ for (let i = 0, len = this.files.length; i < len; i++) {
+ if (this.files[i].id === file.id) return i;
+ }
+ return -1;
+ }
+
+};
+
+module.exports = {
+ data, methods, mounted, components,
+};
\ No newline at end of file
message += errors[key].join('\n');
});
this.$events.emit('error', message);
- } else if (error.response.status === 403) {
- this.$events.emit('error', error.response.data.error);
}
});
},
}).catch(error=> {
if (error.response.status === 400) {
this.dependantPages = error.response.data;
- } else if (error.response.status === 403) {
- this.$events.emit('error', error.response.data.error);
}
});
},
'code-editor': require('./code-editor'),
'image-manager': require('./image-manager'),
'tag-manager': require('./tag-manager'),
+ 'attachment-manager': require('./attachment-manager'),
};
window.vues = {};
-Object.keys(vueMapping).forEach(id => {
- if (exists(id)) {
- let config = vueMapping[id];
- config.el = '#' + id;
- window.vues[id] = new Vue(config);
- }
-});
\ No newline at end of file
+let ids = Object.keys(vueMapping);
+for (let i = 0, len = ids.length; i < len; i++) {
+ if (!exists(ids[i])) continue;
+ let config = vueMapping[ids[i]];
+ config.el = '#' + ids[i];
+ window.vues[ids[i]] = new Vue(config);
+}
\ No newline at end of file
}
-[tab-container] .nav-tabs {
+.tab-container .nav-tabs {
text-align: left;
border-bottom: 1px solid #DDD;
margin-bottom: $-m;
}
}
-table.file-table {
- @extend .no-style;
- td {
- padding: $-xs;
- }
- .ui-sortable-helper {
- display: table;
- }
-}
-
.fake-table {
display: table;
+ width: 100%;
> div {
display: table-row-group;
}
<div class="padded tags">
<p class="muted small">{!! nl2br(e(trans('entities.tags_explain'))) !!}</p>
- <draggable class="fake-table no-style tag-table" :options="{handle: '.handle'}" :list="tags" element="div" style="width: 100%;">
- <transition-group name="test" tag="div">
+ <draggable class="fake-table no-style tag-table" :options="{handle: '.handle'}" :list="tags" element="div">
+ <transition-group tag="div">
<div v-for="(tag, i) in tags" :key="tag.key">
<div width="20" class="handle" ><i class="zmdi zmdi-menu"></i></div>
<div>
</div>
@if(userCan('attachment-create-all'))
- <div toolbox-tab-content="files" ng-controller="PageAttachmentController" page-id="{{ $page->id or 0 }}">
+ <div toolbox-tab-content="files" id="attachment-manager" page-id="{{ $page->id or 0 }}">
<h4>{{ trans('entities.attachments') }}</h4>
<div class="padded files">
- <div id="file-list" ng-show="!editFile">
+ <div id="file-list" v-show="!fileToEdit">
<p class="muted small">{{ trans('entities.attachments_explain') }} <span class="secondary">{{ trans('entities.attachments_explain_instant_save') }}</span></p>
- <div tab-container>
+ <div class="tab-container">
<div class="nav-tabs">
- <div tab-button="list" class="tab-item">{{ trans('entities.attachments_items') }}</div>
- <div tab-button="file" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
- <div tab-button="link" class="tab-item">{{ trans('entities.attachments_link') }}</div>
+ <div @click="tab = 'list'" :class="{selected: tab === 'list'}" class="tab-item">{{ trans('entities.attachments_items') }}</div>
+ <div @click="tab = 'file'" :class="{selected: tab === 'file'}" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
+ <div @click="tab = 'link'" :class="{selected: tab === 'link'}" class="tab-item">{{ trans('entities.attachments_link') }}</div>
</div>
- <div tab-content="list">
- <table class="file-table" style="width: 100%;">
- <tbody ui-sortable="sortOptions" ng-model="files" >
- <tr ng-repeat="file in files track by $index">
- <td width="20" ><i class="handle zmdi zmdi-menu"></i></td>
- <td>
- <a ng-href="@{{getFileUrl(file)}}" target="_blank" ng-bind="file.name"></a>
- <div ng-if="file.deleting">
+ <div v-show="tab === 'list'">
+ <draggable class="fake-table no-style " style="width: 100%;" :options="{handle: '.handle'}" @change="fileSortUpdate" :list="files" element="div">
+ <transition-group tag="div">
+ <div v-for="(file, index) in files" :key="file.id">
+ <div width="20" ><i class="handle zmdi zmdi-menu"></i></div>
+ <div>
+ <a :href="getFileUrl(file)" target="_blank" v-text="file.name"></a>
+ <div v-if="file.deleting">
<span class="neg small">{{ trans('entities.attachments_delete_confirm') }}</span>
<br>
- <span class="text-primary small" ng-click="file.deleting=false;">{{ trans('common.cancel') }}</span>
+ <span class="text-primary small" @click="file.deleting = false;">{{ trans('common.cancel') }}</span>
</div>
- </td>
- <td width="10" ng-click="startEdit(file)" class="text-center text-primary" style="padding: 0;"><i class="zmdi zmdi-edit"></i></td>
- <td width="5"></td>
- <td width="10" ng-click="deleteFile(file)" class="text-center text-neg" style="padding: 0;"><i class="zmdi zmdi-close"></i></td>
- </tr>
- </tbody>
- </table>
- <p class="small muted" ng-if="files.length == 0">
+ </div>
+ <div width="10" @click="startEdit(file)" class="text-center text-primary" style="padding: 0;"><i class="zmdi zmdi-edit"></i></div>
+ <div width="5"></div>
+ <div width="10" @click="deleteFile(file)" class="text-center text-neg" style="padding: 0;"><i class="zmdi zmdi-close"></i></div>
+ </div>
+ </transition-group>
+ </draggable>
+ <p class="small muted" v-if="files.length === 0">
{{ trans('entities.attachments_no_files') }}
</p>
</div>
- <div tab-content="file">
- <drop-zone message="{{ trans('entities.attachments_dropzone') }}" upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
+ <div v-show="tab === 'file'">
+ <dropzone placeholder="{{ trans('entities.attachments_dropzone') }}" :upload-url="getUploadUrl()" :uploaded-to="pageId" @success="uploadSuccess"></dropzone>
</div>
- <div tab-content="link" sub-form="attachLinkSubmit(file)">
+ <div v-show="tab === 'link'" @keypress.enter.prevent="attachNewLink(file)">
<p class="muted small">{{ trans('entities.attachments_explain_link') }}</p>
<div class="form-group">
<label for="attachment-via-link">{{ trans('entities.attachments_link_name') }}</label>
- <input placeholder="{{ trans('entities.attachments_link_name') }}" ng-model="file.name">
- <p class="small neg" ng-repeat="error in errors.link.name" ng-bind="error"></p>
+ <input type="text" placeholder="{{ trans('entities.attachments_link_name') }}" v-model="file.name">
+ <p class="small neg" v-for="error in errors.link.name" v-text="error"></p>
</div>
<div class="form-group">
<label for="attachment-via-link">{{ trans('entities.attachments_link_url') }}</label>
- <input placeholder="{{ trans('entities.attachments_link_url_hint') }}" ng-model="file.link">
- <p class="small neg" ng-repeat="error in errors.link.link" ng-bind="error"></p>
+ <input type="text" placeholder="{{ trans('entities.attachments_link_url_hint') }}" v-model="file.link">
+ <p class="small neg" v-for="error in errors.link.link" v-text="error"></p>
</div>
- <button class="button pos">{{ trans('entities.attach') }}</button>
+ <button @click.prevent="attachNewLink(file)" class="button pos">{{ trans('entities.attach') }}</button>
</div>
</div>
</div>
- <div id="file-edit" ng-if="editFile" sub-form="updateFile(editFile)">
+ <div id="file-edit" v-if="fileToEdit" @keypress.enter.prevent="updateFile(fileToEdit)">
<h5>{{ trans('entities.attachments_edit_file') }}</h5>
<div class="form-group">
<label for="attachment-name-edit">{{ trans('entities.attachments_edit_file_name') }}</label>
- <input type="text" id="attachment-name-edit" placeholder="{{ trans('entities.attachments_edit_file_name') }}" ng-model="editFile.name">
- <p class="small neg" ng-repeat="error in errors.edit.name" ng-bind="error"></p>
+ <input type="text" id="attachment-name-edit" placeholder="{{ trans('entities.attachments_edit_file_name') }}" v-model="fileToEdit.name">
+ <p class="small neg" v-for="error in errors.edit.name" v-text="error"></p>
</div>
- <div tab-container="@{{ editFile.external ? 'link' : 'file' }}">
+ <div class="tab-container">
<div class="nav-tabs">
- <div tab-button="file" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
- <div tab-button="link" class="tab-item">{{ trans('entities.attachments_set_link') }}</div>
+ <div @click="editTab = 'file'" :class="{selected: editTab === 'file'}" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
+ <div @click="editTab = 'link'" :class="{selected: editTab === 'link'}" class="tab-item">{{ trans('entities.attachments_set_link') }}</div>
</div>
- <div tab-content="file">
- <drop-zone upload-url="@{{getUploadUrl(editFile)}}" uploaded-to="@{{uploadedTo}}" placeholder="{{ trans('entities.attachments_edit_drop_upload') }}" event-success="uploadSuccessUpdate"></drop-zone>
+ <div v-if="editTab === 'file'">
+ <dropzone :upload-url="getUploadUrl(fileToEdit)" :uploaded-to="pageId" placeholder="{{ trans('entities.attachments_edit_drop_upload') }}" @success="uploadSuccessUpdate"></dropzone>
<br>
</div>
- <div tab-content="link">
+ <div v-if="editTab === 'link'">
<div class="form-group">
<label for="attachment-link-edit">{{ trans('entities.attachments_link_url') }}</label>
- <input id="attachment-link-edit" placeholder="{{ trans('entities.attachment_link') }}" ng-model="editFile.link">
- <p class="small neg" ng-repeat="error in errors.edit.link" ng-bind="error"></p>
+ <input type="text" id="attachment-link-edit" placeholder="{{ trans('entities.attachment_link') }}" v-model="fileToEdit.link">
+ <p class="small neg" v-for="error in errors.edit.link" v-text="error"></p>
</div>
</div>
</div>
- <button type="button" class="button" ng-click="cancelEdit()">{{ trans('common.back') }}</button>
- <button class="button pos">{{ trans('common.save') }}</button>
+ <button type="button" class="button" @click="cancelEdit">{{ trans('common.back') }}</button>
+ <button @click.enter.prevent="updateFile(fileToEdit)" class="button pos">{{ trans('common.save') }}</button>
</div>
</div>