Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

072924.01/api revision meta data #8720

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,106 @@ describe('ApiRevisionOptionsComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

describe('Tag APIRevision appropriately based on date and/or status', () => {
const apiRevisions = [
{
id: '1',
isApproved: false,
version: "12.15.1",
apiRevisionType: 'manual',
},
{
id: '2',
isApproved: true,
version: "12.20.0-beta.2",
changeHistory: [
{
changeAction: 'approved',
changedOn: '2024-07-01T00:00:00Z',
}
],
isReleased: true,
releasedOn: '2024-07-02T00:00:00Z',
apiRevisionType: 'automatic',
lastUpdatedOn: '2024-07-01T00:00:00Z',
},
{
id: '3',
isApproved: true,
version: "12.20.0",
changeHistory: [
{
changeAction: 'approved',
changedOn: '2024-07-04T00:00:00Z',
}
],
isReleased: true,
releasedOn: '2024-07-05T00:00:00Z',
apiRevisionType: 'automatic',
lastUpdatedOn: '2024-07-04T00:00:00Z',
},
{
id: '4',
isApproved: true,
version: "12.21.1",
changeHistory: [
{
changeAction: 'approved',
changedOn: '2024-07-05T00:00:00Z',
}
],
isReleased: false,
apiRevisionType: 'automatic',
lastUpdatedOn: '2024-07-05T00:00:00Z',
},
{
id: '5',
isApproved: false,
version: "13.0.0",
isReleased: false,
apiRevisionType: 'automatic',
lastUpdatedOn: '2024-07-04T00:00:00Z',
},
{
id: '6',
isApproved: true,
version: "11.0.0",
changeHistory: [
{
changeAction: 'approved',
changedOn: '2021-07-04T00:00:00Z',
}
],
isReleased: true,
releasedOn: '2021-07-05T00:00:00Z',
apiRevisionType: 'automatic',
lastUpdatedOn: '2021-07-04T00:00:00Z',
},
];

it('should correctly tag the latest GA APIRevision', () => {
var result = component.tagLatestGARevision(apiRevisions);
expect(result.id).toEqual('3');
expect(result.isLatestGA).toBeTruthy();
});

it('should correctly tag the latest approved APIRevision', () => {
var result = component.tagLatestApprovedRevision(apiRevisions);
expect(result.id).toEqual('4');
expect(result.isLatestApproved).toBeTruthy();
});

it('should correctly tag the latest automatic APIRevision', () => {
chidozieononiwu marked this conversation as resolved.
Show resolved Hide resolved
var result = component.tagCurrentMainRevision(apiRevisions);
expect(result.id).toEqual('4');
expect(result.isLatestMain).toBeTruthy();
});

it('should correctly tag the latest released APIRevision', () => {
var result = component.tagLatestReleasedRevision(apiRevisions);
expect(result.id).toEqual('3');
expect(result.isLatestReleased).toBeTruthy();
});
})
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { getQueryParams } from 'src/app/_helpers/router-helpers';
import { AzureEngSemanticVersion } from 'src/app/_models/azureEngSemanticVersion';
import { APIRevision } from 'src/app/_models/revision';

@Component({
Expand Down Expand Up @@ -42,8 +43,8 @@ export class ApiRevisionOptionsComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges): void {
if (changes['apiRevisions'] || changes['activeApiRevisionId'] || changes['diffApiRevisionId']) {
if (this.apiRevisions.length > 0) {
let mappedApiRevisions = this.mapRevisionToMenu(this.apiRevisions);
this.mappedApiRevisions = this.identifyAndProcessSpecialAPIRevisions(mappedApiRevisions);
this.mappedApiRevisions = this.mapRevisionToMenu(this.apiRevisions);
this.tagSpecialRevisions(this.mappedApiRevisions);

this.activeApiRevisionsMenu = this.mappedApiRevisions.filter((apiRevision: any) => apiRevision.id !== this.diffApiRevisionId);
const selectedActiveAPIRevisionindex = this.activeApiRevisionsMenu.findIndex((apiRevision: APIRevision) => apiRevision.id === this.activeApiRevisionId);
Expand Down Expand Up @@ -170,6 +171,7 @@ export class ApiRevisionOptionsComponent implements OnChanges {
return {
id : apiRevision.id,
resolvedLabel: apiRevision.resolvedLabel,
language: apiRevision.language,
label: apiRevision.label,
typeClass: typeClass,
apiRevisionType: apiRevision.apiRevisionType,
Expand All @@ -181,6 +183,7 @@ export class ApiRevisionOptionsComponent implements OnChanges {
isApproved: apiRevision.isApproved,
isReleased: apiRevision.isReleased,
releasedOn: apiRevision.releasedOn,
changeHistory: apiRevision.changeHistory,
isLatestGA : false,
isLatestApproved : false,
isLatestMain : false,
Expand All @@ -191,74 +194,92 @@ export class ApiRevisionOptionsComponent implements OnChanges {
});
}

identifyAndProcessSpecialAPIRevisions(mappedApiRevisions: any []) {
const result = [];
const semVarRegex = /(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:(?<presep>-?)(?<prelabel>[a-zA-Z]+)(?:(?<prenumsep>\.?)(?<prenumber>[0-9]{1,8})(?:(?<buildnumsep>\.?)(?<buildnumber>\d{1,3}))?)?)?/;

let latestGAApiRevision : any = null;
let latestApprovedApiRevision : any = null;
let currentMainApiRevision : any = null;
let latestReleasedApiRevision : any = null;

while (mappedApiRevisions.length > 0) {
let apiRevision = mappedApiRevisions.shift();
tagSpecialRevisions(mappedApiRevisions: any []) {
this.tagLatestGARevision(mappedApiRevisions);
this.tagLatestApprovedRevision(mappedApiRevisions);
this.tagCurrentMainRevision(mappedApiRevisions);
this.tagLatestReleasedRevision(mappedApiRevisions);
}

if (latestGAApiRevision === null) {
if (apiRevision.version) {
let versionParts = apiRevision.version.match(semVarRegex);
tagLatestGARevision(apiRevisions: any[]) {
const gaRevisions : any [] = [];

if (versionParts.groups?.prelabel === undefined && versionParts.groups?.prenumber === undefined &&
versionParts.groups?.prenumsep === undefined && versionParts.groups?.presep === undefined) {
apiRevision.isLatestGA = true;
latestGAApiRevision = apiRevision;
continue;
}
for (let apiRevision of apiRevisions) {
if (apiRevision.isReleased && apiRevision.version) {
const semVar = new AzureEngSemanticVersion(apiRevision.version, apiRevision.language);
if (semVar.versionType == "GA") {
apiRevision.semanticVersion = semVar;
gaRevisions.push(apiRevision);
}
}
}

if (latestApprovedApiRevision === null) {
if (apiRevision.isApproved) {
apiRevision.isLatestApproved = true;
latestApprovedApiRevision = apiRevision;
continue;
}
}
if (gaRevisions.length > 0) {
gaRevisions.sort((a: any, b: any) => b.semanticVersion.compareTo(a.semanticVersion));
gaRevisions[0].isLatestGA = true;
chidozieononiwu marked this conversation as resolved.
Show resolved Hide resolved
this.updateTaggedAPIRevisions(apiRevisions, gaRevisions[0]);
return gaRevisions[0];
}
}

if (currentMainApiRevision === null) {
if (apiRevision.apiRevisionType === 'Automatic') {
apiRevision.isLatestMain = true;
currentMainApiRevision = apiRevision;
continue;
}
}
tagLatestApprovedRevision(apiRevisions: any[]) {
const approvedRevisions : any [] = [];

if (latestReleasedApiRevision === null) {
if (apiRevision.isReleased) {
apiRevision.isLatestReleased = true;
latestReleasedApiRevision = apiRevision;
continue;
for (let apiRevision of apiRevisions) {
if (apiRevision.isApproved && apiRevision.changeHistory.length > 0) {
var approval = apiRevision.changeHistory.find((change: any) => change.changeAction === 'approved');
if (approval) {
apiRevision.approvedOn = approval.changedOn;
approvedRevisions.push(apiRevision);
}
}
result.push(apiRevision);
}

if (latestGAApiRevision) {
result.unshift(latestGAApiRevision);
if (approvedRevisions.length > 0) {
approvedRevisions.sort((a: any, b: any) => (new Date(b.approvedOn) as any) - (new Date(a.approvedOn) as any));
approvedRevisions[0].isLatestApproved = true;
this.updateTaggedAPIRevisions(apiRevisions, approvedRevisions[0]);
return approvedRevisions[0];
}
}

tagCurrentMainRevision(apiRevisions: any[]) {
const automaticRevisions : any [] = [];

if (latestApprovedApiRevision) {
result.unshift(latestApprovedApiRevision);
for (let apiRevision of apiRevisions) {
if (apiRevision.apiRevisionType === 'automatic') {
automaticRevisions.push(apiRevision);
}
}

if (currentMainApiRevision) {
result.unshift(currentMainApiRevision);
if (automaticRevisions.length > 0) {
automaticRevisions.sort((a: any, b: any) => (new Date(b.lastUpdatedOn) as any) - (new Date(a.lastUpdatedOn) as any));
automaticRevisions[0].isLatestMain = true;
this.updateTaggedAPIRevisions(apiRevisions, automaticRevisions[0]);
return automaticRevisions[0];
}
}

tagLatestReleasedRevision(apiRevisions: any[]) {
const releasedRevisions : any [] = [];

if (latestReleasedApiRevision) {
result.unshift(latestReleasedApiRevision);
for (let apiRevision of apiRevisions) {
if (apiRevision.isReleased) {
releasedRevisions.push(apiRevision);
}
}

if (releasedRevisions.length > 0) {
releasedRevisions.sort((a: any, b: any) => (new Date(b.releasedOn) as any) - (new Date(a.releasedOn) as any));
releasedRevisions[0].isLatestReleased = true;
this.updateTaggedAPIRevisions(apiRevisions, releasedRevisions[0]);
return releasedRevisions[0];
}
}

return result;
private updateTaggedAPIRevisions(apiRevisions: any[], taggedApiRevision: any) {
apiRevisions.splice(apiRevisions.indexOf(taggedApiRevision), 1)
apiRevisions.unshift(taggedApiRevision);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Datasource, IDatasource, SizeStrategy } from 'ngx-ui-scroll';
import { CommentsService } from 'src/app/_services/comments/comments.service';
import { getQueryParams } from 'src/app/_helpers/router-helpers';
import { ActivatedRoute, Router } from '@angular/router';
import { SCROLL_TO_NODE_QUERY_PARAM } from 'src/app/_helpers/literal-helpers';
import { SCROLL_TO_NODE_QUERY_PARAM } from 'src/app/_helpers/common-helpers';
import { CodePanelRowData, CodePanelRowDatatype } from 'src/app/_models/codePanelRowData';
import { StructuredToken } from 'src/app/_models/structuredToken';
import { CommentItemModel, CommentType } from 'src/app/_models/commentItemModel';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange
import { ActivatedRoute, Router } from '@angular/router';
import { InputSwitchOnChangeEvent } from 'primeng/inputswitch';
import { getQueryParams } from 'src/app/_helpers/router-helpers';
import { mapLanguageAliases } from 'src/app/_helpers/service-helpers';
import { mapLanguageAliases } from 'src/app/_helpers/common-helpers';
import { Review } from 'src/app/_models/review';
import { APIRevision } from 'src/app/_models/revision';
import { ConfigService } from 'src/app/_services/config/config.service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { MenuItem, TreeNode } from 'primeng/api';
import { Subject, take, takeUntil } from 'rxjs';
import { getLanguageCssSafeName } from 'src/app/_helpers/component-helpers';
import { getLanguageCssSafeName } from 'src/app/_helpers/common-helpers';
import { getQueryParams } from 'src/app/_helpers/router-helpers';
import { Review } from 'src/app/_models/review';
import { APIRevision, ApiTreeBuilderData, CodePanelData, ReviewPageWorkerMessageDirective } from 'src/app/_models/revision';
Expand All @@ -12,7 +12,7 @@ import { UserProfileService } from 'src/app/_services/user-profile/user-profile.
import { WorkerService } from 'src/app/_services/worker/worker.service';
import { CodePanelComponent } from '../code-panel/code-panel.component';
import { CommentsService } from 'src/app/_services/comments/comments.service';
import { ACTIVE_API_REVISION_ID_QUERY_PARAM, DIFF_API_REVISION_ID_QUERY_PARAM, DIFF_STYLE_QUERY_PARAM, REVIEW_ID_ROUTE_PARAM, SCROLL_TO_NODE_QUERY_PARAM } from 'src/app/_helpers/literal-helpers';
import { ACTIVE_API_REVISION_ID_QUERY_PARAM, DIFF_API_REVISION_ID_QUERY_PARAM, DIFF_STYLE_QUERY_PARAM, REVIEW_ID_ROUTE_PARAM, SCROLL_TO_NODE_QUERY_PARAM } from 'src/app/_helpers/common-helpers';
import { CodePanelRowData, CodePanelRowDatatype } from 'src/app/_models/codePanelRowData';
import { UserProfile } from 'src/app/_models/userProfile';

Expand Down
29 changes: 29 additions & 0 deletions src/dotnet/APIView/ClientSPA/src/app/_helpers/common-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const REVIEW_ID_ROUTE_PARAM = "reviewId";
export const ACTIVE_API_REVISION_ID_QUERY_PARAM = "activeApiRevisionId";
export const DIFF_API_REVISION_ID_QUERY_PARAM = "diffApiRevisionId";
export const DIFF_STYLE_QUERY_PARAM = "diffStyle";
export const SCROLL_TO_NODE_QUERY_PARAM = "nId";

export function getLanguageCssSafeName(language: string): string {
switch (language.toLowerCase()) {
case "c#":
return "csharp";
case "c++":
return "cplusplus";
default:
return language.toLowerCase();
}
}

export function mapLanguageAliases(languages: Iterable<string>): string[] {
const result: Set<string> = new Set<string>();

for (const language of languages) {
if (language === "TypeSpec" || language === "Cadl") {
chidozieononiwu marked this conversation as resolved.
Show resolved Hide resolved
result.add("Cadl");
result.add("TypeSpec");
}
result.add(language);
}
return Array.from(result);
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading