Skip to content

Commit ecb5b5b

Browse files
authored
Merge pull request #2481 from FAIRsharing/dev
Dev
2 parents 77a2347 + a5aa988 commit ecb5b5b

File tree

12 files changed

+304
-97
lines changed

12 files changed

+304
-97
lines changed

documentation/html/components_Records_Record_RelatedContent.vue.html

+4
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ <h1 class="page-title">Source: components/Records/Record/RelatedContent.vue</h1>
272272
if (_module.currentRecord['fairsharingRecord'].registry === 'Policy') {
273273
_module.$set(_module.tabsData.tabs, 'related_collections', {registry: ["Collection"], data: [], count:0});
274274
}
275+
if (_module.currentRecord['fairsharingRecord'].registry === 'FAIRassist' ||
276+
_module.currentRecord['fairsharingRecord'].registry === 'Standard') {
277+
_module.$set(_module.tabsData.tabs, 'related_fairassist_components', {registry: ["FAIRassist"], data: [], count:0});
278+
}
275279
if (Object.keys(_module.currentRecord['fairsharingRecord']).includes('recordAssociations') ||
276280
Object.keys(_module.currentRecord['fairsharingRecord']).includes('reverseRecordAssociations')) {
277281
Object.keys(_module.tabsData.tabs).forEach(tabName => {

documentation/html/quicksearch.html

+1-1
Large diffs are not rendered by default.

src/components/Editor/EditRelationships.vue

+75-13
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<v-switch
4949
v-model="searchFilters[filterName]"
5050
inset
51-
:label="`${capitalize(filterName)}(s)`"
51+
:label="`${prepareFilterName(filterName)}`"
5252
/>
5353
</v-col>
5454
</v-row>
@@ -188,7 +188,7 @@
188188
<v-switch
189189
v-model="labelsFilter[filterName]"
190190
inset
191-
:label="`${capitalize(filterName)}(s)`"
191+
:label="`${prepareFilterName(filterName)}`"
192192
/>
193193
</v-col>
194194
</v-row>
@@ -425,6 +425,13 @@
425425
>
426426
The same record/relation combination may not be added more than once.
427427
</v-snackbar>
428+
<v-snackbar
429+
v-model="multipleRelationship"
430+
color="warning"
431+
class="text-body"
432+
>
433+
{{ multipleRelationshipMessage }}
434+
</v-snackbar>
428435
</v-card>
429436
</template>
430437

@@ -462,11 +469,20 @@
462469
initialized: false,
463470
lastQuery: null,
464471
duplicateRelationship: false,
465-
recordsList: []
472+
multipleRelationship: false,
473+
multipleRelationshipMessage: null,
474+
recordsList: [],
475+
fairsharingRegistries: [
476+
"collection",
477+
"standard",
478+
"database",
479+
"policy",
480+
"fairassist"
481+
]
466482
}
467483
},
468484
computed: {
469-
...mapState("record", ["sections", "currentID"]),
485+
...mapState("record", ["sections", "currentID", "currentRecord"]),
470486
...mapState("users", ["user"]),
471487
...mapState("editor", ["availableRecords", "relationsTypes"]),
472488
...mapGetters("editor", ["allowedRelations", "allowedTargets"]),
@@ -492,7 +508,8 @@
492508
/* istanbul ignore next */
493509
if ((obj.linkedRecord.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
494510
obj.linkedRecord.abbreviation.toLowerCase().includes(searchTerm.toLowerCase()) )
495-
&& this.labelsFilter[obj.linkedRecord.registry.toLowerCase()] === true){
511+
&& (this.labelsFilter[obj.linkedRecord.registry.toLowerCase()] ||
512+
this.labelsFilter[obj.linkedRecord.type.toLowerCase()]) === true){
496513
return obj;
497514
}
498515
}
@@ -563,10 +580,34 @@
563580
tmpRelation === _module.addingRelation.recordAssocLabel.relation;
564581
565582
});
583+
// Check if a duplicate relation is being added.
566584
if (exists) {
567585
_module.duplicateRelationship = true;
568586
return;
569587
}
588+
// Check if the user is trying to add multiple examples of FAIRassist relations.
589+
// https://github.com/FAIRsharing/FAIRsharing-API/issues/1137
590+
if (_module.currentRecord.fairsharingRecord.type === "metric" || _module.currentRecord.fairsharingRecord.type === "principle") {
591+
let parts_of = _module.sections.relations.data.recordAssociations.filter((item) => {
592+
return item.recordAssocLabel === 'part_of';
593+
})
594+
if (parts_of.length > 0) {
595+
_module.multipleRelationship = true;
596+
_module.multipleRelationshipMessage = "A principle or metric can be part of no more than 1 other of the same type.";
597+
return;
598+
}
599+
}
600+
if (_module.currentRecord.fairsharingRecord.type === "metric") {
601+
let measures = _module.sections.relations.data.recordAssociations.filter((item) => {
602+
return item.recordAssocLabel === 'measures_principle';
603+
})
604+
if (measures.length > 0) {
605+
_module.multipleRelationship = true;
606+
_module.multipleRelationshipMessage = "A metric can only measure one principle.";
607+
return;
608+
}
609+
}
610+
// Finally get to add the new relation.
570611
let newRelation = {
571612
linkedRecord: _module.addingRelation.linkedRecord,
572613
recordAssocLabel: _module.addingRelation.recordAssocLabel,
@@ -606,7 +647,8 @@
606647
registry: target.registry.toLowerCase(),
607648
type: target.type.toLowerCase()
608649
},
609-
sourceType: this.sections.relations.data.registry.toLowerCase(),
650+
sourceRegistry: this.sections.relations.data.registry.toLowerCase(),
651+
sourceType: this.sections.relations.data.type.toLowerCase(),
610652
prohibited: prohibited
611653
});
612654
this.$nextTick(() => {this.$refs['editRecordAssociation'].validate()});
@@ -616,19 +658,24 @@
616658
},
617659
getRelations() {
618660
let labelsFilter = {};
619-
let allRelations = ['standard', 'database', 'collection', 'policy'];
620-
661+
let allRegistries = ['standard', 'database', 'collection', 'policy', 'fairassist'];
662+
let types = [];
621663
let allowedRelations = this.allowedRelations({
622664
target: null,
623-
sourceType: this.sections.relations.data.registry.toLowerCase(),
665+
sourceRegistry: this.sections.relations.data.registry.toLowerCase(),
666+
sourceType: this.sections.relations.data.type.toLowerCase(),
624667
prohibited: null
625668
});
626669
allowedRelations.forEach(allowedRelation => {
627670
if (!Object.keys(labelsFilter).includes(allowedRelation.target)){
628671
/* istanbul ignore else */
629-
if (allRelations.includes(allowedRelation.target.toLowerCase())) {
672+
if (allRegistries.includes(allowedRelation.target.toLowerCase())) {
673+
labelsFilter[allowedRelation.target] = true;
674+
allRegistries.splice(allRegistries.indexOf(allowedRelation.target.toLowerCase()), 1)
675+
}
676+
else { // This must therefore be a record type.
630677
labelsFilter[allowedRelation.target] = true;
631-
allRelations.splice(allRelations.indexOf(allowedRelation.target.toLowerCase()), 1)
678+
types.push(allowedRelation.target);
632679
}
633680
}
634681
});
@@ -643,16 +690,25 @@
643690
search = this.search.trim();
644691
}
645692
let registries = [];
693+
let types = [];
646694
Object.keys(this.searchFilters).forEach(filter => {
647695
if (this.searchFilters[filter]){
648-
registries.push(filter);
696+
// Check if this is a registry or type
697+
if (this.fairsharingRegistries.indexOf(filter) > -1) {
698+
registries.push(filter);
699+
}
700+
else {
701+
types.push(filter);
702+
}
649703
}
650704
});
651705
this.lastQuery = search;
652706
await _module.getAvailableRecords({
653707
q: search,
654708
fairsharingRegistry: registries,
655-
excludeId: _module.currentID
709+
recordType: types,
710+
excludeId: _module.currentID,
711+
searchAnd: false
656712
});
657713
let i = 0;
658714
this.availableRecords.forEach(rec => {
@@ -682,6 +738,12 @@
682738
if (redirect && !this.message.error){
683739
await this.$router.push({path: '/' + this.$route.params.id})
684740
}
741+
},
742+
prepareFilterName(name) {
743+
if (name == 'fairassist') {
744+
return 'FAIRassist'
745+
}
746+
return capitalize(name) + "(s)";
685747
}
686748
}
687749
}

src/components/Editor/GeneralInformation/BaseFields.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@
276276
<v-autocomplete
277277
ref="editRecordType"
278278
v-model="fields.type"
279-
label="Registry type"
279+
label="Registry and type"
280280
:rules="[rules.isRequired()]"
281281
:items="recordTypes"
282282
item-text="name"

src/components/Records/Record/RelatedContent.vue

+4
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ export default {
179179
if (_module.currentRecord['fairsharingRecord'].registry === 'Policy') {
180180
_module.$set(_module.tabsData.tabs, 'related_collections', {registry: ["Collection"], data: [], count:0});
181181
}
182+
if (_module.currentRecord['fairsharingRecord'].registry === 'FAIRassist' ||
183+
_module.currentRecord['fairsharingRecord'].registry === 'Standard') {
184+
_module.$set(_module.tabsData.tabs, 'related_fairassist_components', {registry: ["FAIRassist"], data: [], count:0});
185+
}
182186
if (Object.keys(_module.currentRecord['fairsharingRecord']).includes('recordAssociations') ||
183187
Object.keys(_module.currentRecord['fairsharingRecord']).includes('reverseRecordAssociations')) {
184188
Object.keys(_module.tabsData.tabs).forEach(tabName => {

src/data/RecordRelationShipsDefinitions.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@
99
"shares data with": "This database shares a portion of data with another database",
1010
"shares code with": "This database shares a portion of code with another database",
1111
"accepts": "This database accepts data that follows a particular standard",
12-
"outputs": "This database outputs data that follows a particular standard"
12+
"outputs": "This database outputs data that follows a particular standard",
13+
"measures principle": "Used to show which 'owning' principle any given metric belongs to",
14+
"part of": "Allows composition of metrics within other metrics, or shows what 'parent' principle a principle bleongs to"
1315
}

src/data/jumbotronData.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
},
3030
"collection": {
3131
"title": "Collections",
32-
"subtitle": " Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation. A Recommendation is a core-set of resources that are selected or endorsed by data policies from journals, funders or other organisations. "
32+
"subtitle": " Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation. "
3333
},
3434
"collections": {
3535
"title": "Collections",
36-
"subtitle": " Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation. A Recommendation is a core-set of resources that are selected or endorsed by data policies from journals, funders or other organisations. "
36+
"subtitle": " Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation."
3737
},
3838
"privacy": {
3939
"title": "Privacy policy",

src/data/recordsTypes.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"recordSubTitles": {
33
"Standards": "The standards in FAIRsharing are manually curated from a variety of sources, including BioPortal, MIBBI and the Equator Network.",
4-
"Collections": "Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation. A Recommendation is a core-set of resources that are selected or endorsed by data policies from journals, funders or other organisations.",
4+
"Collections": "Collections group together one or more types of resource (standard, database or policy) by domain, project or organisation.",
55
"Databases": "A catalogue of databases, described according to the BioDBcore guidelines, along with the standards used within them; partly compiled with the support of Oxford University Press (NAR Database Issue and DATABASE Journal).",
66
"Policies": "FAIRsharing policies: A catalogue of data preservation, management and sharing policies from international funding agencies, regulators and journals.",
77
"Search": "Search the FAIRsharing records using advanced filtering"

src/plugins/icons.js

+5
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ const customIcons = {
184184
icon: "/assets/records/benchmark.svg",
185185
tooltip: "Benchmark",
186186
},
187+
principle: {
188+
type: "img",
189+
icon: "/assets/records/principle.svg",
190+
tooltip: "Principle",
191+
},
187192
repository: {
188193
type: "img",
189194
icon: "/assets/records/db-icon.svg",

src/store/editor.js

+27-11
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ let editorStore = {
192192
getRecordsQuery.queryParam = {perPage: 100};
193193
if (options.q) getRecordsQuery.queryParam.q = options.q;
194194
getRecordsQuery.queryParam.fairsharingRegistry = options.fairsharingRegistry;
195+
getRecordsQuery.queryParam.recordType = options.recordType;
195196
getRecordsQuery.queryParam.searchAnd = false;
196197
getRecordsQuery.queryParam.excludeId = options.excludeId;
197198
let data = await graphClient.executeQuery(getRecordsQuery);
@@ -205,10 +206,11 @@ let editorStore = {
205206
async getAvailableRelationsTypes({commit}){
206207
let types = await restClient.getRelationsTypes();
207208
let allowed = {};
208-
let relationTypes = ['standard', 'database', 'policy', 'collection'];
209+
let relationTypes = ['standard', 'database', 'policy', 'collection', 'fairassist'];
209210
for (let typeObject of types) {
210211
let relationName = typeObject.name,
211212
id = typeObject.id;
213+
/* istanbul ignore else */
212214
if (typeObject['allowed_associations'].length > 0) {
213215
typeObject['allowed_associations'].forEach(allowed_association => {
214216
let relationParent = allowed_association.from;
@@ -263,21 +265,35 @@ let editorStore = {
263265
},
264266
allowedRelations: (state) => (options) => {
265267
let output = [];
266-
state.relationsTypes[options.sourceType].forEach(relation => {
267-
if ((options.target && options.prohibited) &&
268-
(relation.target === options.target.registry || relation.target === options.target.type) &&
269-
!options.prohibited.includes(relation.relation)){
270-
output.push(relation)
271-
}
272-
if (!options.target && !options.prohibited){
273-
output.push(relation);
268+
let seen = [];
269+
[options.sourceType, options.sourceRegistry].forEach(type => {
270+
// This undefined check prevents allowed relations from being pushed to the array twice,
271+
// as we're checking for both registry and record type here.
272+
/* istanbul ignore else */
273+
if (state.relationsTypes[type] !== undefined) {
274+
state.relationsTypes[type].forEach(relation => {
275+
if ((options.target && options.prohibited) &&
276+
(relation.target === options.target.registry || relation.target === options.target.type) &&
277+
!options.prohibited.includes(relation.relation)) {
278+
if (!seen.includes(relation.id)) {
279+
output.push(relation)
280+
seen.push(relation.id);
281+
}
282+
}
283+
if (!options.target && !options.prohibited) {
284+
if (!seen.includes(relation.id)) {
285+
output.push(relation);
286+
seen.push(relation.id);
287+
}
288+
}
289+
});
274290
}
275-
});
291+
})
276292
return output;
277293
},
278294
allowedTargets: (state) => (source) => {
279295
let output = [];
280-
let allowed = ["standard", "database", "policy", "collection"];
296+
let allowed = ["standard", "database", "policy", "collection", "fairassist"];
281297
state.relationsTypes[source.toLowerCase()].forEach(relation => {
282298
/* istanbul ignore else */
283299
if (allowed.includes(relation.target)) output.push(relation.target);

0 commit comments

Comments
 (0)