@immobiliarelabs/backstage-plugin-gitlab
Version:
<p align="center"> <img src="https://avatars.githubusercontent.com/u/10090828?s=200&v=4" width="200px" alt="logo"/> </p> <h1 align="center">Backstage Plugin GitLab</h1>
2,310 lines (2,297 loc) • 54.3 kB
JavaScript
import { createApiRef, createRouteRef, createPlugin, createApiFactory, configApiRef, discoveryApiRef, identityApiRef, createRoutableExtension, createComponentExtension, useApi } from '@backstage/core-plugin-api';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import duration from 'dayjs/plugin/duration';
import React, { useState } from 'react';
import { useEntity } from '@backstage/plugin-catalog-react';
import { Progress, InfoCard, Link, StructuredMetadataTable, MarkdownContent } from '@backstage/core-components';
import { Tooltip, Chip, Avatar, Box, Grid, Divider, makeStyles as makeStyles$1, FormControl, Select, MenuItem, FormHelperText, Link as Link$1 } from '@material-ui/core';
import { makeStyles, withStyles } from '@material-ui/core/styles';
import Alert from '@material-ui/lab/Alert';
import { useAsync } from 'react-use';
import '@backstage/integration-react';
import '@backstage/catalog-model';
import ArrowIcon from '@material-ui/icons/ArrowForward';
import '@material-ui/core/Link';
import LocalOfferOutlinedIcon from '@material-ui/icons/LocalOfferOutlined';
import { rcompare, valid, prerelease } from 'semver';
const GitlabCIApiRef = createApiRef({
id: "plugin.gitlabci.service"
});
dayjs.extend(relativeTime);
dayjs.extend(duration);
const getElapsedTime = (start) => {
return dayjs(start).fromNow();
};
const getDuration = (start, end) => {
if (!end || !start) {
return "NA";
}
const end_time = dayjs(end);
const start_time = dayjs(start);
const duration2 = dayjs.duration(
end_time.diff(start_time, "seconds"),
"seconds"
);
const days = duration2.days();
const hours = duration2.hours();
const minutes = duration2.minutes();
const seconds = duration2.seconds();
const output = `${days ? days + "d " : ""}${hours ? hours + "h " : ""}${minutes ? minutes + "m " : ""}${seconds ? seconds + "s" : ""}`;
if (!output)
return "0s";
return output;
};
const parseCodeOwners = (str) => {
try {
const lines = str.replace(/\r/g, "").split("\n");
const owned = [];
for (const line of lines) {
if (!line || line.startsWith("#")) {
continue;
}
owned.push(parseCodeOwnerLine(line));
}
return owned;
} catch (error) {
console.log(`failed to load codeowners`, error);
throw error;
}
};
const parseCodeOwnerLine = (rule) => {
const parts = rule.split(/\s+/);
const path = parts[0];
let teamNames = [];
if (parts.length > 1) {
teamNames = parts.slice(1, parts.length);
for (const name of teamNames) {
if (!codeOwnerRegex.test(name)) {
throw new Error(
`${name} is not a valid owner name in rule ${rule}`
);
}
}
}
return {
rule,
path,
owners: teamNames
};
};
const codeOwnerRegex = /(^@[a-zA-Z0-9_\-/]*$)|(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
class GitlabCIClient {
constructor({
discoveryApi,
identityApi,
codeOwnersPath,
readmePath,
gitlabInstance
}) {
this.discoveryApi = discoveryApi;
this.codeOwnersPath = codeOwnersPath || "CODEOWNERS";
this.readmePath = readmePath || "README.md";
this.gitlabInstance = gitlabInstance;
this.identityApi = identityApi;
}
static setupAPI({
discoveryApi,
identityApi,
codeOwnersPath,
readmePath
}) {
return {
build: (gitlabInstance) => new this({
discoveryApi,
identityApi,
codeOwnersPath,
readmePath,
gitlabInstance
})
};
}
async callApi(path, query) {
var _a;
const apiUrl = `${await this.discoveryApi.getBaseUrl("gitlab")}/${this.gitlabInstance}`;
const token = (await this.identityApi.getCredentials()).token;
const options = token ? {
headers: {
Authorization: `Bearer ${token}`
}
} : {};
const response = await fetch(
`${apiUrl}/${path}?${new URLSearchParams(query).toString()}`,
options
);
if (response.status === 200) {
if ((_a = response.headers.get("content-type")) == null ? void 0 : _a.includes("application/json")) {
return await response.json();
} else {
return response.text();
}
}
return null;
}
async getPipelineSummary(projectID) {
const pipelineObjects = await this.callApi(
"projects/" + projectID + "/pipelines",
{}
);
const projectObj = await this.callApi(
"projects/" + projectID,
{}
);
if (pipelineObjects) {
pipelineObjects.forEach((element) => {
element.project_name = projectObj == null ? void 0 : projectObj.name;
});
}
return {
getPipelinesData: pipelineObjects
};
}
async getIssuesSummary(projectId) {
const issuesObject = await this.callApi(
`projects/${projectId}/issues`,
{}
);
const projectObj = await this.callApi(
"projects/" + projectId,
{}
);
if (issuesObject) {
issuesObject.forEach((element) => {
element.project_name = projectObj == null ? void 0 : projectObj.name;
});
}
return {
getIssuesData: issuesObject
};
}
async getProjectName(projectID) {
const projectObj = await this.callApi(
"projects/" + projectID,
{}
);
return projectObj == null ? void 0 : projectObj.name;
}
//TODO: Merge with getUserDetail
async getUserProfilesData(contributorsData) {
for (let i = 0; contributorsData && i < contributorsData.length; i++) {
const userProfile = await this.callApi("users", {
search: contributorsData[i].email,
without_project_bots: "true"
});
if (userProfile) {
userProfile.forEach(
(userProfileElement) => {
if (userProfileElement.name == contributorsData[i].name) {
contributorsData[i].avatar_url = userProfileElement == null ? void 0 : userProfileElement.avatar_url;
}
}
);
}
}
return contributorsData;
}
async getUserDetail(username) {
var _a;
if (username.startsWith("@")) {
username = username.slice(1);
}
const userDetail = (_a = await this.callApi("users", {
username
})) == null ? void 0 : _a[0];
if (!userDetail)
throw new Error(`user ${username} does not exist`);
return userDetail;
}
async getGroupDetail(name) {
if (name.startsWith("@")) {
name = name.slice(1);
}
const groupDetail = await this.callApi(
`groups/${encodeURIComponent(name)}`,
{ with_projects: "false" }
);
if (!groupDetail)
throw new Error(`group ${name} does not exist`);
return groupDetail;
}
async getMergeRequestsSummary(projectID) {
const mergeRquestsList = await this.callApi(
"projects/" + projectID + "/merge_requests",
{}
);
return {
getMergeRequestsData: mergeRquestsList
};
}
async getMergeRequestsStatusSummary(projectID, count) {
const mergeRequestsList = await this.callApi(
"projects/" + projectID + "/merge_requests",
{ per_page: count }
);
return {
getMergeRequestsStatusData: mergeRequestsList
};
}
async getContributorsSummary(projectID) {
const contributorsData = await this.callApi(
"projects/" + projectID + "/repository/contributors",
{ sort: "desc" }
);
const updatedContributorsData = await this.getUserProfilesData(
contributorsData
);
return {
getContributorsData: updatedContributorsData
};
}
async getLanguagesSummary(projectID) {
const languageObjects = await this.callApi(
"projects/" + projectID + "/languages",
{}
);
return {
getLanguagesData: languageObjects
};
}
async getReleasesSummary(projectID) {
const releaseObjects = await this.callApi(
"projects/" + projectID + "/releases",
{}
);
return {
getReleasesData: releaseObjects
};
}
async getProjectDetails(projectSlug) {
let projectDetails;
if (projectSlug) {
projectDetails = await this.callApi(
"projects/" + encodeURIComponent(projectSlug),
{}
);
}
return projectDetails;
}
async retryPipelineBuild(projectID, pipelineID) {
const retryBuild = await this.callApi(
"projects/" + projectID + "/pipelines/" + pipelineID + "/retry",
{}
);
return retryBuild;
}
async getCodeOwners(projectID, branch = "HEAD", filePath) {
filePath = filePath || this.codeOwnersPath;
if (filePath.startsWith("./"))
filePath = filePath.slice(2);
const codeOwnersStr = await this.callApi(
`projects/${projectID}/repository/files/${encodeURI(filePath)}/raw`,
{ ref: branch }
);
if (!codeOwnersStr) {
throw Error(`Code owners file not found`);
}
const codeOwners = parseCodeOwners(codeOwnersStr || "");
const dataOwners = codeOwners;
const uniqueOwners = [
...new Set(dataOwners.flatMap((owner) => owner.owners))
];
const ownersSettledResult = await Promise.allSettled(
uniqueOwners.map(async (owner) => {
try {
const ownerData = await this.getUserDetail(owner);
return ownerData;
} catch (error) {
const ownerData = await this.getGroupDetail(owner);
return ownerData;
}
})
);
const owners = ownersSettledResult.filter((result) => result.status === "fulfilled").map(
(result) => result.value
);
return owners;
}
async getReadme(projectID, branch = "HEAD", filePath) {
filePath = filePath || this.readmePath;
if (filePath.startsWith("./"))
filePath = filePath.slice(2);
const readmeStr = await this.callApi(
`projects/${projectID}/repository/files/${encodeURI(filePath)}/raw`,
{ ref: branch }
);
if (!readmeStr) {
throw Error(`README file not found`);
}
return readmeStr;
}
getContributorsLink(projectWebUrl, projectDefaultBranch) {
return `${projectWebUrl}/-/graphs/${projectDefaultBranch}`;
}
getOwnersLink(projectWebUrl, projectDefaultBranch, codeOwnersPath) {
return `${projectWebUrl}/-/blob/${projectDefaultBranch}/${codeOwnersPath || this.codeOwnersPath}`;
}
}
const rootRouteRef = createRouteRef({
id: "Gitlab"
});
const gitlabPlugin = createPlugin({
id: "Gitlab",
apis: [
createApiFactory({
api: GitlabCIApiRef,
deps: {
configApi: configApiRef,
discoveryApi: discoveryApiRef,
identityApi: identityApiRef
},
factory: ({ configApi, discoveryApi, identityApi }) => GitlabCIClient.setupAPI({
discoveryApi,
identityApi,
codeOwnersPath: configApi.getOptionalString(
"gitlab.defaultCodeOwnersPath"
),
readmePath: configApi.getOptionalString(
"gitlab.defaultReadmePath"
)
})
})
]
});
const EntityGitlabContent = gitlabPlugin.provide(
createRoutableExtension({
name: "EntityGitlabContent",
component: () => import('./index-f78e0833.esm.js').then((m) => m.GitlabCI),
mountPoint: rootRouteRef
})
);
const EntityGitlabLanguageCard = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabLanguageCard",
component: {
lazy: () => import('./index-d6520eff.esm.js').then(
(m) => m.LanguagesCard
)
}
})
);
const EntityGitlabPeopleCard = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabPeopleCard",
component: {
lazy: () => import('./index-d6520eff.esm.js').then((m) => m.PeopleCard)
}
})
);
const EntityGitlabMergeRequestsTable = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabMergeRequestsTable",
component: {
lazy: () => import('./index-d6520eff.esm.js').then(
(m) => m.MergeRequestsTable
)
}
})
);
const EntityGitlabMergeRequestStatsCard = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabMergeRequestStatsCard",
component: {
lazy: () => import('./index-d6520eff.esm.js').then(
(m) => m.MergeRequestStats
)
}
})
);
const EntityGitlabPipelinesTable = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabPipelinesTable",
component: {
lazy: () => import('./index-d6520eff.esm.js').then(
(m) => m.PipelinesTable
)
}
})
);
const EntityGitlabReleasesCard = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabReleasesCard",
component: {
lazy: () => import('./index-d6520eff.esm.js').then(
(m) => m.ReleasesCard
)
}
})
);
const EntityGitlabIssuesTable = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabIssuesTable",
component: {
lazy: () => import('./index-d6520eff.esm.js').then((m) => m.IssuesTable)
}
})
);
const EntityGitlabReadmeCard = gitlabPlugin.provide(
createComponentExtension({
name: "EntityGitlabReadmeCard",
component: {
lazy: () => import('./index-d6520eff.esm.js').then((m) => m.ReadmeCard)
}
})
);
const GITLAB_ANNOTATION_PROJECT_ID = "gitlab.com/project-id";
const GITLAB_ANNOTATION_PROJECT_SLUG = "gitlab.com/project-slug";
const GITLAB_ANNOTATION_INSTANCE = "gitlab.com/instance";
const GITLAB_ANNOTATION_CODEOWNERS_PATH = "gitlab.com/codeowners-path";
const GITLAB_ANNOTATION_README_PATH = "gitlab.com/readme-path";
const gitlabProjectId = () => {
var _a, _b;
const { entity } = useEntity();
const project_id = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[GITLAB_ANNOTATION_PROJECT_ID]) != null ? _b : "";
return project_id;
};
const gitlabProjectSlug = () => {
var _a, _b;
const { entity } = useEntity();
const project_slug = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[GITLAB_ANNOTATION_PROJECT_SLUG]) != null ? _b : "";
return project_slug;
};
const gitlabInstance = () => {
var _a, _b;
const { entity } = useEntity();
const instance = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[GITLAB_ANNOTATION_INSTANCE]) != null ? _b : "";
return instance;
};
const gitlabCodeOwnerPath = () => {
var _a, _b;
const { entity } = useEntity();
const codeowners_path = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[GITLAB_ANNOTATION_CODEOWNERS_PATH]) != null ? _b : "";
return codeowners_path;
};
const gitlabReadmePath = () => {
var _a, _b;
const { entity } = useEntity();
const readme_path = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[GITLAB_ANNOTATION_README_PATH]) != null ? _b : "";
return readme_path;
};
const colors = {
"1C Enterprise": {
color: "#814CCC"
},
"4D": {
color: "inherit"
},
ABAP: {
color: "#E8274B"
},
ActionScript: {
color: "#882B0F"
},
Ada: {
color: "#02f88c"
},
Agda: {
color: "#315665"
},
"AGS Script": {
color: "#B9D9FF"
},
AL: {
color: "#3AA2B5"
},
Alloy: {
color: "#64C800"
},
"Alpine Abuild": {
color: "inherit"
},
AMPL: {
color: "#E6EFBB"
},
AngelScript: {
color: "#C7D7DC"
},
ANTLR: {
color: "#9DC3FF"
},
Apex: {
color: "#1797c0"
},
"API Blueprint": {
color: "#2ACCA8"
},
APL: {
color: "#5A8164"
},
"Apollo Guidance Computer": {
color: "#0B3D91"
},
AppleScript: {
color: "#101F1F"
},
Arc: {
color: "#aa2afe"
},
ASL: {
color: "inherit"
},
"ASP.NET": {
color: "#9400ff"
},
AspectJ: {
color: "#a957b0"
},
Assembly: {
color: "#6E4C13"
},
Asymptote: {
color: "#ff0000"
},
ATS: {
color: "#1ac620"
},
Augeas: {
color: "inherit"
},
AutoHotkey: {
color: "#6594b9"
},
AutoIt: {
color: "#1C3552"
},
Awk: {
color: "inherit"
},
Ballerina: {
color: "#FF5000"
},
Batchfile: {
color: "#C1F12E"
},
Befunge: {
color: "inherit"
},
Bison: {
color: "#6A463F"
},
BitBake: {
color: "inherit"
},
Blade: {
color: "#f7523f"
},
BlitzBasic: {
color: "inherit"
},
BlitzMax: {
color: "#cd6400"
},
Bluespec: {
color: "inherit"
},
Boo: {
color: "#d4bec1"
},
Brainfuck: {
color: "#2F2530"
},
Brightscript: {
color: "inherit"
},
C: {
color: "#555555"
},
"C#": {
color: "#178600"
},
"C++": {
color: "#f34b7d"
},
"C2hs Haskell": {
color: "inherit"
},
"Cap'n Proto": {
color: "inherit"
},
CartoCSS: {
color: "inherit"
},
Ceylon: {
color: "#dfa535"
},
Chapel: {
color: "#8dc63f"
},
Charity: {
color: "inherit"
},
ChucK: {
color: "inherit"
},
Cirru: {
color: "#ccccff"
},
Clarion: {
color: "#db901e"
},
"Classic ASP": {
color: "#6a40fd"
},
Clean: {
color: "#3F85AF"
},
Click: {
color: "#E4E6F3"
},
CLIPS: {
color: "inherit"
},
Clojure: {
color: "#db5855"
},
CMake: {
color: "inherit"
},
COBOL: {
color: "inherit"
},
CodeQL: {
color: "inherit"
},
CoffeeScript: {
color: "#244776"
},
ColdFusion: {
color: "#ed2cd6"
},
"ColdFusion CFC": {
color: "#ed2cd6"
},
"Common Lisp": {
color: "#3fb68b"
},
"Common Workflow Language": {
color: "#B5314C"
},
"Component Pascal": {
color: "#B0CE4E"
},
Cool: {
color: "inherit"
},
Coq: {
color: "inherit"
},
Crystal: {
color: "#000100"
},
CSON: {
color: "#244776"
},
Csound: {
color: "inherit"
},
"Csound Document": {
color: "inherit"
},
"Csound Score": {
color: "inherit"
},
CSS: {
color: "#563d7c"
},
Cuda: {
color: "#3A4E3A"
},
CWeb: {
color: "inherit"
},
Cycript: {
color: "inherit"
},
Cython: {
color: "inherit"
},
D: {
color: "#ba595e"
},
Dafny: {
color: "#FFEC25"
},
Dart: {
color: "#00B4AB"
},
Gnuplot: {
color: "#f0a9f0"
},
DataWeave: {
color: "#003a52"
},
Dhall: {
color: "#dfafff"
},
"DIGITAL Command Language": {
color: "inherit"
},
DM: {
color: "#447265"
},
Dockerfile: {
color: "#384d54"
},
Dogescript: {
color: "#cca760"
},
DTrace: {
color: "inherit"
},
Dylan: {
color: "#6c616e"
},
E: {
color: "#ccce35"
},
eC: {
color: "#913960"
},
ECL: {
color: "#8a1267"
},
ECLiPSe: {
color: "inherit"
},
Eiffel: {
color: "#4d6977"
},
EJS: {
color: "#a91e50"
},
Elixir: {
color: "#6e4a7e"
},
Elm: {
color: "#60B5CC"
},
"Emacs Lisp": {
color: "#c065db"
},
EmberScript: {
color: "#FFF4F3"
},
EQ: {
color: "#a78649"
},
Erlang: {
color: "#B83998"
},
"F#": {
color: "#b845fc"
},
"F*": {
color: "#572e30"
},
Factor: {
color: "#636746"
},
Fancy: {
color: "#7b9db4"
},
Fantom: {
color: "#14253c"
},
Faust: {
color: "#c37240"
},
"Filebench WML": {
color: "inherit"
},
Filterscript: {
color: "inherit"
},
fish: {
color: "inherit"
},
FLUX: {
color: "#88ccff"
},
Forth: {
color: "#341708"
},
Fortran: {
color: "#4d41b1"
},
"Fortran Free Form": {
color: "inherit"
},
FreeMarker: {
color: "#0050b2"
},
Frege: {
color: "#00cafe"
},
Futhark: {
color: "#5f021f"
},
"G-code": {
color: "#D08CF2"
},
"Game Maker Language": {
color: "#71b417"
},
GAML: {
color: "#FFC766"
},
GAMS: {
color: "inherit"
},
GAP: {
color: "inherit"
},
"GCC Machine Description": {
color: "inherit"
},
GDB: {
color: "inherit"
},
GDScript: {
color: "#355570"
},
Genie: {
color: "#fb855d"
},
Genshi: {
color: "inherit"
},
"Gentoo Ebuild": {
color: "inherit"
},
"Gentoo Eclass": {
color: "inherit"
},
Gherkin: {
color: "#5B2063"
},
GLSL: {
color: "inherit"
},
Glyph: {
color: "#c1ac7f"
},
Go: {
color: "#00ADD8"
},
Golo: {
color: "#88562A"
},
Gosu: {
color: "#82937f"
},
Grace: {
color: "inherit"
},
"Grammatical Framework": {
color: "#ff0000"
},
GraphQL: {
color: "#e10098"
},
Groovy: {
color: "#e69f56"
},
"Groovy Server Pages": {
color: "inherit"
},
Hack: {
color: "#878787"
},
Haml: {
color: "#ece2a9"
},
Handlebars: {
color: "#f7931e"
},
Harbour: {
color: "#0e60e3"
},
Haskell: {
color: "#5e5086"
},
Haxe: {
color: "#df7900"
},
HCL: {
color: "#00dfd4"
},
HiveQL: {
color: "#dce200"
},
HLSL: {
color: "inherit"
},
HolyC: {
color: "#ffefaf"
},
HTML: {
color: "#e34c26"
},
Hy: {
color: "#7790B2"
},
HyPhy: {
color: "inherit"
},
IDL: {
color: "#a3522f"
},
Idris: {
color: "#b30000"
},
"IGOR Pro": {
color: "#0000cc"
},
"Inform 7": {
color: "inherit"
},
"Inno Setup": {
color: "inherit"
},
Io: {
color: "#a9188d"
},
Ioke: {
color: "#078193"
},
Isabelle: {
color: "#FEFE00"
},
"Isabelle ROOT": {
color: "inherit"
},
J: {
color: "#9EEDFF"
},
Jasmin: {
color: "inherit"
},
Java: {
color: "#b07219"
},
"Java Server Pages": {
color: "inherit"
},
JavaScript: {
color: "#f1e05a"
},
"JavaScript+ERB": {
color: "inherit"
},
JFlex: {
color: "#DBCA00"
},
Jison: {
color: "inherit"
},
"Jison Lex": {
color: "inherit"
},
Jolie: {
color: "#843179"
},
JSONiq: {
color: "#40d47e"
},
Jsonnet: {
color: "#0064bd"
},
JSX: {
color: "inherit"
},
Julia: {
color: "#a270ba"
},
"Jupyter Notebook": {
color: "#DA5B0B"
},
"Kaitai Struct": {
color: "#773b37"
},
Kotlin: {
color: "#F18E33"
},
KRL: {
color: "#28430A"
},
LabVIEW: {
color: "inherit"
},
Lasso: {
color: "#999999"
},
Latte: {
color: "#f2a542"
},
Lean: {
color: "inherit"
},
Less: {
color: "#1d365d"
},
Lex: {
color: "#DBCA00"
},
LFE: {
color: "#4C3023"
},
LilyPond: {
color: "inherit"
},
Limbo: {
color: "inherit"
},
"Literate Agda": {
color: "inherit"
},
"Literate CoffeeScript": {
color: "inherit"
},
"Literate Haskell": {
color: "inherit"
},
LiveScript: {
color: "#499886"
},
LLVM: {
color: "#185619"
},
Logos: {
color: "inherit"
},
Logtalk: {
color: "inherit"
},
LOLCODE: {
color: "#cc9900"
},
LookML: {
color: "#652B81"
},
LoomScript: {
color: "inherit"
},
LSL: {
color: "#3d9970"
},
Lua: {
color: "#000080"
},
M: {
color: "inherit"
},
M4: {
color: "inherit"
},
M4Sugar: {
color: "inherit"
},
Macaulay2: {
color: "#d8ffff"
},
Makefile: {
color: "#427819"
},
Mako: {
color: "inherit"
},
Markdown: {
color: "#083fa1"
},
Marko: {
color: "#42bff2"
},
Mask: {
color: "#f97732"
},
Mathematica: {
color: "inherit"
},
MATLAB: {
color: "#e16737"
},
Max: {
color: "#c4a79c"
},
MAXScript: {
color: "#00a6a6"
},
mcfunction: {
color: "#E22837"
},
Mercury: {
color: "#ff2b2b"
},
Meson: {
color: "#007800"
},
Metal: {
color: "#8f14e9"
},
MiniD: {
color: "inherit"
},
Mirah: {
color: "#c7a938"
},
"mIRC Script": {
color: "#3d57c3"
},
MLIR: {
color: "#5EC8DB"
},
Modelica: {
color: "inherit"
},
"Modula-2": {
color: "inherit"
},
"Modula-3": {
color: "#223388"
},
"Module Management System": {
color: "inherit"
},
Monkey: {
color: "inherit"
},
Moocode: {
color: "inherit"
},
MoonScript: {
color: "inherit"
},
"Motorola 68K Assembly": {
color: "inherit"
},
MQL4: {
color: "#62A8D6"
},
MQL5: {
color: "#4A76B8"
},
MTML: {
color: "#b7e1f4"
},
MUF: {
color: "inherit"
},
mupad: {
color: "inherit"
},
Myghty: {
color: "inherit"
},
NASL: {
color: "inherit"
},
NCL: {
color: "#28431f"
},
Nearley: {
color: "#990000"
},
Nemerle: {
color: "#3d3c6e"
},
nesC: {
color: "#94B0C7"
},
NetLinx: {
color: "#0aa0ff"
},
"NetLinx+ERB": {
color: "#747faa"
},
NetLogo: {
color: "#ff6375"
},
NewLisp: {
color: "#87AED7"
},
Nextflow: {
color: "#3ac486"
},
Nim: {
color: "#ffc200"
},
Nit: {
color: "#009917"
},
Nix: {
color: "#7e7eff"
},
NSIS: {
color: "inherit"
},
Nu: {
color: "#c9df40"
},
NumPy: {
color: "#9C8AF9"
},
"Objective-C": {
color: "#438eff"
},
"Objective-C++": {
color: "#6866fb"
},
"Objective-J": {
color: "#ff0c5a"
},
ObjectScript: {
color: "#424893"
},
OCaml: {
color: "#3be133"
},
Odin: {
color: "#60AFFE"
},
Omgrofl: {
color: "#cabbff"
},
ooc: {
color: "#b0b77e"
},
Opa: {
color: "inherit"
},
Opal: {
color: "#f7ede0"
},
"Open Policy Agent": {
color: "inherit"
},
OpenCL: {
color: "inherit"
},
"OpenEdge ABL": {
color: "inherit"
},
OpenQASM: {
color: "#AA70FF"
},
"OpenRC runscript": {
color: "inherit"
},
OpenSCAD: {
color: "inherit"
},
Ox: {
color: "inherit"
},
Oxygene: {
color: "#cdd0e3"
},
Oz: {
color: "#fab738"
},
P4: {
color: "#7055b5"
},
Pan: {
color: "#cc0000"
},
Papyrus: {
color: "#6600cc"
},
Parrot: {
color: "#f3ca0a"
},
"Parrot Assembly": {
color: "inherit"
},
"Parrot Internal Representation": {
color: "inherit"
},
Pascal: {
color: "#E3F171"
},
Pawn: {
color: "#dbb284"
},
Pep8: {
color: "#C76F5B"
},
Perl: {
color: "#0298c3"
},
PHP: {
color: "#4F5D95"
},
PicoLisp: {
color: "inherit"
},
PigLatin: {
color: "#fcd7de"
},
Pike: {
color: "#005390"
},
PLpgSQL: {
color: "inherit"
},
PLSQL: {
color: "#dad8d8"
},
PogoScript: {
color: "#d80074"
},
Pony: {
color: "inherit"
},
PostScript: {
color: "#da291c"
},
"POV-Ray SDL": {
color: "inherit"
},
PowerBuilder: {
color: "#8f0f8d"
},
PowerShell: {
color: "#012456"
},
Prisma: {
color: "#0c344b"
},
Processing: {
color: "#0096D8"
},
Prolog: {
color: "#74283c"
},
"Propeller Spin": {
color: "#7fa2a7"
},
Pug: {
color: "#a86454"
},
Puppet: {
color: "#302B6D"
},
PureBasic: {
color: "#5a6986"
},
PureScript: {
color: "#1D222D"
},
Python: {
color: "#3572A5"
},
"Python console": {
color: "inherit"
},
q: {
color: "#0040cd"
},
"Q#": {
color: "#fed659"
},
QMake: {
color: "inherit"
},
QML: {
color: "#44a51c"
},
"Qt Script": {
color: "#00b841"
},
Quake: {
color: "#882233"
},
R: {
color: "#198CE7"
},
Racket: {
color: "#3c5caa"
},
Ragel: {
color: "#9d5200"
},
Raku: {
color: "#0000fb"
},
RAML: {
color: "#77d9fb"
},
Rascal: {
color: "#fffaa0"
},
REALbasic: {
color: "inherit"
},
Reason: {
color: "#ff5847"
},
Rebol: {
color: "#358a5b"
},
Red: {
color: "#f50000"
},
Redcode: {
color: "inherit"
},
"Ren'Py": {
color: "#ff7f7f"
},
RenderScript: {
color: "inherit"
},
REXX: {
color: "inherit"
},
Ring: {
color: "#2D54CB"
},
Riot: {
color: "#A71E49"
},
RobotFramework: {
color: "inherit"
},
Roff: {
color: "#ecdebe"
},
Rouge: {
color: "#cc0088"
},
RPC: {
color: "inherit"
},
Ruby: {
color: "#701516"
},
RUNOFF: {
color: "#665a4e"
},
Rust: {
color: "#dea584"
},
Sage: {
color: "inherit"
},
SaltStack: {
color: "#646464"
},
SAS: {
color: "#B34936"
},
Sass: {
color: "#a53b70"
},
Scala: {
color: "#c22d40"
},
Scheme: {
color: "#1e4aec"
},
Scilab: {
color: "inherit"
},
SCSS: {
color: "#c6538c"
},
sed: {
color: "#64b970"
},
Self: {
color: "#0579aa"
},
ShaderLab: {
color: "inherit"
},
Shell: {
color: "#89e051"
},
ShellSession: {
color: "inherit"
},
Shen: {
color: "#120F14"
},
Sieve: {
color: "inherit"
},
Slash: {
color: "#007eff"
},
Slice: {
color: "#003fa2"
},
Slim: {
color: "#2b2b2b"
},
Smali: {
color: "inherit"
},
Smalltalk: {
color: "#596706"
},
Smarty: {
color: "#bedf00"
},
SmPL: {
color: "#c94949"
},
SMT: {
color: "inherit"
},
Solidity: {
color: "#AA6746"
},
SourcePawn: {
color: "#f69e1d"
},
SQF: {
color: "#3F3F3F"
},
SQLPL: {
color: "inherit"
},
Squirrel: {
color: "#800000"
},
"SRecode Template": {
color: "#348a34"
},
Stan: {
color: "#b2011d"
},
"Standard ML": {
color: "#dc566d"
},
Starlark: {
color: "#76d275"
},
Stata: {
color: "inherit"
},
Stylus: {
color: "#ff6347"
},
SuperCollider: {
color: "#46390b"
},
Svelte: {
color: "#ff3e00"
},
SVG: {
color: "#ff9900"
},
Swift: {
color: "#ffac45"
},
SWIG: {
color: "inherit"
},
SystemVerilog: {
color: "#DAE1C2"
},
Tcl: {
color: "#e4cc98"
},
Tcsh: {
color: "inherit"
},
Terra: {
color: "#00004c"
},
TeX: {
color: "#3D6117"
},
Thrift: {
color: "inherit"
},
"TI Program": {
color: "#A0AA87"
},
TLA: {
color: "inherit"
},
TSQL: {
color: "inherit"
},
TSX: {
color: "inherit"
},
Turing: {
color: "#cf142b"
},
Twig: {
color: "#c1d026"
},
TXL: {
color: "inherit"
},
TypeScript: {
color: "#2b7489"
},
"Unified Parallel C": {
color: "#4e3617"
},
"Unix Assembly": {
color: "inherit"
},
Uno: {
color: "#9933cc"
},
UnrealScript: {
color: "#a54c4d"
},
UrWeb: {
color: "inherit"
},
V: {
color: "#4f87c4"
},
Vala: {
color: "#fbe5cd"
},
VBA: {
color: "#867db1"
},
VBScript: {
color: "#15dcdc"
},
VCL: {
color: "#148AA8"
},
Verilog: {
color: "#b2b7f8"
},
VHDL: {
color: "#adb2cb"
},
"Vim script": {
color: "#199f4b"
},
"Visual Basic .NET": {
color: "#945db7"
},
Volt: {
color: "#1F1F1F"
},
Vue: {
color: "#2c3e50"
},
wdl: {
color: "#42f1f4"
},
WebAssembly: {
color: "#04133b"
},
WebIDL: {
color: "inherit"
},
wisp: {
color: "#7582D1"
},
Wollok: {
color: "#a23738"
},
X10: {
color: "#4B6BEF"
},
xBase: {
color: "#403a40"
},
XC: {
color: "#99DA07"
},
Xojo: {
color: "inherit"
},
XProc: {
color: "inherit"
},
XQuery: {
color: "#5232e7"
},
XS: {
color: "inherit"
},
XSLT: {
color: "#EB8CEB"
},
Xtend: {
color: "inherit"
},
Yacc: {
color: "#4B6C4B"
},
YAML: {
color: "#cb171e"
},
YARA: {
color: "#220000"
},
YASnippet: {
color: "#32AB90"
},
ZAP: {
color: "#0d665e"
},
Zeek: {
color: "inherit"
},
ZenScript: {
color: "#00BCD1"
},
Zephir: {
color: "#118f9e"
},
Zig: {
color: "#ec915c"
},
ZIL: {
color: "#dc75e5"
},
Zimpl: {
color: "inherit"
}
};
const useStyles$6 = makeStyles((theme) => ({
infoCard: {
marginBottom: theme.spacing(3),
"& + .MuiAlert-root": {
marginTop: theme.spacing(3)
}
},
barContainer: {
height: theme.spacing(2),
marginBottom: theme.spacing(3),
borderRadius: "4px",
backgroundColor: "transparent",
overflow: "hidden"
},
bar: {
height: "100%",
position: "relative"
},
languageDot: {
width: "10px",
height: "10px",
borderRadius: "50%",
marginRight: theme.spacing(1),
display: "inline-block"
},
label: {
color: "inherit"
}
}));
const LanguagesCard = ({}) => {
const classes = useStyles$6();
let barWidth = 0;
let languageTitle = new String();
const project_id = gitlabProjectId();
const project_slug = gitlabProjectSlug();
const gitlab_instance = gitlabInstance();
const GitlabCIAPI = useApi(GitlabCIApiRef).build(
gitlab_instance || "gitlab.com"
);
const { value, loading, error } = useAsync(async () => {
const projectDetails = await GitlabCIAPI.getProjectDetails(
project_slug
);
const projectId = project_id || (projectDetails == null ? void 0 : projectDetails.id);
const gitlabObj = await GitlabCIAPI.getLanguagesSummary(projectId);
const data = gitlabObj == null ? void 0 : gitlabObj.getLanguagesData;
return data;
});
if (loading) {
return /* @__PURE__ */ React.createElement(Progress, null);
} else if (error) {
return /* @__PURE__ */ React.createElement(Alert, { severity: "error", className: classes.infoCard }, error.message);
}
return value ? /* @__PURE__ */ React.createElement(InfoCard, { title: "Languages" }, /* @__PURE__ */ React.createElement("div", { className: classes.barContainer }, Object.entries(value).map(
(language, index) => {
var _a;
barWidth = barWidth + language[1];
languageTitle = language[0] + " " + language[1] + "%";
return /* @__PURE__ */ React.createElement(
Tooltip,
{
title: languageTitle,
placement: "bottom-end",
key: language[0]
},
/* @__PURE__ */ React.createElement(
"div",
{
className: classes.bar,
key: language[0],
style: {
marginTop: index === 0 ? "0" : `-16px`,
zIndex: Object.keys(value).length - index,
backgroundColor: ((_a = colors[language[0]]) == null ? void 0 : _a.color) || "#333",
width: `${barWidth}%`
}
}
)
);
}
)), Object.entries(value).map((language) => {
var _a;
return /* @__PURE__ */ React.createElement(
Chip,
{
classes: {
label: classes.label
},
label: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
"span",
{
className: classes.languageDot,
style: {
backgroundColor: ((_a = colors[language[0]]) == null ? void 0 : _a.color) || "#333"
}
}
), /* @__PURE__ */ React.createElement("b", null, language[0]), " - ", language[1], "%"),
variant: "outlined",
key: language[0]
}
);
})) : /* @__PURE__ */ React.createElement(InfoCard, { title: "Languages" });
};
const LightTooltip = withStyles({
tooltip: {
backgroundColor: "white",
border: "1px solid lightgrey",
color: "#333",
minWidth: "320px"
}
})(Tooltip);
const PeopleCardEntity = ({ peopleCardEntity }) => {
return /* @__PURE__ */ React.createElement(LightTooltip, { title: peopleCardEntity.name }, /* @__PURE__ */ React.createElement("a", { href: peopleCardEntity.web_url, target: "_blank" }, /* @__PURE__ */ React.createElement(
Avatar,
{
key: peopleCardEntity.name,
alt: peopleCardEntity.name,
src: peopleCardEntity.avatar_url
}
)));
};
const useStyles$5 = makeStyles((theme) => ({
link: {
color: "inherit",
textDecoration: "none",
marginRight: theme.spacing(1),
marginTop: theme.spacing(0)
},
box: {
marginTop: theme.spacing(0),
marginBottom: theme.spacing(1)
},
boxLink: {
marginTop: theme.spacing(0)
},
title: {
marginTop: theme.spacing(0),
marginBottom: theme.spacing(0)
}
}));
const PeopleList = ({ title, peopleObj, deepLink }) => {
const classes = useStyles$5();
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
Box,
{
className: classes.box,
display: "flex",
alignItems: "center",
justifyContent: "space-between"
},
/* @__PURE__ */ React.createElement("h2", { className: classes.title }, title),
deepLink && /* @__PURE__ */ React.createElement(
Box,
{
className: classes.boxLink,
display: "flex",
alignItems: "center"
},
/* @__PURE__ */ React.createElement(
Link,
{
className: classes.link,
to: deepLink.link,
onClick: deepLink.onClick
},
deepLink.title
),
/* @__PURE__ */ React.createElement(ArrowIcon, { fontSize: "small" })
)
), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 1, justifyContent: "flex-start" }, peopleObj == null ? void 0 : peopleObj.map((peopleCardEntity) => /* @__PURE__ */ React.createElement(
Grid,
{
key: peopleCardEntity.email || peopleCardEntity.name,
item: true
},
/* @__PURE__ */ React.createElement(PeopleCardEntity, { peopleCardEntity })
))));
};
const useStyles$4 = makeStyles((theme) => ({
infoCard: {
marginBottom: theme.spacing(3),
"& + .MuiAlert-root": {
marginTop: theme.spacing(3)
}
},
subTitle: {
marginTop: theme.spacing(0)
},
divider: {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2)
}
}));
const PeopleCard = ({}) => {
const classes = useStyles$4();
const project_id = gitlabProjectId();
const project_slug = gitlabProjectSlug();
const gitlab_instance = gitlabInstance();
const codeowners_path = gitlabCodeOwnerPath();
const GitlabCIAPI = useApi(GitlabCIApiRef).build(
gitlab_instance || "gitlab.com"
);
const { value, loading, error } = useAsync(async () => {
const projectDetails = await GitlabCIAPI.getProjectDetails(
project_slug || project_id
);
const projectId = project_id || (projectDetails == null ? void 0 : projectDetails.id);
const gitlabObj = await GitlabCIAPI.getContributorsSummary(projectId);
const contributorData = gitlabObj == null ? void 0 : gitlabObj.getContributorsData;
const projectDetailsData = {
project_web_url: projectDetails == null ? void 0 : projectDetails.web_url,
project_default_branch: projectDetails == null ? void 0 : projectDetails.default_branch
};
let codeOwners = [];
try {
codeOwners = await GitlabCIAPI.getCodeOwners(
projectId,
projectDetailsData.project_default_branch,
codeowners_path
);
} catch (error2) {
codeOwners = void 0;
}
return {
contributors: contributorData,
owners: codeOwners,
projectDetails: projectDetailsData
};
}, []);
const project_web_url = value == null ? void 0 : value.projectDetails.project_web_url;
const project_default_branch = value == null ? void 0 : value.projectDetails.project_default_branch;
const contributorsLink = GitlabCIAPI.getContributorsLink(
project_web_url,
project_default_branch
);
const ownersLink = GitlabCIAPI.getOwnersLink(
project_web_url,
project_default_branch,
codeowners_path
);
const contributorsDeepLink = {
link: contributorsLink,
title: "go to Contributors",
onClick: (e) => {
e.preventDefault();
window.open(contributorsLink);
}
};
const ownersDeepLink = {
link: ownersLink,
title: "go to Owners File",
onClick: (e) => {
e.preventDefault();
window.open(ownersLink);
}
};
if (loading) {
return /* @__PURE__ */ React.createElement(Progress, null);
} else if (error) {
return /* @__PURE__ */ React.createElement(Alert, { severity: "error", className: classes.infoCard }, error.message);
}
return /* @__PURE__ */ React.createElement(InfoCard, { title: "People", className: classes.infoCard }, (value == null ? void 0 : value.owners) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
PeopleList,
{
title: "Owners",
peopleObj: value == null ? void 0 : value.owners,
deepLink: ownersDeepLink
}
), /* @__PURE__ */ React.createElement(Divider, { className: classes.divider })), /* @__PURE__ */ React.createElement(
PeopleList,
{
title: "Contributors",
peopleObj: (value == null ? void 0 : value.contributors) || [],
deepLink: contributorsDeepLink
}
));
};
const useStyles$3 = makeStyles$1((theme) => ({
infoCard: {
marginBottom: theme.spacing(3),
"& + .MuiAlert-root": {
marginTop: theme.spacing(3)
},
"& .MuiCardContent-root": {
padding: theme.spacing(2, 1, 2, 2)
},
"& td": {
whiteSpace: "normal"
}
}
}));
const MergeRequestStats = (props) => {
const [count, setCount] = useState(20);
const classes = useStyles$3();
const project_id = gitlabProjectId();
const project_slug = gitlabProjectSlug();
const gitlab_instance = gitlabInstance();
const GitlabCIAPI = useApi(GitlabCIApiRef).build(
gitlab_instance || "gitlab.com"
);
const mergeStat = {
avgTimeUntilMerge: 0,
closedCount: 0,
mergedCount: 0
};
const { value, loading, error } = useAsync(async () => {
const projectDetails = await GitlabCIAPI.getProjectDetails(
project_slug
);
const projectId = project_id || (projectDetails == null ? void 0 : projectDetails.id);
const gitlabObj = await GitlabCIAPI.getMergeRequestsStatusSummary(
projectId,
count
);
const data = gitlabObj == null ? void 0 : gitlabObj.getMergeRequestsStatusData;
const renderData = { data };
renderData.project_name = await GitlabCIAPI.getProjectName(
projectId
);
if (renderData.data) {
renderData.data.forEach((element) => {
mergeStat.avgTimeUntilMerge += element.merged_at ? new Date(element.merged_at).getTime() - new Date(element.created_at).getTime() : 0;
mergeStat.mergedCount += element.merged_at ? 1 : 0;
mergeStat.closedCount += element.closed_at ? 1 : 0;
});
}
if (mergeStat.mergedCount === 0)
return {
avgTimeUntilMerge: "Never",
mergedToTotalRatio: "0%"
};
const avgTimeUntilMergeDiff = dayjs.duration(
mergeStat.avgTimeUntilMerge / mergeStat.mergedCount
);
const avgTimeUntilMerge = avgTimeUntilMergeDiff.humanize();
return {
avgTimeUntilMerge,
mergedToTotalRatio: `${Math.round(
mergeStat.mergedCount / count * 100
)}%`
};
}, [count]);
if (loading) {
return /* @__PURE__ */ React.createElement(Progress, null);
} else if (error) {
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
}
return value ? /* @__PURE__ */ React.createElement(
InfoCard,
{
title: "Merge requests statistics",
className: classes.infoCard,
variant: props.variant
},
/* @__PURE__ */ React.createElement(Box, { position: "relative" }, /* @__PURE__ */ React.createElement(StructuredMetadataTable, { metadata: value }), /* @__PURE__ */ React.createElement(Box, { display: "flex", justifyContent: "flex-end" }, /* @__PURE__ */ React.createElement(FormControl, null, /* @__PURE__ */ React.createElement(
Select,
{
value: count,
onChange: (event) => setCount(Number(event.target.value))
},
/* @__PURE__ */ React.createElement(MenuItem, { value: 10 }, "10"),
/* @__PURE__ */ React.createElement(MenuItem, { value: 20 }, "20"),
/* @__PURE__ */ React.createElement(MenuItem, { value: 50 }, "50"),
/* @__PURE__ */ React.createElement(MenuItem, { value: 100 }, "100")
), /* @__PURE__ */ React.createElement(FormHelperText, null, "Number of MRs"))))
) : /* @__PURE__ */ React.createElement(InfoCard, { title: "Merge Request Statistics" });
};
var MergeRequestStats$1 = MergeRequestStats;
const useStyles$2 = makeStyles$1(() => ({
open: {
fill: "#22863a"
},
closed: {
fill: "#cb2431"
},
merged: {
fill: "#6f42c1"
},
draft: {
fill: "#6a737d"
}
}));
const StatusOpen = () => {
const classes = useStyles$2();
return /* @__PURE__ */ React.createElement(
"svg",
{
width: "16",
height: "16",
className: classes.open,
viewBox: "0 0 16 16"
},
/* @__PURE__ */ React.createElement(
"path",
{
fillRule: "evenodd",
d: "M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"
}
)
);
};
const StatusClosed = () => {
const classes = useStyles$2();
return /* @__PURE__ */ React.createElement(
"svg",
{
width: "16",
height: "16",
className: classes.closed,
viewBox: "0 0 16 16"
},
/* @__PURE__ */ React.createElement(
"path",
{
fillRule: "evenodd",
d: "M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"
}
)
);
};
const StatusMerged = () => {
const classes = useStyles$2();
return /* @__PURE__ */ React.createElement(
"svg",
{
width: "16",
height: "16",
className: classes.merged,
viewBox: "0 0 16 16"
},
/* @__PURE__ */ React.createElement(
"path",
{
fillRule: "evenodd",
d: "M5 3.254V3.25v.005a.75.75 0 110-.005v.004zm.45 1.9a2.25 2.25 0 10-1.95.218v5.256a2.25 2.25 0 101.5 0V7.123A5.735 5.735 0 009.25 9h1.378a2.251 2.251 0 100-1.5H9.25a4.25 4.25 0 01-3.8-2.346zM12.75 9a.75.75 0 100-1.5.75.75 0 000 1.5zm-8.5 4.5a.75.75 0 100-1.5.75.75 0 000 1.5z"
}
)
);
};
const getStatusIconType = (row) => {
switch (true) {
case row.state === "opened":
return /* @__PURE__ */ React.createElement(Tooltip, { title: "Open" }, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(StatusOpen, null)));
case row.state === "locked":
return /* @__PURE__ */ React.createElement(Tooltip, { title: "Open" }, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(StatusOpen, null)));
case row.state === "merged":
return /* @__PURE__ */ React.createElement(Tooltip, { title: "Merged" }, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(StatusMerged, null)));
case row.state === "closed":
return /* @__PURE__ */ React.createElement(Tooltip, { title: "Closed" }, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(StatusClosed, null)));
default:
return null;
}
};
const useStyles$1 = makeStyles((theme) => ({
infoCard: {
marginBottom: theme.spacing(3),
"& + .MuiAlert-root": {
marginTop: theme.spacing(3)
}
},
releaseTitle: {
...theme.typography.h6,
margin: 0,
marginRight: "0.5rem"
},
releaseTagIcon: {
verticalAlign: "middle"
}
}));
function makeFilter(show) {
switch (show) {
case "patch":
return (value) => {
try {
return prerelease(value.tag_name) == null;
} catch (error) {
return true;
}
};
case "all":
default:
return () => true;
}
}
const ReleasesCard = (props) => {
const { show = "all", limit = 6 } = props;
const classes = useStyles$1();
const project_id = gitlabProjectId();
const project_slug = gitlabProjectSlug();
const gitlab_instance = gitlabInstance();
const GitlabCIAPI = useApi(GitlabCIApiRef).build(
gitlab_instance || "gitlab.com"
);
const { value, loading, error } = useAsync(async () => {
const projectDetails = await GitlabCIAPI.getProjectDetails(
project_slug || project_id
);
const projectDetailsData = {
project_web_url: projectDetails == null ? void 0 : projectDetails.web_url,
project_default_branch: projectDetails == null ? void 0 : projectDetails.default_branch
};
const projectId = project_id || (projectDetails == null ? void 0 : projectDetails.id);
const gitlabObj = await GitlabCIAPI.getReleasesSummary(projectId);
const releaseData = gitlabObj == null ? void 0 : gitlabObj.getReleasesData;
return {
releases: releaseData,
projectDetails: projectDetailsData
};
}, []);
const project_web_url = value == null ? void 0 : value.projectDetails.project_web_url;
if (loading) {
return /* @__PURE__ */ React.createElement(Progress, null);
} else if (error) {
return /* @__PURE__ */ React.createElement(Alert, { severity: "error", className: classes.infoCard }, error.message);
}
let releases = [];
if ((value == null ? void 0 : value.releases) != null) {
value == null ? void 0 : value.releases.filter(makeFilter(show)).sort((a, b) => {
try {
return rcompare(a.tag_name, b.tag_name);
} catch (error2) {
return a.tag_name > b.tag_name ? 1 : -1;
}
}).forEach((release) => {
if (!valid(release.tag_name)) {
releases.push(release);
return;
}
const idx = releases.findIndex((value2) => {
return release.tag_name.startsWith(value2.tag_name);
});
if (idx < 0)
releases.push(r