-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extending a Concept Set with a new tab 'Annotations' (#2971)
* Show metadata tag to show history conceptset * Add function to remove metadata conceptset * Adjust styles action column metadata tab * [ATL-17] Refactored the annotations feature. Renamed metadata to annotation, added vocabulary version and createdBy/createdDate * [ATL-58] Added concept set version to annotations * [ATL-58] Implemented copying of annotations along with ConceptSet * [ATL-58] Transform search data JSON to a human friendly format in annotations tab * Added 'Copied From' list of concept set ids for concept set annotations * Fixed issue with current conceptset ID not propagating correctly into a URL for router to the current active concept set * Annotations delete button (whole Actions column) to be visible only for Admin (user with conceptset:annotation:*:delete permission) * Changed owner/permissions check for annotations delete to consider ownership of the concept set for annotations --------- Co-authored-by: hernaldo.urbina <[email protected]> Co-authored-by: oleg-odysseus <[email protected]> Co-authored-by: Chris Knoll <[email protected]>
- Loading branch information
1 parent
0f4594e
commit 5163a9d
Showing
15 changed files
with
440 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
js/pages/concept-sets/components/tabs/conceptset-annotation.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<loading data-bind="visible: isLoading()" params="status: ko.i18n('components.annotation.loading', 'Loading annotation...')"></loading> | ||
<div data-bind="visible: !isLoading()"> | ||
<faceted-datatable params=" | ||
order: [], | ||
autoWidth: false, | ||
reference: data, | ||
columns: columns, | ||
options: null, | ||
pageLength: pageLength, | ||
lengthMenu: lengthMenu, | ||
rowClick: onRowClick, | ||
language: ko.i18n('datatable.language') | ||
"> | ||
</faceted-datatable> | ||
</div> |
175 changes: 175 additions & 0 deletions
175
js/pages/concept-sets/components/tabs/conceptset-annotation.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
define([ | ||
'knockout', | ||
'text!./conceptset-annotation.html', | ||
'components/Component', | ||
'utils/AutoBind', | ||
'utils/CommonUtils', | ||
'services/AuthAPI', | ||
'faceted-datatable', | ||
'less!./conceptset-annotation.less', | ||
], function ( | ||
ko, | ||
view, | ||
Component, | ||
AutoBind, | ||
commonUtils, | ||
authApi, | ||
) { | ||
class ConceptsetAnnotation extends AutoBind(Component) { | ||
constructor(params) { | ||
super(params); | ||
this.isLoading = ko.observable(true); | ||
this.data = ko.observable(); | ||
this.getList = params.getList; | ||
this.delete = params.delete; | ||
this.canDeleteAnnotations = params.canDeleteAnnotations; | ||
|
||
const { pageLength, lengthMenu } = commonUtils.getTableOptions('M'); | ||
this.pageLength = params.pageLength || pageLength; | ||
this.lengthMenu = params.lengthMenu || lengthMenu; | ||
|
||
this.columns = ko.computed(() => { | ||
let cols = [ | ||
{ | ||
title: ko.i18n('columns.conceptID', 'Concept Id'), | ||
data: 'conceptId', | ||
}, | ||
{ | ||
title: ko.i18n('columns.searchData', 'Search Data'), | ||
className: this.classes('tbl-col', 'search-data'), | ||
render: (d, t, r) => { | ||
if (r.searchData === null || r.searchData === undefined || !r.searchData) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.searchData}</p>` | ||
} | ||
}, | ||
sortable: false | ||
}, | ||
{ | ||
title: ko.i18n('columns.vocabularyVersion', 'Vocabulary Version'), | ||
data: 'vocabularyVersion', | ||
render: (d, t, r) => { | ||
if (r.vocabularyVersion === null || r.vocabularyVersion === undefined || !r.vocabularyVersion) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.vocabularyVersion}</p>` | ||
} | ||
}, | ||
sortable: false | ||
}, | ||
{ | ||
title: ko.i18n('columns.conceptSetVersion', 'Concept Set Version'), | ||
data: 'conceptSetVersion', | ||
render: (d, t, r) => { | ||
if (r.conceptSetVersion === null || r.conceptSetVersion === undefined || !r.conceptSetVersion) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.conceptSetVersion}</p>` | ||
} | ||
}, | ||
sortable: false | ||
}, | ||
{ | ||
title: ko.i18n('columns.createdBy', 'Created By'), | ||
data: 'createdBy', | ||
render: (d, t, r) => { | ||
if (r.createdBy === null || r.createdBy === undefined || !r.createdBy) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.createdBy}</p>` | ||
} | ||
}, | ||
sortable: false | ||
}, | ||
{ | ||
title: ko.i18n('columns.createdDate', 'Created Date'), | ||
render: (d, t, r) => { | ||
if (r.createdDate === null || r.createdDate === undefined) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.createdDate}</p>` | ||
} | ||
}, | ||
sortable: false | ||
}, | ||
{ | ||
title: ko.i18n('columns.originConceptSets', 'Origin Concept Sets'), | ||
render: (d, t, r) => { | ||
if (r.copiedFromConceptSetIds === null || r.copiedFromConceptSetIds === undefined) { | ||
return 'N/A'; | ||
} else { | ||
return `<p>${r.copiedFromConceptSetIds}</p>` | ||
} | ||
}, | ||
sortable: false | ||
} | ||
]; | ||
|
||
if (this.canDeleteAnnotations()) { | ||
cols.push({ | ||
title: ko.i18n('columns.action', 'Action'), | ||
sortable: false, | ||
render: function () { | ||
return `<i class="deleteIcon fa fa-trash" aria-hidden="true"></i>`; | ||
} | ||
}); | ||
} | ||
return cols; | ||
}); | ||
|
||
this.loadData(); | ||
} | ||
|
||
objectMap(obj) { | ||
const newObject = {}; | ||
const keysNotToParse = ['createdBy', 'createdDate', 'vocabularyVersion', 'conceptSetVersion', 'copiedFromConceptSetIds', 'searchData']; | ||
Object.keys(obj).forEach((key) => { | ||
if (typeof obj[key] === 'string' && !keysNotToParse.includes(key)) { | ||
newObject[key] = JSON.parse(obj[key] || null); | ||
} else { | ||
newObject[key] = obj[key]; | ||
} | ||
}); | ||
return newObject; | ||
} | ||
|
||
async onRowClick(d, e){ | ||
try { | ||
const { id } = d; | ||
if(e.target.className === 'deleteIcon fa fa-trash') { | ||
const res = await this.delete(id); | ||
if(res){ | ||
this.loadData(); | ||
} | ||
} | ||
} catch (ex) { | ||
console.log(ex); | ||
} finally { | ||
this.isLoading(false); | ||
} | ||
} | ||
|
||
handleConvertData(arr){ | ||
const newDatas = []; | ||
(arr || []).forEach(item => { | ||
newDatas.push(this.objectMap(item)) | ||
}) | ||
return newDatas; | ||
} | ||
|
||
async loadData() { | ||
this.isLoading(true); | ||
try { | ||
const data = await this.getList(); | ||
this.data(this.handleConvertData(data.data)); | ||
} catch (ex) { | ||
console.log(ex); | ||
} finally { | ||
this.isLoading(false); | ||
} | ||
} | ||
|
||
} | ||
return commonUtils.build('conceptset-annotation', ConceptsetAnnotation, view); | ||
}); |
23 changes: 23 additions & 0 deletions
23
js/pages/concept-sets/components/tabs/conceptset-annotation.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.conceptset-annotation { | ||
|
||
&__tbl-col { | ||
&--search-data { | ||
min-width: 40%; | ||
} | ||
&--concept-data{ | ||
max-width: 500px; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
display: -webkit-box; | ||
-webkit-line-clamp: 3; | ||
-webkit-box-orient: vertical; | ||
overflow: hidden; | ||
} | ||
} | ||
} | ||
|
||
.deleteIcon { | ||
color: #d9534f; | ||
cursor: pointer; | ||
min-width: 30px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.