mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 10:15:35 +01:00
Add co-sign checkbox for project policy (#16184)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
063991078a
commit
634f0139a0
@ -4,27 +4,32 @@
|
||||
<label>{{ 'PROJECT_CONFIG.REGISTRY' | translate }}</label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input type="checkbox" id="clr-checkbox-wrapper-public" clrCheckbox [(ngModel)]="projectPolicy.Public"
|
||||
name="public" [disabled]="!hasChangeConfigRole" />
|
||||
name="public" [disabled]="!hasChangeConfigRole" />
|
||||
<label>{{ 'PROJECT_CONFIG.PUBLIC_TOGGLE' | translate }}</label>
|
||||
</clr-checkbox-wrapper>
|
||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }}
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<clr-checkbox-container *ngIf="withNotary && !isProxyCacheProject">
|
||||
<label><span *ngIf="withNotary && !isProxyCacheProject">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper *ngIf="withNotary && !isProxyCacheProject">
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
||||
[disabled]="!hasChangeConfigRole" />
|
||||
<label>{{ 'PROJECT_CONFIG.CONTENT_TRUST_TOGGLE' | translate }}</label>
|
||||
<clr-checkbox-container *ngIf="!isProxyCacheProject" clrInline>
|
||||
<label><span>{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input id="content-trust-cosign" type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrustCosign" name="content-trust-cosign"
|
||||
[disabled]="!hasChangeConfigRole" />
|
||||
<label for="content-trust-cosign">{{ 'ACCESSORY.CO_SIGN' | translate }}</label>
|
||||
</clr-checkbox-wrapper>
|
||||
<clr-checkbox-wrapper *ngIf="withNotary">
|
||||
<input id="content-trust" type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
||||
[disabled]="!hasChangeConfigRole" />
|
||||
<label for="content-trust">{{ 'ACCESSORY.NOTARY' | translate }}</label>
|
||||
</clr-checkbox-wrapper>
|
||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }}
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<clr-checkbox-container id="prevent-vulenrability-image" class="margin-top-05">
|
||||
<label><span *ngIf="!(withNotary && !isProxyCacheProject)">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<label><span *ngIf="!(!isProxyCacheProject)">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
||||
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||
<label>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_TOGGLE' | translate }}</label>
|
||||
</clr-checkbox-wrapper>
|
||||
<clr-control-helper class="config-subtext">
|
||||
@ -34,8 +39,8 @@
|
||||
<div>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_1' | translate }}</div>
|
||||
<div class="clr-select-wrapper">
|
||||
<select id="severity" name="severity" class="clr-select"
|
||||
[(ngModel)]="projectPolicy.PreventVulImgSeverity"
|
||||
[disabled]="!projectPolicy.PreventVulImg">
|
||||
[(ngModel)]="projectPolicy.PreventVulImgSeverity"
|
||||
[disabled]="!projectPolicy.PreventVulImg">
|
||||
<option *ngFor='let s of severityOptions' [ngValue]="s.severity">
|
||||
{{ s.severityLevel | translate }}</option>
|
||||
</select>
|
||||
@ -50,14 +55,14 @@
|
||||
<label>{{ 'PROJECT_CONFIG.SCAN' | translate }}</label>
|
||||
<clr-checkbox-wrapper id="scan-image-on-push-wrapper">
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ScanImgOnPush"
|
||||
[disabled]="!hasChangeConfigRole" name="scan-image-on-push" />
|
||||
[disabled]="!hasChangeConfigRole" name="scan-image-on-push" />
|
||||
<label>{{ 'PROJECT_CONFIG.AUTOSCAN_TOGGLE' | translate }}</label>
|
||||
</clr-checkbox-wrapper>
|
||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.AUTOSCAN_POLICY' | translate }}
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<div *ngIf="systemInfo" class="clr-form-control" [class.clr-form-control-disabled]="!hasChangeConfigRole">
|
||||
<label for="systemAllowlist" class="clr-control-label">{{'CVE_ALLOWLIST.CVE_ALLOWLIST'|translate}}</label>
|
||||
<label class="clr-control-label">{{'CVE_ALLOWLIST.CVE_ALLOWLIST'|translate}}</label>
|
||||
<div class="w-100 clr-control-container">
|
||||
<div class="config-subtext">
|
||||
<div>
|
||||
@ -71,22 +76,22 @@
|
||||
</div>
|
||||
<div *ngIf="hasExpired">
|
||||
<span *ngIf="isUseSystemAllowlist()"
|
||||
class="label label-warning">{{'CVE_ALLOWLIST.WARNING_SYS'|translate}}</span>
|
||||
class="label label-warning">{{'CVE_ALLOWLIST.WARNING_SYS'|translate}}</span>
|
||||
<span *ngIf="!isUseSystemAllowlist()"
|
||||
class="label label-warning">{{'CVE_ALLOWLIST.WARNING_PRO'|translate}}</span>
|
||||
class="label label-warning">{{'CVE_ALLOWLIST.WARNING_PRO'|translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<clr-radio-container clrInline>
|
||||
<clr-radio-wrapper>
|
||||
<input id="use-system" [attr.disabled]="!hasChangeConfigRole?'disabled':null" type="radio" clrRadio
|
||||
name="systemAllowlistOrProjectAllowlist" required value="true"
|
||||
[(ngModel)]="systemAllowlistOrProjectAllowlist" />
|
||||
name="systemAllowlistOrProjectAllowlist" required value="true"
|
||||
[(ngModel)]="systemAllowlistOrProjectAllowlist" />
|
||||
<label>{{'CVE_ALLOWLIST.SYS_ALLOWLIST'|translate}}</label>
|
||||
</clr-radio-wrapper>
|
||||
<clr-radio-wrapper>
|
||||
<input id="use-project" [attr.disabled]="!hasChangeConfigRole?'disabled':null" type="radio" clrRadio
|
||||
name="systemAllowlistOrProjectAllowlist" required value="false"
|
||||
[(ngModel)]="systemAllowlistOrProjectAllowlist" />
|
||||
name="systemAllowlistOrProjectAllowlist" required value="false"
|
||||
[(ngModel)]="systemAllowlistOrProjectAllowlist" />
|
||||
<label>{{'CVE_ALLOWLIST.PRO_ALLOWLIST'|translate}}</label>
|
||||
</clr-radio-wrapper>
|
||||
</clr-radio-container>
|
||||
@ -94,27 +99,27 @@
|
||||
<div class="clr-col position-relative col-flex-grow-0 ">
|
||||
<div>
|
||||
<button id="show-add-modal" [disabled]="isUseSystemAllowlist() || !hasChangeConfigRole"
|
||||
(click)="showAddModal=!showAddModal"
|
||||
class="btn btn-link">{{'CVE_ALLOWLIST.ADD'|translate}}</button>
|
||||
(click)="showAddModal=!showAddModal"
|
||||
class="btn btn-link">{{'CVE_ALLOWLIST.ADD'|translate}}</button>
|
||||
<button id="add-system" [disabled]="isUseSystemAllowlist() || !hasChangeConfigRole"
|
||||
(click)="addSystem()"
|
||||
class="btn btn-link ml-1">{{'CVE_ALLOWLIST.ADD_SYSTEM'|translate}}</button>
|
||||
(click)="addSystem()"
|
||||
class="btn btn-link ml-1">{{'CVE_ALLOWLIST.ADD_SYSTEM'|translate}}</button>
|
||||
</div>
|
||||
<div class="add-modal add-modal-dark" *ngIf="showAddModal && !isUseSystemAllowlist()">
|
||||
<clr-icon (click)="showAddModal=false" class="float-lg-right margin-top-4"
|
||||
shape="window-close"></clr-icon>
|
||||
shape="window-close"></clr-icon>
|
||||
<div>
|
||||
<clr-textarea-container class="flex-direction-column">
|
||||
<label>{{'CVE_ALLOWLIST.ENTER'|translate}}</label>
|
||||
<textarea id="allowlist-textarea" class="w-100" clrTextarea [(ngModel)]="cveIds"
|
||||
name="cveIds"></textarea>
|
||||
name="cveIds"></textarea>
|
||||
<clr-control-helper>{{'CVE_ALLOWLIST.HELP'|translate}}</clr-control-helper>
|
||||
</clr-textarea-container>
|
||||
</div>
|
||||
<div>
|
||||
<button id="add-to-allowlist" [disabled]="isDisabled()"
|
||||
(click)="addToProjectAllowlist()"
|
||||
class="btn btn-link">{{'CVE_ALLOWLIST.ADD'|translate}}</button>
|
||||
(click)="addToProjectAllowlist()"
|
||||
class="btn btn-link">{{'CVE_ALLOWLIST.ADD'|translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="allowlist-window" *ngIf="isUseSystemAllowlist()">
|
||||
@ -137,24 +142,23 @@
|
||||
</div>
|
||||
<div class="clr-col padding-top-16 pl-2">
|
||||
<div class="clr-row expire-data">
|
||||
<label for="expires"
|
||||
class="bottom-line bottom-line-project-config clr-col-3">{{'CVE_ALLOWLIST.EXPIRES_AT'|translate}}</label>
|
||||
<label class="bottom-line bottom-line-project-config clr-col-3">{{'CVE_ALLOWLIST.EXPIRES_AT'|translate}}</label>
|
||||
<div class="underline">
|
||||
<input #dateSystemInput readonly type="date" [(clrDate)]="systemExpiresDate">
|
||||
<input [disabled]="!hasChangeConfigRole" *ngIf="!isUseSystemAllowlist()" #dateInput
|
||||
placeholder="{{'CVE_ALLOWLIST.NEVER_EXPIRES'|translate}}" readonly type="date"
|
||||
[(clrDate)]="expiresDate" newFormLayout="true">
|
||||
placeholder="{{'CVE_ALLOWLIST.NEVER_EXPIRES'|translate}}" readonly type="date"
|
||||
[(clrDate)]="expiresDate" newFormLayout="true">
|
||||
<input clrInput [disabled]="!hasChangeConfigRole" *ngIf="isUseSystemAllowlist()"
|
||||
placeholder="{{'CVE_ALLOWLIST.NEVER_EXPIRES'|translate}}" readonly type="text"
|
||||
value="{{systemExpiresDateString}}">
|
||||
placeholder="{{'CVE_ALLOWLIST.NEVER_EXPIRES'|translate}}" readonly type="text"
|
||||
value="{{systemExpiresDateString}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clr-row">
|
||||
<label for="expires" class="clr-col-3"></label>
|
||||
<label for="neverExpires" class="clr-col-3"></label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input [disabled]="isUseSystemAllowlist() || !hasChangeConfigRole"
|
||||
[checked]="neverExpires" [(ngModel)]="neverExpires" type="checkbox" clrCheckbox
|
||||
name="neverExpires" id="neverExpires" />
|
||||
[checked]="neverExpires" [(ngModel)]="neverExpires" type="checkbox" clrCheckbox
|
||||
name="neverExpires" id="neverExpires" />
|
||||
<label>
|
||||
{{'CVE_ALLOWLIST.NEVER_EXPIRES'|translate}}
|
||||
</label>
|
||||
@ -165,10 +169,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" (click)="save()"
|
||||
[disabled]="((!isValid() || !hasChanges()) && !hasAllowlistChanged) || !hasChangeConfigRole">{{'BUTTON.SAVE'
|
||||
[disabled]="((!isValid() || !hasChanges()) && !hasAllowlistChanged) || !hasChangeConfigRole">{{'BUTTON.SAVE'
|
||||
| translate}}</button>
|
||||
<button type="button" class="btn btn-outline" (click)="cancel()"
|
||||
[disabled]="((!isValid() || !hasChanges()) && !hasAllowlistChanged) || !hasChangeConfigRole">{{'BUTTON.CANCEL'
|
||||
[disabled]="((!isValid() || !hasChanges()) && !hasAllowlistChanged) || !hasChangeConfigRole">{{'BUTTON.CANCEL'
|
||||
| translate}}</button>
|
||||
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
||||
</section>
|
||||
|
@ -23,6 +23,7 @@ const TARGET_BLANK = "_blank";
|
||||
export class ProjectPolicy {
|
||||
Public: boolean;
|
||||
ContentTrust: boolean;
|
||||
ContentTrustCosign: boolean;
|
||||
PreventVulImg: boolean;
|
||||
PreventVulImgSeverity: string;
|
||||
ScanImgOnPush: boolean;
|
||||
@ -30,6 +31,7 @@ export class ProjectPolicy {
|
||||
constructor() {
|
||||
this.Public = false;
|
||||
this.ContentTrust = false;
|
||||
this.ContentTrustCosign = false;
|
||||
this.PreventVulImg = false;
|
||||
this.PreventVulImgSeverity = LOW;
|
||||
this.ScanImgOnPush = false;
|
||||
@ -38,6 +40,7 @@ export class ProjectPolicy {
|
||||
initByProject(pro: Project) {
|
||||
this.Public = pro.metadata.public === 'true';
|
||||
this.ContentTrust = pro.metadata.enable_content_trust === 'true';
|
||||
this.ContentTrustCosign = pro.metadata.enable_content_trust_cosign === 'true';
|
||||
this.PreventVulImg = pro.metadata.prevent_vul === 'true';
|
||||
if (pro.metadata.severity) {
|
||||
this.PreventVulImgSeverity = pro.metadata.severity;
|
||||
|
@ -15,6 +15,7 @@ export class Project {
|
||||
metadata?: {
|
||||
public: string | boolean;
|
||||
enable_content_trust: string | boolean;
|
||||
enable_content_trust_cosign?: string | boolean;
|
||||
prevent_vul: string | boolean;
|
||||
severity: string;
|
||||
auto_scan: string | boolean;
|
||||
@ -24,6 +25,7 @@ export class Project {
|
||||
constructor () {
|
||||
this.metadata.public = false;
|
||||
this.metadata.enable_content_trust = false;
|
||||
this.metadata.enable_content_trust_cosign = false;
|
||||
this.metadata.prevent_vul = false;
|
||||
this.metadata.severity = 'low';
|
||||
this.metadata.auto_scan = false;
|
||||
|
@ -157,7 +157,7 @@
|
||||
</clr-dg-column>
|
||||
<clr-dg-column class="pull-command-column">{{'REPOSITORY.PULL_COMMAND' | translate}}</clr-dg-column>
|
||||
<clr-dg-column *ngIf="depth">{{'REPOSITORY.PLATFORM' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPOSITORY.TAGS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="tag-column">{{'REPOSITORY.TAGS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="co-signed-column">{{'ACCESSORY.CO_SIGNED' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'size'">{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="vul-column">{{'REPOSITORY.VULNERABILITY' | translate}}</clr-dg-column>
|
||||
@ -166,7 +166,7 @@
|
||||
<clr-dg-column [clrDgSortBy]="pushComparator">{{'REPOSITORY.PUSH_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="pullComparator">{{'REPOSITORY.PULL_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'ARTIFACT.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
<clr-dg-row *ngFor="let artifact of artifactList" [clrDgItem]="artifact" >
|
||||
<clr-dg-row *ngFor="let artifact of artifactList;let i = index" [clrDgItem]="artifact" >
|
||||
<clr-dg-cell class="flex-max-width truncated">
|
||||
<div class="cell white-normal">
|
||||
<div class="artifact-icon clr-display-inline-block" *ngIf="artifact.icon">
|
||||
@ -203,10 +203,8 @@
|
||||
<clr-tooltip class="width-p-100">
|
||||
<div clrTooltipTrigger class="center">
|
||||
<div class="center">
|
||||
<span #tagName class="truncated">{{artifact?.tags[0]?.name}}</span>
|
||||
<span class="eslip"
|
||||
*ngIf="artifact?.tags?.length>1 && isOverflow()">...</span>
|
||||
<span *ngIf="artifact?.tags?.length>1 || isOverflow()">({{artifact?.tagNumber}})</span>
|
||||
<span class="truncated">{{tagsString(artifact?.tags)}}</span>
|
||||
<span *ngIf="artifact?.tags?.length>1">({{artifact?.tagNumber}})</span>
|
||||
</div>
|
||||
</div>
|
||||
<clr-tooltip-content [clrPosition]="'top-right'" class="lg" [clrSize]="'lg'" *clrIfOpen>
|
||||
|
@ -422,7 +422,7 @@ clr-datagrid {
|
||||
width: 6rem !important;
|
||||
}
|
||||
.co-signed-column {
|
||||
width: 6rem !important;
|
||||
width: 7rem !important;
|
||||
}
|
||||
.vul-column {
|
||||
width: 11rem !important;
|
||||
@ -430,6 +430,9 @@ clr-datagrid {
|
||||
.annotations-column {
|
||||
width: 5rem !important;
|
||||
}
|
||||
.tag-column {
|
||||
width: 7rem !important;
|
||||
}
|
||||
.signed {
|
||||
color: #00d40f;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import { forkJoin, Observable, of, Subject, Subscription } from "rxjs";
|
||||
import { catchError, debounceTime, distinctUntilChanged, finalize, map } from 'rxjs/operators';
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { ClrDatagridComparatorInterface, ClrDatagridStateInterface, ClrLoadingState } from "@clr/angular";
|
||||
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { Comparator, } from "../../../../../../../shared/services";
|
||||
import {
|
||||
@ -62,6 +61,7 @@ import { AppConfigService } from "src/app/services/app-config.service";
|
||||
import { ArtifactListPageService } from "../../artifact-list-page.service";
|
||||
import { ACCESSORY_PAGE_SIZE } from "./sub-accessories/sub-accessories.component";
|
||||
import { Accessory } from "ng-swagger-gen/models/accessory";
|
||||
import { Tag } from '../../../../../../../../../ng-swagger-gen/models/tag';
|
||||
|
||||
export interface LabelState {
|
||||
iconsShow: boolean;
|
||||
@ -176,8 +176,6 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
onScanArtifactsLength: number = 0;
|
||||
stopBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
updateArtifactSub: Subscription;
|
||||
@ViewChild('tagName') nameSpan: ElementRef;
|
||||
|
||||
constructor(
|
||||
private errorHandlerService: ErrorHandler,
|
||||
private artifactService: ArtifactService,
|
||||
@ -1200,11 +1198,15 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
}
|
||||
isOverflow(): boolean {
|
||||
if (!this.nameSpan) {
|
||||
return false;
|
||||
tagsString(tags: Tag[]): string {
|
||||
if (tags?.length) {
|
||||
const arr: string[] = [];
|
||||
tags.forEach(item => {
|
||||
arr.push(item.name);
|
||||
});
|
||||
return arr.join(', ');
|
||||
}
|
||||
return !(this.nameSpan?.nativeElement?.clientWidth >= this.nameSpan?.nativeElement?.scrollWidth);
|
||||
return null;
|
||||
}
|
||||
deleteAccessory(a: Accessory) {
|
||||
let titleKey: string, summaryKey: string, content: string, buttons: ConfirmationButtons;
|
||||
|
@ -115,6 +115,7 @@ export class ProjectDefaultService extends ProjectService {
|
||||
metadata: {
|
||||
public: projectPolicy.Public ? "true" : "false",
|
||||
enable_content_trust: projectPolicy.ContentTrust ? "true" : "false",
|
||||
enable_content_trust_cosign: projectPolicy.ContentTrustCosign ? "true" : "false",
|
||||
prevent_vul: projectPolicy.PreventVulImg ? "true" : "false",
|
||||
severity: projectPolicy.PreventVulImgSeverity,
|
||||
auto_scan: projectPolicy.ScanImgOnPush ? "true" : "false",
|
||||
|
@ -1713,12 +1713,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1713,12 +1713,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1712,12 +1712,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1681,12 +1681,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1709,12 +1709,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1713,12 +1713,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
@ -1711,12 +1711,12 @@
|
||||
"DELETE_ACCESSORY": "删除附件",
|
||||
"DELETED_SUCCESS": "删除附件成功",
|
||||
"DELETED_FAILED": "删除附件失败",
|
||||
"CO_SIGNED": "Co-sign 签名",
|
||||
"CO_SIGNED": "Cosign 签名",
|
||||
"NOTARY_SIGNED": "Notary 签名",
|
||||
"ACCESSORY": "附件",
|
||||
"ACCESSORIES": "附件",
|
||||
"SUBJECT_ARTIFACT": "主体 Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "未发现任何附件!"
|
||||
}
|
||||
|
@ -1698,12 +1698,12 @@
|
||||
"DELETE_ACCESSORY": "Delete Accessory",
|
||||
"DELETED_SUCCESS": "Accessory deleted successfully",
|
||||
"DELETED_FAILED": "Deleting accessory failed",
|
||||
"CO_SIGNED": "Co-signed",
|
||||
"NOTARY_SIGNED": "Notary signed",
|
||||
"CO_SIGNED": "Signed by Cosign",
|
||||
"NOTARY_SIGNED": "Signed by Notary",
|
||||
"ACCESSORY": "Accessory",
|
||||
"ACCESSORIES": "Accessories",
|
||||
"SUBJECT_ARTIFACT": "Subject Artifact",
|
||||
"CO_SIGN": "Co-sign",
|
||||
"CO_SIGN": "Cosign",
|
||||
"NOTARY": "Notary",
|
||||
"PLACEHOLDER": "We couldn't find any accessories!"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user