Skip to content

Commit

Permalink
RDISCROWD-7088 Ownership ID v2 (#470)
Browse files Browse the repository at this point in the history
* update ownership_id handling

* error handling

* update test

* lint

* lint
  • Loading branch information
n00rsy authored Oct 10, 2024
1 parent 1ea341c commit 8fe0705
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 29 deletions.
80 changes: 60 additions & 20 deletions static/src/components/setting/ownership_setting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,17 @@ export default {
contactResult: [],
coownerQuery: '',
contactQuery: '',
ownership_id: {},
ownership_id_title: 'Ownership ID',
waiting: false
ownershipId: '',
ownershipIdTitle: 'Ownership ID',
waiting: false,
projectId: ''
};
},
created () {
this.getData();
this.getOwnershipIdTitle();
this.getProjectId();
},
methods: {
Expand All @@ -221,13 +224,35 @@ export default {
return users;
},
getURL (keyword) {
getCoownersURL () {
let path = window.location.pathname;
let res = path.split('/');
res[res.length - 1] = keyword;
res[res.length - 1] = 'coowners';
return res.join('/');
},
getProjectApiURL () {
return `/api/project/${this.projectId}`;
},
getOwnershipIdTitle () {
let element = document.getElementById('ownership-id-title');
if (element == null) {
window.pybossaNotify('An error occurred.', true, 'error');
return;
}
this.ownershipIdTitle = element.innerText;
},
getProjectId () {
let element = document.getElementById('project-id');
if (element == null) {
window.pybossaNotify('An error occurred.', true, 'error');
return;
}
this.projectId = element.innerText;
},
async search (user, contact) {
// Reset and hide drop-downs with search results.
this.coownerResult = [];
Expand All @@ -237,8 +262,7 @@ export default {
} else {
this.contactQuery = null;
}
const res = await fetch(this.getURL('coowners'), {
const res = await fetch(this.getCoownersURL(), {
method: 'POST',
headers: {
'content-type': 'application/json',
Expand All @@ -258,7 +282,7 @@ export default {
async getData () {
this.waiting = true;
try {
const res = await fetch(this.getURL('coowners'), {
const res = await fetch(this.getCoownersURL(), {
method: 'GET',
headers: {
'content-type': 'application/json'
Expand All @@ -271,16 +295,15 @@ export default {
window.pybossaNotify('An error occurred.', true, 'error');
}
try {
const res = await fetch(this.getURL('ownership_id'), {
const res = await fetch(this.getProjectApiURL(), {
method: 'GET',
headers: {
'content-type': 'application/json'
},
credentials: 'same-origin'
});
const data = await res.json();
this.ownership_id = data.ownership_id;
this.ownership_id_title = data.title;
this.ownershipId = data.info.ownership_id == null ? '' : data.info.ownership_id;
} catch (error) {
window.pybossaNotify('An error occurred.', true, 'error');
} finally {
Expand All @@ -306,6 +329,12 @@ export default {
Vue.delete(this.contacts, id);
},
validateOwnershipId () {
let reg = new RegExp('^[0-9]+$');
return this.ownershipId.length === 0 ||
(reg.test(this.ownershipId) && this.ownershipId.length <= 20);
},
async searchCoowners () {
try {
if (this.coownerQuery) {
Expand All @@ -331,6 +360,11 @@ export default {
},
async save () {
if (!this.validateOwnershipId()) {
window.pybossaNotify(`${this.ownershipIdTitle} must be numeric and less than 20 characters!`, true, 'error');
return;
}
const coowners = Object.keys(this.coowners);
const contacts = Object.keys(this.contacts);
// Reset and hide drop-downs with search results.
Expand All @@ -339,9 +373,8 @@ export default {
this.coownerQuery = null;
this.contactQuery = null;
this.waiting = true;
try {
const res = await fetch(this.getURL('coowners'), {
const res = await fetch(this.getCoownersURL(), {
method: 'POST',
headers: {
'content-type': 'application/json',
Expand All @@ -365,19 +398,23 @@ export default {
window.pybossaNotify('An error occurred configuring ownership config.', true, 'error');
}
try {
const res = await fetch(this.getURL('ownership_id'), {
let body = {
'info': {
'ownership_id': this.ownershipId
}
};
const res = await fetch(this.getProjectApiURL(), {
method: 'PUT',
headers: {
'content-type': 'application/json',
'X-CSRFToken': this.csrfToken
},
credentials: 'same-origin',
body: JSON.stringify({ ownership_id: this.ownership_id })
body: JSON.stringify(body)
});
if (res.ok) {
const data = await res.json();
this.ownership_id = data.ownership_id;
window.pybossaNotify(data['flash'], true, data['status']);
this.ownershipId = data.info.ownership_id;
} else {
window.pybossaNotify('An error occurred configuring ownership id.', true, 'error');
}
Expand All @@ -396,14 +433,17 @@ export default {
font-size: 100%;
margin-right: 10px
}
.fa-times {
margin-left:3px;
color:silver
margin-left: 3px;
color: silver
}
.fa-times:hover {
color: red
}
.form-control.input-sm {
width: 280px;
width: 280px;
}
</style>
18 changes: 9 additions & 9 deletions static/src/test/components/setting/ownship_setting.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('ownershipConfig', () => {
const wrapper = shallowMount(ownershipConfig);
await localVue.nextTick();
expect(fetch.mock.calls).toHaveLength(2);
expect(notify.mock.calls).toHaveLength(0);
expect(notify.mock.calls).toHaveLength(2);
expect(wrapper.vm._data.owner.id).toBe(1);
expect(Object.keys(wrapper.vm._data.coowners)).toHaveLength(1);
expect(Object.keys(wrapper.vm._data.contacts)).toHaveLength(1);
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('ownershipConfig', () => {
searchButton.trigger('click');
await localVue.nextTick();
expect(wrapper.findAll('p')).toHaveLength(9); // valid search results
expect(notify.mock.calls).toHaveLength(0); // no error alert
expect(notify.mock.calls).toHaveLength(2); // no error alert
});

it('search users invalid', async () => {
Expand All @@ -97,8 +97,8 @@ describe('ownershipConfig', () => {
const searchButton = wrapper.findAll('button').at(0); // Search users button
searchButton.trigger('click');
await localVue.nextTick();
expect(notify.mock.calls).toHaveLength(2); // no search results
expect(notify.mock.calls[0][0]).toEqual('Please enter a search query.'); // error alert
expect(notify.mock.calls).toHaveLength(4); // no search results
expect(notify.mock.calls[2][0]).toEqual('Please enter a search query.'); // error alert
});

it('search contacts', async () => {
Expand Down Expand Up @@ -129,7 +129,7 @@ describe('ownershipConfig', () => {
searchButton.trigger('click');
await localVue.nextTick();
expect(wrapper.findAll('p')).toHaveLength(9); // valid search results
expect(notify.mock.calls).toHaveLength(0); // no error alert
expect(notify.mock.calls).toHaveLength(2); // no error alert
});

it('search contacts invalid', async () => {
Expand All @@ -145,8 +145,8 @@ describe('ownershipConfig', () => {
const searchButton = wrapper.findAll('button').at(1); // Search contacts button
searchButton.trigger('click');
await localVue.nextTick();
expect(notify.mock.calls).toHaveLength(2); // no search results
expect(notify.mock.calls[0][0]).toEqual('Please enter a search query.'); // error alert
expect(notify.mock.calls).toHaveLength(4); // no search results
expect(notify.mock.calls[2][0]).toEqual('Please enter a search query.'); // error alert
});

it('add coowners', async () => {
Expand Down Expand Up @@ -226,7 +226,7 @@ describe('ownershipConfig', () => {
saveButton.trigger('click');
await localVue.nextTick();
expect(fetch.mock.calls).toHaveLength(4);
expect(notify.mock.calls).toHaveLength(4);
expect(notify.mock.calls).toHaveLength(6);
});

it('saves config fails', async () => {
Expand All @@ -242,6 +242,6 @@ describe('ownershipConfig', () => {
saveButton.trigger('click');
await localVue.nextTick();
expect(fetch.mock.calls).toHaveLength(4);
expect(notify.mock.calls).toHaveLength(4);
expect(notify.mock.calls).toHaveLength(6);
});
});
3 changes: 3 additions & 0 deletions templates/projects/summary.webpack.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
</ul>
<br>

<div id = "ownership-id-title" style="display: none;">{{config.OWNERSHIP_ID_TITLE}}</div>
<div id = "project-id" style="display: none;">{{project.id}}</div>

<div id="setting" class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="project">
<div class="col-md-12">
Expand Down

0 comments on commit 8fe0705

Please sign in to comment.