Update vue-resource
This commit is contained in:
parent
fd692d1066
commit
aaa78199c2
28 changed files with 328 additions and 171 deletions
|
@ -51,8 +51,9 @@ export default () => {
|
||||||
methods: {
|
methods: {
|
||||||
loadFile() {
|
loadFile() {
|
||||||
this.$http.get(el.dataset.endpoint)
|
this.$http.get(el.dataset.endpoint)
|
||||||
|
.then(response => response.json())
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.json = res.json();
|
this.json = res;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
|
|
|
@ -81,8 +81,9 @@ $(() => {
|
||||||
mounted () {
|
mounted () {
|
||||||
Store.disabled = this.disabled;
|
Store.disabled = this.disabled;
|
||||||
gl.boardService.all()
|
gl.boardService.all()
|
||||||
|
.then(response => response.json())
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
resp.json().forEach((board) => {
|
resp.forEach((board) => {
|
||||||
const list = Store.addList(board, this.defaultAvatar);
|
const list = Store.addList(board, this.defaultAvatar);
|
||||||
|
|
||||||
if (list.type === 'closed') {
|
if (list.type === 'closed') {
|
||||||
|
@ -97,7 +98,8 @@ $(() => {
|
||||||
|
|
||||||
Store.addBlankState();
|
Store.addBlankState();
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}).catch(() => new Flash('An error occurred. Please try again.'));
|
})
|
||||||
|
.catch(() => new Flash('An error occurred. Please try again.'));
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateTokens() {
|
updateTokens() {
|
||||||
|
|
|
@ -64,8 +64,9 @@ export default {
|
||||||
|
|
||||||
// Save the labels
|
// Save the labels
|
||||||
gl.boardService.generateDefaultLists()
|
gl.boardService.generateDefaultLists()
|
||||||
.then((resp) => {
|
.then(resp => resp.json())
|
||||||
resp.json().forEach((listObj) => {
|
.then((data) => {
|
||||||
|
data.forEach((listObj) => {
|
||||||
const list = Store.findList('title', listObj.title);
|
const list = Store.findList('title', listObj.title);
|
||||||
|
|
||||||
list.id = listObj.id;
|
list.id = listObj.id;
|
||||||
|
|
|
@ -88,9 +88,9 @@ gl.issueBoards.IssuesModal = Vue.extend({
|
||||||
return gl.boardService.getBacklog(queryData(this.filter.path, {
|
return gl.boardService.getBacklog(queryData(this.filter.path, {
|
||||||
page: this.page,
|
page: this.page,
|
||||||
per: this.perPage,
|
per: this.perPage,
|
||||||
})).then((res) => {
|
}))
|
||||||
const data = res.json();
|
.then(resp => resp.json())
|
||||||
|
.then((data) => {
|
||||||
if (clearIssues) {
|
if (clearIssues) {
|
||||||
this.issues = [];
|
this.issues = [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,8 @@ class List {
|
||||||
|
|
||||||
save () {
|
save () {
|
||||||
return gl.boardService.createList(this.label.id)
|
return gl.boardService.createList(this.label.id)
|
||||||
.then((resp) => {
|
.then(resp => resp.json())
|
||||||
const data = resp.json();
|
.then((data) => {
|
||||||
|
|
||||||
this.id = data.id;
|
this.id = data.id;
|
||||||
this.type = data.list_type;
|
this.type = data.list_type;
|
||||||
this.position = data.position;
|
this.position = data.position;
|
||||||
|
@ -91,8 +90,8 @@ class List {
|
||||||
}
|
}
|
||||||
|
|
||||||
return gl.boardService.getIssuesForList(this.id, data)
|
return gl.boardService.getIssuesForList(this.id, data)
|
||||||
.then((resp) => {
|
.then(resp => resp.json())
|
||||||
const data = resp.json();
|
.then((data) => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.issuesSize = data.size;
|
this.issuesSize = data.size;
|
||||||
|
|
||||||
|
@ -109,8 +108,8 @@ class List {
|
||||||
this.issuesSize += 1;
|
this.issuesSize += 1;
|
||||||
|
|
||||||
return gl.boardService.newIssue(this.id, issue)
|
return gl.boardService.newIssue(this.id, issue)
|
||||||
.then((resp) => {
|
.then(resp => resp.json())
|
||||||
const data = resp.json();
|
.then((data) => {
|
||||||
issue.id = data.iid;
|
issue.id = data.iid;
|
||||||
|
|
||||||
if (this.issuesSize > 1) {
|
if (this.issuesSize > 1) {
|
||||||
|
|
|
@ -23,11 +23,6 @@ class BoardService {
|
||||||
url: bulkUpdatePath,
|
url: bulkUpdatePath,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.http.interceptors.push((request, next) => {
|
|
||||||
request.headers['X-CSRF-Token'] = $.rails.csrfToken();
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
all () {
|
all () {
|
||||||
|
|
|
@ -51,11 +51,11 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
successCallback(resp) {
|
successCallback(resp) {
|
||||||
const response = resp.json();
|
return resp.json().then((response) => {
|
||||||
|
// depending of the endpoint the response can either bring a `pipelines` key or not.
|
||||||
// depending of the endpoint the response can either bring a `pipelines` key or not.
|
const pipelines = response.pipelines || response;
|
||||||
const pipelines = response.pipelines || response;
|
this.setCommonData(pipelines);
|
||||||
this.setCommonData(pipelines);
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, no-new, max-len */
|
/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, max-len */
|
||||||
/* global CommentsStore */
|
/* global CommentsStore */
|
||||||
/* global ResolveService */
|
/* global ResolveService */
|
||||||
/* global Flash */
|
/* global Flash */
|
||||||
|
@ -64,8 +64,6 @@ const ResolveBtn = Vue.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
resolve: function () {
|
resolve: function () {
|
||||||
const errorFlashMsg = 'An error occurred when trying to resolve a comment. Please try again.';
|
|
||||||
|
|
||||||
if (!this.canResolve) return;
|
if (!this.canResolve) return;
|
||||||
|
|
||||||
let promise;
|
let promise;
|
||||||
|
@ -79,24 +77,20 @@ const ResolveBtn = Vue.extend({
|
||||||
.resolve(this.noteId);
|
.resolve(this.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.then((response) => {
|
promise
|
||||||
this.loading = false;
|
.then(resp => resp.json())
|
||||||
|
.then((data) => {
|
||||||
|
this.loading = false;
|
||||||
|
|
||||||
if (response.status === 200) {
|
|
||||||
const data = response.json();
|
|
||||||
const resolved_by = data ? data.resolved_by : null;
|
const resolved_by = data ? data.resolved_by : null;
|
||||||
|
|
||||||
CommentsStore.update(this.discussionId, this.noteId, !this.isResolved, resolved_by);
|
CommentsStore.update(this.discussionId, this.noteId, !this.isResolved, resolved_by);
|
||||||
this.discussion.updateHeadline(data);
|
this.discussion.updateHeadline(data);
|
||||||
gl.mrWidget.checkStatus();
|
gl.mrWidget.checkStatus();
|
||||||
} else {
|
|
||||||
new Flash(errorFlashMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateTooltip();
|
this.updateTooltip();
|
||||||
}).catch(() => {
|
})
|
||||||
new Flash(errorFlashMsg);
|
.catch(() => new Flash('An error occurred when trying to resolve a comment. Please try again.'));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable class-methods-use-this, one-var, camelcase, no-new, comma-dangle, no-param-reassign, max-len */
|
|
||||||
/* global Flash */
|
/* global Flash */
|
||||||
/* global CommentsStore */
|
/* global CommentsStore */
|
||||||
|
|
||||||
|
@ -32,27 +31,22 @@ class ResolveServiceClass {
|
||||||
promise = this.resolveAll(mergeRequestId, discussionId);
|
promise = this.resolveAll(mergeRequestId, discussionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.then((response) => {
|
promise
|
||||||
discussion.loading = false;
|
.then(resp => resp.json())
|
||||||
|
.then((data) => {
|
||||||
if (response.status === 200) {
|
discussion.loading = false;
|
||||||
const data = response.json();
|
const resolvedBy = data ? data.resolved_by : null;
|
||||||
const resolved_by = data ? data.resolved_by : null;
|
|
||||||
|
|
||||||
if (isResolved) {
|
if (isResolved) {
|
||||||
discussion.unResolveAllNotes();
|
discussion.unResolveAllNotes();
|
||||||
} else {
|
} else {
|
||||||
discussion.resolveAllNotes(resolved_by);
|
discussion.resolveAllNotes(resolvedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.mrWidget.checkStatus();
|
gl.mrWidget.checkStatus();
|
||||||
discussion.updateHeadline(data);
|
discussion.updateHeadline(data);
|
||||||
} else {
|
})
|
||||||
throw new Error('An error occurred when trying to resolve discussion.');
|
.catch(() => new Flash('An error occurred when trying to resolve a discussion. Please try again.'));
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
new Flash('An error occurred when trying to resolve a discussion. Please try again.');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveAll(mergeRequestId, discussionId) {
|
resolveAll(mergeRequestId, discussionId) {
|
||||||
|
@ -62,7 +56,7 @@ class ResolveServiceClass {
|
||||||
|
|
||||||
return this.discussionResource.save({
|
return this.discussionResource.save({
|
||||||
mergeRequestId,
|
mergeRequestId,
|
||||||
discussionId
|
discussionId,
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +67,7 @@ class ResolveServiceClass {
|
||||||
|
|
||||||
return this.discussionResource.delete({
|
return this.discussionResource.delete({
|
||||||
mergeRequestId,
|
mergeRequestId,
|
||||||
discussionId
|
discussionId,
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
saveData(resp) {
|
saveData(resp) {
|
||||||
const response = {
|
const headers = resp.headers;
|
||||||
headers: resp.headers,
|
return resp.json().then((response) => {
|
||||||
body: resp.json(),
|
this.isLoading = false;
|
||||||
};
|
|
||||||
|
|
||||||
this.isLoading = false;
|
this.store.storeAvailableCount(response.available_count);
|
||||||
|
this.store.storeStoppedCount(response.stopped_count);
|
||||||
this.store.storeAvailableCount(response.body.available_count);
|
this.store.storeEnvironments(response.environments);
|
||||||
this.store.storeStoppedCount(response.body.stopped_count);
|
this.store.setPagination(headers);
|
||||||
this.store.storeEnvironments(response.body.environments);
|
});
|
||||||
this.store.setPagination(response.headers);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -99,8 +99,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
page: currentPath,
|
page: currentPath,
|
||||||
}, document.title, currentPath);
|
}, document.title, currentPath);
|
||||||
|
|
||||||
this.updateGroups(response.json());
|
return response.json().then((data) => {
|
||||||
this.updatePagination(response.headers);
|
this.updateGroups(data);
|
||||||
|
this.updatePagination(response.headers);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(this.handleErrorResponse);
|
.catch(this.handleErrorResponse);
|
||||||
},
|
},
|
||||||
|
@ -114,18 +116,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
},
|
},
|
||||||
leaveGroup(group, collection) {
|
leaveGroup(group, collection) {
|
||||||
this.service.leaveGroup(group.leavePath)
|
this.service.leaveGroup(group.leavePath)
|
||||||
|
.then(resp => resp.json())
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
$.scrollTo(0);
|
$.scrollTo(0);
|
||||||
|
|
||||||
this.store.removeGroup(group, collection);
|
this.store.removeGroup(group, collection);
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
new Flash(response.json().notice, 'notice');
|
new Flash(response.notice, 'notice');
|
||||||
})
|
})
|
||||||
.catch((response) => {
|
.catch((error) => {
|
||||||
let message = 'An error occurred. Please try again.';
|
let message = 'An error occurred. Please try again.';
|
||||||
|
|
||||||
if (response.status === 403) {
|
if (error.status === 403) {
|
||||||
message = 'Failed to leave the group. Please make sure you are not the only owner';
|
message = 'Failed to leave the group. Please make sure you are not the only owner';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,10 +202,7 @@ export default {
|
||||||
this.poll = new Poll({
|
this.poll = new Poll({
|
||||||
resource: this.service,
|
resource: this.service,
|
||||||
method: 'getData',
|
method: 'getData',
|
||||||
successCallback: (res) => {
|
successCallback: res => res.json().then(data => this.store.updateState(data)),
|
||||||
const data = res.json();
|
|
||||||
this.store.updateState(data);
|
|
||||||
},
|
|
||||||
errorCallback(err) {
|
errorCallback(err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
},
|
},
|
||||||
|
|
|
@ -54,9 +54,8 @@ export default class JobMediator {
|
||||||
}
|
}
|
||||||
|
|
||||||
successCallback(response) {
|
successCallback(response) {
|
||||||
const data = response.json();
|
|
||||||
this.state.isLoading = false;
|
this.state.isLoading = false;
|
||||||
this.store.storeJob(data);
|
return response.json().then(data => this.store.storeJob(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCallback() {
|
errorCallback() {
|
||||||
|
|
|
@ -1270,7 +1270,7 @@ export default class Notes {
|
||||||
<div class="timeline-entry-inner">
|
<div class="timeline-entry-inner">
|
||||||
<div class="timeline-icon">
|
<div class="timeline-icon">
|
||||||
<a href="/${currentUsername}">
|
<a href="/${currentUsername}">
|
||||||
<img class="avatar s40" src="${currentUserAvatar}">
|
<img class="avatar s40" src="${currentUserAvatar}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeline-content ${discussionClass}">
|
<div class="timeline-content ${discussionClass}">
|
||||||
|
|
|
@ -129,14 +129,11 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
successCallback(resp) {
|
successCallback(resp) {
|
||||||
const response = {
|
return resp.json().then((response) => {
|
||||||
headers: resp.headers,
|
this.store.storeCount(response.count);
|
||||||
body: resp.json(),
|
this.store.storePagination(resp.headers);
|
||||||
};
|
this.setCommonData(response.pipelines);
|
||||||
|
});
|
||||||
this.store.storeCount(response.body.count);
|
|
||||||
this.store.storePagination(response.headers);
|
|
||||||
this.setCommonData(response.body.pipelines);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,8 +73,9 @@ export default {
|
||||||
|
|
||||||
fetchJobs() {
|
fetchJobs() {
|
||||||
this.$http.get(this.stage.dropdown_path)
|
this.$http.get(this.stage.dropdown_path)
|
||||||
.then((response) => {
|
.then(response => response.json())
|
||||||
this.dropdownContent = response.json().html;
|
.then((data) => {
|
||||||
|
this.dropdownContent = data.html;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
@ -40,10 +40,10 @@ export default class pipelinesMediator {
|
||||||
}
|
}
|
||||||
|
|
||||||
successCallback(response) {
|
successCallback(response) {
|
||||||
const data = response.json();
|
return response.json().then((data) => {
|
||||||
|
this.state.isLoading = false;
|
||||||
this.state.isLoading = false;
|
this.store.storePipeline(data);
|
||||||
this.store.storePipeline(data);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCallback() {
|
errorCallback() {
|
||||||
|
|
|
@ -28,8 +28,8 @@ export default class SidebarMediator {
|
||||||
|
|
||||||
fetch() {
|
fetch() {
|
||||||
this.service.get()
|
this.service.get()
|
||||||
.then((response) => {
|
.then(response => response.json())
|
||||||
const data = response.json();
|
.then((data) => {
|
||||||
this.store.setAssigneeData(data);
|
this.store.setAssigneeData(data);
|
||||||
this.store.setTimeTrackingData(data);
|
this.store.setTimeTrackingData(data);
|
||||||
})
|
})
|
||||||
|
|
|
@ -44,9 +44,8 @@
|
||||||
text: this.$slots.textarea[0].elm.value,
|
text: this.$slots.textarea[0].elm.value,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then(resp => resp.json())
|
||||||
const data = res.json();
|
.then((data) => {
|
||||||
|
|
||||||
this.markdownPreviewLoading = false;
|
this.markdownPreviewLoading = false;
|
||||||
this.markdownPreview = data.body;
|
this.markdownPreview = data.body;
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,22 @@ Vue.http.interceptors.push((request, next) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inject CSRF token so we don't break any tests.
|
// Inject CSRF token and parse headers.
|
||||||
|
// New Vue Resource version uses Headers, we are expecting a plain object to render pagination
|
||||||
|
// and polling.
|
||||||
Vue.http.interceptors.push((request, next) => {
|
Vue.http.interceptors.push((request, next) => {
|
||||||
if ($.rails) {
|
if ($.rails) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
request.headers.set('X-CSRF-Token', $.rails.csrfToken());
|
||||||
request.headers['X-CSRF-Token'] = $.rails.csrfToken();
|
|
||||||
}
|
}
|
||||||
next();
|
|
||||||
|
next((response) => {
|
||||||
|
// Headers object has a `forEach` property that iterates through all values.
|
||||||
|
const headers = {};
|
||||||
|
|
||||||
|
response.headers.forEach((value, key) => {
|
||||||
|
headers[key] = value;
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
response.headers = headers;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
4
changelogs/unreleased/34534-update-vue-resource.yml
Normal file
4
changelogs/unreleased/34534-update-vue-resource.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Updates vue resource and code according to breaking changes
|
||||||
|
merge_request:
|
||||||
|
author:
|
|
@ -112,7 +112,50 @@ Vue Resource should only be imported in the service file.
|
||||||
Vue.use(VueResource);
|
Vue.use(VueResource);
|
||||||
```
|
```
|
||||||
|
|
||||||
### CSRF token
|
#### Vue-resource gotchas
|
||||||
|
#### Headers
|
||||||
|
Headers are being parsed into a plain object in an interceptor.
|
||||||
|
In Vue-resource 1.x `headers` object was changed into an `Headers` object. In order to not change all old code, an interceptor was added.
|
||||||
|
|
||||||
|
If you need to write a unit test that takes the headers in consideration, you need to include an interceptor to parse the headers after your test interceptor.
|
||||||
|
You can see an example in `spec/javascripts/environments/environment_spec.js`:
|
||||||
|
```javascript
|
||||||
|
import { headersInterceptor } from './helpers/vue_resource_helper';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
Vue.http.interceptors.push(myInterceptor);
|
||||||
|
Vue.http.interceptors.push(headersInterceptor);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, myInterceptor);
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `.json()`
|
||||||
|
When making a request to the server, you will most likely need to access the body of the response.
|
||||||
|
Use `.json()` to convert. Because `.json()` returns a Promise the follwoing structure should be used:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
service.get('url')
|
||||||
|
.then(resp => resp.json())
|
||||||
|
.then((data) => {
|
||||||
|
this.store.storeData(data);
|
||||||
|
})
|
||||||
|
.catch(() => new Flash('Something went wrong'));
|
||||||
|
```
|
||||||
|
|
||||||
|
When using `Poll` (`app/assets/javascripts/lib/utils/poll.js`), the `successCallback` needs to handle `.json()` as a Promise:
|
||||||
|
```javascript
|
||||||
|
successCallback: (response) => {
|
||||||
|
return response.json().then((data) => {
|
||||||
|
// handle the response
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### CSRF token
|
||||||
We use a Vue Resource interceptor to manage the CSRF token.
|
We use a Vue Resource interceptor to manage the CSRF token.
|
||||||
`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
|
`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
|
||||||
Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
|
Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
|
||||||
|
@ -126,13 +169,13 @@ The following example shows an application:
|
||||||
// store.js
|
// store.js
|
||||||
export default class Store {
|
export default class Store {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is where we will iniatialize the state of our data.
|
* This is where we will iniatialize the state of our data.
|
||||||
* Usually in a small SPA you don't need any options when starting the store. In the case you do
|
* Usually in a small SPA you don't need any options when starting the store. In the case you do
|
||||||
* need guarantee it's an Object and it's documented.
|
* need guarantee it's an Object and it's documented.
|
||||||
*
|
*
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
*/
|
*/
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
|
@ -205,14 +248,14 @@ import Store from 'store';
|
||||||
import Service from 'service';
|
import Service from 'service';
|
||||||
import TodoComponent from 'todoComponent';
|
import TodoComponent from 'todoComponent';
|
||||||
export default {
|
export default {
|
||||||
/**
|
/**
|
||||||
* Although most data belongs in the store, each component it's own state.
|
* Although most data belongs in the store, each component it's own state.
|
||||||
* We want to show a loading spinner while we are fetching the todos, this state belong
|
* We want to show a loading spinner while we are fetching the todos, this state belong
|
||||||
* in the component.
|
* in the component.
|
||||||
*
|
*
|
||||||
* We need to access the store methods through all methods of our component.
|
* We need to access the store methods through all methods of our component.
|
||||||
* We need to access the state of our store.
|
* We need to access the state of our store.
|
||||||
*/
|
*/
|
||||||
data() {
|
data() {
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
|
|
||||||
|
@ -396,42 +439,46 @@ need to test the rendered output. [Vue][vue-test] guide's to unit test show us e
|
||||||
[Vue Resource Interceptors][vue-resource-interceptor] allow us to add a interceptor with
|
[Vue Resource Interceptors][vue-resource-interceptor] allow us to add a interceptor with
|
||||||
the response we need:
|
the response we need:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Mock the service to return data
|
// Mock the service to return data
|
||||||
const interceptor = (request, next) => {
|
const interceptor = (request, next) => {
|
||||||
next(request.respondWith(JSON.stringify([{
|
next(request.respondWith(JSON.stringify([{
|
||||||
title: 'This is a todo',
|
title: 'This is a todo',
|
||||||
body: 'This is the text'
|
body: 'This is the text'
|
||||||
}]), {
|
}]), {
|
||||||
status: 200,
|
status: 200,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Vue.http.interceptors.push(interceptor);
|
Vue.http.interceptors.push(interceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
|
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do something', (done) => {
|
it('should do something', (done) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Test received data
|
// Test received data
|
||||||
done();
|
done();
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. Headers interceptor
|
||||||
|
Refer to [this section](vue.md#headers)
|
||||||
|
|
||||||
1. Use `$.mount()` to mount the component
|
1. Use `$.mount()` to mount the component
|
||||||
```javascript
|
|
||||||
// bad
|
|
||||||
new Component({
|
|
||||||
el: document.createElement('div')
|
|
||||||
});
|
|
||||||
|
|
||||||
// good
|
```javascript
|
||||||
new Component().$mount();
|
// bad
|
||||||
|
new Component({
|
||||||
|
el: document.createElement('div')
|
||||||
|
});
|
||||||
|
|
||||||
|
// good
|
||||||
|
new Component().$mount();
|
||||||
```
|
```
|
||||||
|
|
||||||
[vue-docs]: http://vuejs.org/guide/index.html
|
[vue-docs]: http://vuejs.org/guide/index.html
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
"visibilityjs": "^1.2.4",
|
"visibilityjs": "^1.2.4",
|
||||||
"vue": "^2.2.6",
|
"vue": "^2.2.6",
|
||||||
"vue-loader": "^11.3.4",
|
"vue-loader": "^11.3.4",
|
||||||
"vue-resource": "^0.9.3",
|
"vue-resource": "^1.3.4",
|
||||||
"vue-template-compiler": "^2.2.6",
|
"vue-template-compiler": "^2.2.6",
|
||||||
"webpack": "^2.6.1",
|
"webpack": "^2.6.1",
|
||||||
"webpack-bundle-analyzer": "^2.8.2"
|
"webpack-bundle-analyzer": "^2.8.2"
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
||||||
import '~/flash';
|
import '~/flash';
|
||||||
import environmentsComponent from '~/environments/components/environment.vue';
|
import environmentsComponent from '~/environments/components/environment.vue';
|
||||||
import { environment, folder } from './mock_data';
|
import { environment, folder } from './mock_data';
|
||||||
|
import { headersInterceptor } from '../helpers/vue_resource_helper';
|
||||||
|
|
||||||
describe('Environment', () => {
|
describe('Environment', () => {
|
||||||
preloadFixtures('static/environments/environments.html.raw');
|
preloadFixtures('static/environments/environments.html.raw');
|
||||||
|
@ -25,12 +26,14 @@ describe('Environment', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Vue.http.interceptors.push(environmentsEmptyResponseInterceptor);
|
Vue.http.interceptors.push(environmentsEmptyResponseInterceptor);
|
||||||
|
Vue.http.interceptors.push(headersInterceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
Vue.http.interceptors = _.without(
|
Vue.http.interceptors = _.without(
|
||||||
Vue.http.interceptors, environmentsEmptyResponseInterceptor,
|
Vue.http.interceptors, environmentsEmptyResponseInterceptor,
|
||||||
);
|
);
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the empty state', (done) => {
|
it('should render the empty state', (done) => {
|
||||||
|
@ -54,6 +57,10 @@ describe('Environment', () => {
|
||||||
|
|
||||||
describe('with paginated environments', () => {
|
describe('with paginated environments', () => {
|
||||||
const environmentsResponseInterceptor = (request, next) => {
|
const environmentsResponseInterceptor = (request, next) => {
|
||||||
|
next((response) => {
|
||||||
|
response.headers.set('X-nExt-pAge', '2');
|
||||||
|
});
|
||||||
|
|
||||||
next(request.respondWith(JSON.stringify({
|
next(request.respondWith(JSON.stringify({
|
||||||
environments: [environment],
|
environments: [environment],
|
||||||
stopped_count: 1,
|
stopped_count: 1,
|
||||||
|
@ -73,6 +80,7 @@ describe('Environment', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Vue.http.interceptors.push(environmentsResponseInterceptor);
|
Vue.http.interceptors.push(environmentsResponseInterceptor);
|
||||||
|
Vue.http.interceptors.push(headersInterceptor);
|
||||||
component = new EnvironmentsComponent({
|
component = new EnvironmentsComponent({
|
||||||
el: document.querySelector('#environments-list-view'),
|
el: document.querySelector('#environments-list-view'),
|
||||||
});
|
});
|
||||||
|
@ -82,6 +90,7 @@ describe('Environment', () => {
|
||||||
Vue.http.interceptors = _.without(
|
Vue.http.interceptors = _.without(
|
||||||
Vue.http.interceptors, environmentsResponseInterceptor,
|
Vue.http.interceptors, environmentsResponseInterceptor,
|
||||||
);
|
);
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a table with environments', (done) => {
|
it('should render a table with environments', (done) => {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
||||||
import '~/flash';
|
import '~/flash';
|
||||||
import environmentsFolderViewComponent from '~/environments/folder/environments_folder_view.vue';
|
import environmentsFolderViewComponent from '~/environments/folder/environments_folder_view.vue';
|
||||||
import { environmentsList } from '../mock_data';
|
import { environmentsList } from '../mock_data';
|
||||||
|
import { headersInterceptor } from '../../helpers/vue_resource_helper';
|
||||||
|
|
||||||
describe('Environments Folder View', () => {
|
describe('Environments Folder View', () => {
|
||||||
preloadFixtures('static/environments/environments_folder_view.html.raw');
|
preloadFixtures('static/environments/environments_folder_view.html.raw');
|
||||||
|
@ -36,6 +37,8 @@ describe('Environments Folder View', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Vue.http.interceptors.push(environmentsResponseInterceptor);
|
Vue.http.interceptors.push(environmentsResponseInterceptor);
|
||||||
|
Vue.http.interceptors.push(headersInterceptor);
|
||||||
|
|
||||||
component = new EnvironmentsFolderViewComponent({
|
component = new EnvironmentsFolderViewComponent({
|
||||||
el: document.querySelector('#environments-folder-list-view'),
|
el: document.querySelector('#environments-folder-list-view'),
|
||||||
});
|
});
|
||||||
|
@ -45,6 +48,7 @@ describe('Environments Folder View', () => {
|
||||||
Vue.http.interceptors = _.without(
|
Vue.http.interceptors = _.without(
|
||||||
Vue.http.interceptors, environmentsResponseInterceptor,
|
Vue.http.interceptors, environmentsResponseInterceptor,
|
||||||
);
|
);
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a table with environments', (done) => {
|
it('should render a table with environments', (done) => {
|
||||||
|
|
11
spec/javascripts/helpers/vue_resource_helper.js
Normal file
11
spec/javascripts/helpers/vue_resource_helper.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const headersInterceptor = (request, next) => {
|
||||||
|
next((response) => {
|
||||||
|
const headers = {};
|
||||||
|
response.headers.forEach((value, key) => {
|
||||||
|
headers[key] = value;
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
response.headers = headers;
|
||||||
|
});
|
||||||
|
};
|
|
@ -3,7 +3,6 @@ import '~/render_math';
|
||||||
import '~/render_gfm';
|
import '~/render_gfm';
|
||||||
import issuableApp from '~/issue_show/components/app.vue';
|
import issuableApp from '~/issue_show/components/app.vue';
|
||||||
import eventHub from '~/issue_show/event_hub';
|
import eventHub from '~/issue_show/event_hub';
|
||||||
import Poll from '~/lib/utils/poll';
|
|
||||||
import issueShowData from '../mock_data';
|
import issueShowData from '../mock_data';
|
||||||
|
|
||||||
function formatText(text) {
|
function formatText(text) {
|
||||||
|
@ -11,16 +10,26 @@ function formatText(text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Issuable output', () => {
|
describe('Issuable output', () => {
|
||||||
|
let requestData = issueShowData.initialRequest;
|
||||||
|
|
||||||
document.body.innerHTML = '<span id="task_status"></span>';
|
document.body.innerHTML = '<span id="task_status"></span>';
|
||||||
|
|
||||||
|
const interceptor = (request, next) => {
|
||||||
|
next(request.respondWith(JSON.stringify(requestData), {
|
||||||
|
status: 200,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
let vm;
|
let vm;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach((done) => {
|
||||||
spyOn(eventHub, '$emit');
|
spyOn(eventHub, '$emit');
|
||||||
spyOn(Poll.prototype, 'makeRequest');
|
|
||||||
|
|
||||||
const IssuableDescriptionComponent = Vue.extend(issuableApp);
|
const IssuableDescriptionComponent = Vue.extend(issuableApp);
|
||||||
|
|
||||||
|
requestData = issueShowData.initialRequest;
|
||||||
|
Vue.http.interceptors.push(interceptor);
|
||||||
|
|
||||||
vm = new IssuableDescriptionComponent({
|
vm = new IssuableDescriptionComponent({
|
||||||
propsData: {
|
propsData: {
|
||||||
canUpdate: true,
|
canUpdate: true,
|
||||||
|
@ -40,15 +49,17 @@ describe('Issuable output', () => {
|
||||||
projectPath: '/',
|
projectPath: '/',
|
||||||
},
|
},
|
||||||
}).$mount();
|
}).$mount();
|
||||||
|
|
||||||
|
setTimeout(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
|
||||||
|
|
||||||
|
vm.poll.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a title/description/edited and update title/description/edited on update', (done) => {
|
it('should render a title/description/edited and update title/description/edited on update', (done) => {
|
||||||
vm.poll.options.successCallback({
|
|
||||||
json() {
|
|
||||||
return issueShowData.initialRequest;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let editedText;
|
let editedText;
|
||||||
Vue.nextTick()
|
Vue.nextTick()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -64,13 +75,10 @@ describe('Issuable output', () => {
|
||||||
expect(editedText.querySelector('time')).toBeTruthy();
|
expect(editedText.querySelector('time')).toBeTruthy();
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
vm.poll.options.successCallback({
|
requestData = issueShowData.secondRequest;
|
||||||
json() {
|
vm.poll.makeRequest();
|
||||||
return issueShowData.secondRequest;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.then(Vue.nextTick)
|
.then(() => new Promise(resolve => setTimeout(resolve)))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(document.querySelector('title').innerText).toContain('2 (#1)');
|
expect(document.querySelector('title').innerText).toContain('2 (#1)');
|
||||||
expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>');
|
expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>');
|
||||||
|
@ -304,7 +312,7 @@ describe('Issuable output', () => {
|
||||||
|
|
||||||
it('stops polling when deleting', (done) => {
|
it('stops polling when deleting', (done) => {
|
||||||
spyOn(gl.utils, 'visitUrl');
|
spyOn(gl.utils, 'visitUrl');
|
||||||
spyOn(vm.poll, 'stop');
|
spyOn(vm.poll, 'stop').and.callThrough();
|
||||||
spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
|
spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
|
||||||
resolve({
|
resolve({
|
||||||
json() {
|
json() {
|
||||||
|
@ -347,23 +355,14 @@ describe('Issuable output', () => {
|
||||||
|
|
||||||
describe('open form', () => {
|
describe('open form', () => {
|
||||||
it('shows locked warning if form is open & data is different', (done) => {
|
it('shows locked warning if form is open & data is different', (done) => {
|
||||||
vm.poll.options.successCallback({
|
|
||||||
json() {
|
|
||||||
return issueShowData.initialRequest;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.nextTick()
|
Vue.nextTick()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
vm.openForm();
|
vm.openForm();
|
||||||
|
|
||||||
vm.poll.options.successCallback({
|
requestData = issueShowData.secondRequest;
|
||||||
json() {
|
vm.poll.makeRequest();
|
||||||
return issueShowData.secondRequest;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.then(Vue.nextTick)
|
.then(() => new Promise(resolve => setTimeout(resolve)))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(
|
expect(
|
||||||
vm.formState.lockedWarningVisible,
|
vm.formState.lockedWarningVisible,
|
||||||
|
|
102
yarn.lock
102
yarn.lock
|
@ -1575,6 +1575,12 @@ deckar01-task_list@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/deckar01-task_list/-/deckar01-task_list-2.0.0.tgz#7f7a595430d21b3036ed5dfbf97d6b65de18e2c9"
|
resolved "https://registry.yarnpkg.com/deckar01-task_list/-/deckar01-task_list-2.0.0.tgz#7f7a595430d21b3036ed5dfbf97d6b65de18e2c9"
|
||||||
|
|
||||||
|
decompress-response@^3.2.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
|
||||||
|
dependencies:
|
||||||
|
mimic-response "^1.0.0"
|
||||||
|
|
||||||
deep-extend@~0.4.0:
|
deep-extend@~0.4.0:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
|
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
|
||||||
|
@ -1712,6 +1718,10 @@ dropzone@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3"
|
resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3"
|
||||||
|
|
||||||
|
duplexer3@^0.1.4:
|
||||||
|
version "0.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||||
|
|
||||||
duplexer@^0.1.1, duplexer@~0.1.1:
|
duplexer@^0.1.1, duplexer@~0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
|
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
|
||||||
|
@ -2445,6 +2455,10 @@ get-caller-file@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
|
||||||
|
|
||||||
|
get-stream@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||||
|
|
||||||
getpass@^0.1.1:
|
getpass@^0.1.1:
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
|
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
|
||||||
|
@ -2521,6 +2535,25 @@ got@^3.2.0:
|
||||||
read-all-stream "^3.0.0"
|
read-all-stream "^3.0.0"
|
||||||
timed-out "^2.0.0"
|
timed-out "^2.0.0"
|
||||||
|
|
||||||
|
got@^7.0.0:
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
|
||||||
|
dependencies:
|
||||||
|
decompress-response "^3.2.0"
|
||||||
|
duplexer3 "^0.1.4"
|
||||||
|
get-stream "^3.0.0"
|
||||||
|
is-plain-obj "^1.1.0"
|
||||||
|
is-retry-allowed "^1.0.0"
|
||||||
|
is-stream "^1.0.0"
|
||||||
|
isurl "^1.0.0-alpha5"
|
||||||
|
lowercase-keys "^1.0.0"
|
||||||
|
p-cancelable "^0.3.0"
|
||||||
|
p-timeout "^1.1.1"
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
timed-out "^4.0.0"
|
||||||
|
url-parse-lax "^1.0.0"
|
||||||
|
url-to-options "^1.0.1"
|
||||||
|
|
||||||
graceful-fs@^4.1.11, graceful-fs@^4.1.2:
|
graceful-fs@^4.1.11, graceful-fs@^4.1.2:
|
||||||
version "4.1.11"
|
version "4.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||||
|
@ -2578,6 +2611,16 @@ has-flag@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
||||||
|
|
||||||
|
has-symbol-support-x@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.3.0.tgz#588bd6927eaa0e296afae24160659167fc2be4f8"
|
||||||
|
|
||||||
|
has-to-string-tag-x@^1.2.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.3.0.tgz#78e3d98c3c0ec9413e970eb8d766249a1e13058f"
|
||||||
|
dependencies:
|
||||||
|
has-symbol-support-x "^1.3.0"
|
||||||
|
|
||||||
has-unicode@^2.0.0:
|
has-unicode@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||||
|
@ -2902,6 +2945,10 @@ is-number@^2.0.2, is-number@^2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
kind-of "^3.0.2"
|
kind-of "^3.0.2"
|
||||||
|
|
||||||
|
is-object@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
|
||||||
|
|
||||||
is-path-cwd@^1.0.0:
|
is-path-cwd@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||||
|
@ -2918,7 +2965,7 @@ is-path-inside@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-is-inside "^1.0.1"
|
path-is-inside "^1.0.1"
|
||||||
|
|
||||||
is-plain-obj@^1.0.0:
|
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||||
|
|
||||||
|
@ -2950,6 +2997,10 @@ is-resolvable@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tryit "^1.0.1"
|
tryit "^1.0.1"
|
||||||
|
|
||||||
|
is-retry-allowed@^1.0.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
|
||||||
|
|
||||||
is-stream@^1.0.0:
|
is-stream@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||||
|
@ -3087,6 +3138,13 @@ istanbul@^0.4.5:
|
||||||
which "^1.1.1"
|
which "^1.1.1"
|
||||||
wordwrap "^1.0.0"
|
wordwrap "^1.0.0"
|
||||||
|
|
||||||
|
isurl@^1.0.0-alpha5:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
|
||||||
|
dependencies:
|
||||||
|
has-to-string-tag-x "^1.2.0"
|
||||||
|
is-object "^1.0.1"
|
||||||
|
|
||||||
jasmine-core@^2.6.3:
|
jasmine-core@^2.6.3:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.3.tgz#45072950e4a42b1e322fe55c001100a465d77815"
|
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.3.tgz#45072950e4a42b1e322fe55c001100a465d77815"
|
||||||
|
@ -3633,6 +3691,10 @@ mime@1.3.4, mime@1.3.x, mime@^1.3.4:
|
||||||
version "1.3.4"
|
version "1.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
|
||||||
|
|
||||||
|
mimic-response@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
|
||||||
|
|
||||||
minimalistic-assert@^1.0.0:
|
minimalistic-assert@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
|
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
|
||||||
|
@ -3981,6 +4043,14 @@ osenv@^0.1.0:
|
||||||
os-homedir "^1.0.0"
|
os-homedir "^1.0.0"
|
||||||
os-tmpdir "^1.0.0"
|
os-tmpdir "^1.0.0"
|
||||||
|
|
||||||
|
p-cancelable@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
|
||||||
|
|
||||||
|
p-finally@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
||||||
|
|
||||||
p-limit@^1.1.0:
|
p-limit@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
|
||||||
|
@ -3991,6 +4061,12 @@ p-locate@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-limit "^1.1.0"
|
p-limit "^1.1.0"
|
||||||
|
|
||||||
|
p-timeout@^1.1.1:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.0.tgz#9820f99434c5817868b4f34809ee5291660d5b6c"
|
||||||
|
dependencies:
|
||||||
|
p-finally "^1.0.0"
|
||||||
|
|
||||||
package-json@^1.0.0:
|
package-json@^1.0.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0"
|
resolved "https://registry.yarnpkg.com/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0"
|
||||||
|
@ -4419,7 +4495,7 @@ prelude-ls@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
|
|
||||||
prepend-http@^1.0.0:
|
prepend-http@^1.0.0, prepend-http@^1.0.1:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||||
|
|
||||||
|
@ -5384,6 +5460,10 @@ timed-out@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a"
|
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a"
|
||||||
|
|
||||||
|
timed-out@^4.0.0:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
|
||||||
|
|
||||||
timers-browserify@^1.4.2:
|
timers-browserify@^1.4.2:
|
||||||
version "1.4.2"
|
version "1.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
|
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
|
||||||
|
@ -5545,6 +5625,12 @@ url-loader@^0.5.8:
|
||||||
loader-utils "^1.0.2"
|
loader-utils "^1.0.2"
|
||||||
mime "1.3.x"
|
mime "1.3.x"
|
||||||
|
|
||||||
|
url-parse-lax@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
|
||||||
|
dependencies:
|
||||||
|
prepend-http "^1.0.1"
|
||||||
|
|
||||||
url-parse@1.0.x:
|
url-parse@1.0.x:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b"
|
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b"
|
||||||
|
@ -5559,6 +5645,10 @@ url-parse@^1.0.1, url-parse@^1.1.1:
|
||||||
querystringify "0.0.x"
|
querystringify "0.0.x"
|
||||||
requires-port "1.0.x"
|
requires-port "1.0.x"
|
||||||
|
|
||||||
|
url-to-options@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
|
||||||
|
|
||||||
url@^0.11.0:
|
url@^0.11.0:
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||||
|
@ -5657,9 +5747,11 @@ vue-loader@^11.3.4:
|
||||||
vue-style-loader "^2.0.0"
|
vue-style-loader "^2.0.0"
|
||||||
vue-template-es2015-compiler "^1.2.2"
|
vue-template-es2015-compiler "^1.2.2"
|
||||||
|
|
||||||
vue-resource@^0.9.3:
|
vue-resource@^1.3.4:
|
||||||
version "0.9.3"
|
version "1.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-0.9.3.tgz#ab46e1c44ea219142dcc28ae4043b3b04c80959d"
|
resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.4.tgz#9fc0bdf6a2f5cab430129fc99d347b3deae7b099"
|
||||||
|
dependencies:
|
||||||
|
got "^7.0.0"
|
||||||
|
|
||||||
vue-style-loader@^2.0.0:
|
vue-style-loader@^2.0.0:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
|
|
Loading…
Reference in a new issue