Skip to content

Commit

Permalink
Merge pull request #236 from petridishdev/feature/w3c-vc-link
Browse files Browse the repository at this point in the history
feat: add credential link and raw data for w3c credential items
  • Loading branch information
amanji authored Oct 24, 2024
2 parents 6863a9f + fccffa1 commit fcf3664
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 148 deletions.
165 changes: 89 additions & 76 deletions src/components/entity/CredentialItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
<v-col v-if="topicName" cols="12" sm="12" class="pa-0">
<p class="mb-0">{{ topicName }}</p>
</v-col>
<v-col v-if="credTitle" cols="12" sm="12" class="pa-0">
<v-col v-if="getCredentialTitle" cols="12" sm="12" class="pa-0">
<p class="mb-1">
{{ credTitle["key"] }}:
{{ getCredentialTitle["key"] }}:
{{
translateValue(
credTitle["accessor"],
credTitle["value"],
getCredentialTitle["accessor"],
getCredentialTitle["value"],
entityType
)
}}
Expand All @@ -36,10 +36,10 @@
}"
>
<div class="ma-n1 py-1 text-body-2 text--secondary">
<div :class="{ 'pb-3': timeline && !highlightedAttr.length }">
<div :class="{ 'pb-3': timeline && !highlightedAttributes.length }">
<div class="font-weight-bold">Authority</div>
<div>
<a v-if="getAuthorityLink" :href="getAuthorityLink">
<a v-if="getAuthorityLink" :href="authorityLink">
<span>{{ getAuthority }}</span>
<v-icon small class="fake-link">{{ mdiOpenInNew }}</v-icon>
</a>
Expand All @@ -50,7 +50,7 @@
<v-row>
<v-col
class="pl-0"
v-for="(attr, i) in highlightedAttr"
v-for="(attr, i) in highlightedAttributes"
:key="i"
cols="12"
sm="12"
Expand All @@ -63,18 +63,28 @@
</v-row>

<div>
<v-icon small v-if="!getCredRevoked">{{
<v-icon small v-if="!getCredentialRevoked">{{
mdiShieldCheckOutline
}}</v-icon>
<router-link
:to="{
name: 'Credential',
params: { sourceId, type: topicType, credentialId: getCredId },
params: {
sourceId: topicSourceId,
type: topicType,
credentialId: getCredentialId,
},
}"
class="vertical-align-middle"
>Credential<span v-if="!getCredRevoked"> verified</span
><span v-else> claims</span></router-link
>
>Credential<span v-if="!getCredentialRevoked"> verified</span
><span v-else> claims</span>
</router-link>
</div>
<div v-if="credential?.raw_data?.id">
<v-icon small>{{ mdiOpenInNew }}</v-icon>
<a :href="credential?.raw_data.id" class="vertical-align-middle">
Credential link
</a>
</div>
<div v-if="effectiveDate">
<span>Effective:&nbsp;</span>
Expand Down Expand Up @@ -111,14 +121,15 @@ import { isExpired, toTranslationFormat } from "@/utils/entity";
},
})
export default class CredentialItem extends Vue {
@Prop({}) cred!: ICredentialDisplayType;
@Prop({}) credential!: ICredentialDisplayType;
@Prop({ default: "" }) entityType!: string;
@Prop({ default: "" }) authority!: string;
@Prop({ default: "" }) authorityLink!: string;
@Prop({ default: "" }) effectiveDate!: string;
@Prop({ default: "" }) credentialId!: number;
@Prop({ default: false }) expired!: boolean;
@Prop({ default: "" }) credId!: number;
@Prop({ default: false }) revoked!: boolean;
@Prop({ default: false }) disableDefaultHeader!: boolean;
@Prop({ default: false }) timeline!: boolean;
Expand All @@ -131,25 +142,15 @@ export default class CredentialItem extends Vue {
toTranslationFormate = toTranslationFormat;
$translate = $translate;
get getAuthorityLink(): string | URL {
return this.cred ? this.cred.authorityLink : this.authorityLink;
}
get getAuthority(): string {
return this.cred ? this.cred.authority : this.authority;
return this.credential ? this.credential.authority : this.authority;
}
get getCredRevoked(): boolean {
return this.cred
? this.cred.revoked || !!this.isExpired(this.cred.attributes)
: this.expired;
}
get getCredId(): number {
return this.cred ? this.cred.id : this.credId;
get getAuthorityLink(): string | URL {
return this.credential ? this.credential.authorityLink : this.authorityLink;
}
get sourceId(): string {
get topicSourceId(): string {
const { sourceId } = this.$route.params;
return sourceId;
}
Expand All @@ -160,67 +161,46 @@ export default class CredentialItem extends Vue {
}
get topicName(): string | undefined {
if (!this.cred) {
if (!this.credential) {
return undefined;
}
let ret = this.cred.value as string | undefined;
if (this.cred.type !== "entity_name") {
let ret = this.credential.value as string | undefined;
if (this.credential.type !== "entity_name") {
ret = this.selectedTopic.names[0]?.text;
}
return ret;
}
getClaimLabel(
id: number,
claimLabel: string | undefined
): string | undefined {
const credentialType = selectFirstAttrItem(
{ key: "id", value: id },
this.credentialTypes
);
// TODO: Eventually this should be a translation from OCA
if (credentialType?.format === "vc_di") {
return claimLabel;
} else if (credentialType && claimLabel) {
return credentialType?.claim_labels?.[claimLabel]?.[i18n.locale];
}
get getCredentialId(): number {
return this.credential ? this.credential.id : this.credentialId;
}
translateValue(
accessor: string,
val: string,
entityType: string
): string | TranslateResult {
// need entity type to properly translate due to LEAR entries
const res = $translate(
toTranslationFormat(accessor + "." + val, entityType)
);
if (res != toTranslationFormat(accessor + "." + val, entityType)) {
return res;
}
return val;
get getCredentialRevoked(): boolean {
return this.credential
? this.credential.revoked || !!this.isExpired(this.credential.attributes)
: this.expired;
}
get credTitle(): Record<string, string> | undefined {
if (!this.cred) {
get getCredentialTitle(): Record<string, string> | undefined {
if (!this.credential) {
return undefined;
}
let retval: { [index: string]: string | undefined } = {};
const claimLabel = this.getClaimLabel(
this.cred.credential_type_id,
this.cred.credential_title
const claimLabel = this.claimLabelFromId(
this.credential.credential_type_id,
this.credential.credential_title
);
const default_title = this.cred.rel_id
? { "Relationship description": this.cred.rel_id as string }
: { "Registration number": this.sourceId };
const default_title = this.credential.rel_id
? { "Relationship description": this.credential.rel_id as string }
: { "Registration number": this.topicSourceId };
if (claimLabel === undefined) {
retval = default_title;
} else {
let value = selectFirstAttrItem(
{ key: "type", value: this.cred.credential_title },
this.cred.attributes
{ key: "type", value: this.credential.credential_title },
this.credential.attributes
);
if (value?.format === "datetime") {
value.value = value.value as string;
Expand All @@ -232,30 +212,32 @@ export default class CredentialItem extends Vue {
retval = default_title;
}
}
let accessor = this.cred.credential_title ? this.cred.credential_title : "";
let accessor = this.credential.credential_title
? this.credential.credential_title
: "";
return {
key: Object.keys(retval)[0],
value: retval[Object.keys(retval)[0]] as string,
accessor: accessor,
};
}
get highlightedAttr(): Record<string, string>[] | undefined {
if (!this.cred) {
get highlightedAttributes(): Record<string, string>[] | undefined {
if (!this.credential) {
return undefined;
}
let retval: Record<string, string>[] = [];
if (this.cred.highlighted_attributes) {
this.cred.highlighted_attributes.forEach((accessor) => {
const attrLabel = this.getClaimLabel(
this.cred.credential_type_id,
if (this.credential.highlighted_attributes) {
this.credential.highlighted_attributes.forEach((accessor) => {
const attrLabel = this.claimLabelFromId(
this.credential.credential_type_id,
accessor
);
let attrValue = "";
if (attrLabel) {
const match = selectFirstAttrItem(
{ key: "type", value: accessor },
this.cred.attributes
this.credential.attributes
);
if (match?.format === "datetime") {
attrValue = dateFilter(match.value as string) as string;
Expand All @@ -275,6 +257,37 @@ export default class CredentialItem extends Vue {
}
return retval;
}
claimLabelFromId(
id: number,
claimLabel: string | undefined
): string | undefined {
const credentialType = selectFirstAttrItem(
{ key: "id", value: id },
this.credentialTypes
);
// TODO: Eventually this should be a translation from OCA
if (credentialType?.format === "vc_di") {
return claimLabel;
} else if (credentialType && claimLabel) {
return credentialType?.claim_labels?.[claimLabel]?.[i18n.locale];
}
}
translateValue(
accessor: string,
val: string,
entityType: string
): string | TranslateResult {
// need entity type to properly translate due to LEAR entries
const res = $translate(
toTranslationFormat(accessor + "." + val, entityType)
);
if (res != toTranslationFormat(accessor + "." + val, entityType)) {
return res;
}
return val;
}
}
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/components/entity/EntityResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@
>
<template #expansionPanels>
<CredentialItem
:cred="cred"
:credential="cred"
:entityType="entityJurisdiction"
:timeline="true"
>
Expand Down
Loading

0 comments on commit fcf3664

Please sign in to comment.