Merge branch 'master' into feat/BCKSTG-93-paragraphs
Signed-off-by: Carlos Esteban Lopez Jaramillo <luchillo17@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { parseEntityRef } from '@backstage/catalog-model';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
@@ -83,7 +84,8 @@ export function AdrSearchResultListItem(props: {
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -100,7 +102,7 @@ export function AdrSearchResultListItem(props: {
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
import { apiDocsConfigRef } from '../../config';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
@@ -28,5 +29,5 @@ export const ApiTypeTitle = (props: { apiEntity: ApiEntity }) => {
|
||||
const definition = config.getApiDefinitionWidget(apiEntity);
|
||||
const type = definition ? definition.title : apiEntity.spec.type;
|
||||
|
||||
return <span>{type}</span>;
|
||||
return <Typography component="span">{type}</Typography>;
|
||||
};
|
||||
|
||||
@@ -42,34 +42,34 @@ export const getBuildResultComponent = (result: number | undefined) => {
|
||||
switch (result) {
|
||||
case BuildResult.Succeeded:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusOK /> Succeeded
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.PartiallySucceeded:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Partially Succeeded
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.Failed:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusError /> Failed
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.Canceled:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Canceled
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.None:
|
||||
default:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Unknown
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -81,36 +81,36 @@ export const getBuildStateComponent = (
|
||||
switch (status) {
|
||||
case BuildStatus.InProgress:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusRunning /> In Progress
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.Completed:
|
||||
return getBuildResultComponent(result);
|
||||
case BuildStatus.Cancelling:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Cancelling
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.Postponed:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusPending /> Postponed
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.NotStarted:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Not Started
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.None:
|
||||
default:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Unknown
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
import { Avatar, Link } from '@backstage/core-components';
|
||||
import { Card, CardContent, CardHeader } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import { AutoCompleteIcon } from '../AutoCompleteIcon';
|
||||
import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
@@ -78,9 +79,9 @@ export const PullRequestCard = ({
|
||||
: undefined;
|
||||
|
||||
const subheader = (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{repoLink} · {creationDate}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
|
||||
const avatar = (
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import {
|
||||
PolicyType,
|
||||
} from '@backstage/plugin-azure-devops-common';
|
||||
import { styled, withStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import CancelIcon from '@material-ui/icons/Cancel';
|
||||
import GroupWorkIcon from '@material-ui/icons/GroupWork';
|
||||
@@ -91,6 +92,7 @@ export const PullRequestCardPolicy = ({
|
||||
policy,
|
||||
}: PullRequestCardPolicyProps) => (
|
||||
<PullRequestCardPolicyContainer>
|
||||
{getPolicyIcon(policy)} <span>{policy.text}</span>
|
||||
{getPolicyIcon(policy)}{' '}
|
||||
<Typography component="span">{policy.text}</Typography>
|
||||
</PullRequestCardPolicyContainer>
|
||||
);
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import PublicIcon from '@material-ui/icons/Public';
|
||||
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
||||
import StartIcon from '@material-ui/icons/PlayArrow';
|
||||
import StopIcon from '@material-ui/icons/Stop';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
@@ -51,7 +52,8 @@ const State = ({ value }: { value: States }) => {
|
||||
};
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: 'block',
|
||||
width: '8px',
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Autocomplete } from '@material-ui/lab';
|
||||
import { TextField, makeStyles } from '@material-ui/core';
|
||||
|
||||
@@ -49,7 +50,9 @@ export const ProjectSelector = ({
|
||||
defaultValue={defaultValue}
|
||||
options={catalogEntities}
|
||||
getOptionLabel={option => option?.metadata?.name}
|
||||
renderOption={option => <span>{option?.metadata?.name}</span>}
|
||||
renderOption={option => (
|
||||
<Typography component="span">{option?.metadata?.name}</Typography>
|
||||
)}
|
||||
renderInput={params => <TextField {...params} label={label} />}
|
||||
onChange={(_, data) => {
|
||||
onChange(data!);
|
||||
|
||||
+9
-7
@@ -577,13 +577,15 @@ export class IncrementalIngestionDatabaseManager {
|
||||
.update('ingestion_mark_id', markId)
|
||||
.whereIn('ref', existingRefsArray);
|
||||
|
||||
await tx('ingestion_mark_entities').insert(
|
||||
newRefs.map(ref => ({
|
||||
id: v4(),
|
||||
ingestion_mark_id: markId,
|
||||
ref,
|
||||
})),
|
||||
);
|
||||
if (newRefs.length > 0) {
|
||||
await tx('ingestion_mark_entities').insert(
|
||||
newRefs.map(ref => ({
|
||||
id: v4(),
|
||||
ingestion_mark_id: markId,
|
||||
ref,
|
||||
})),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -125,11 +125,15 @@ export const EntityPeekAheadPopover = (props: EntityPeekAheadPopoverProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<span onMouseEnter={debouncedHandleMouseEnter}>
|
||||
<span data-testid="trigger" {...bindHover(popupState)}>
|
||||
<Typography component="span" onMouseEnter={debouncedHandleMouseEnter}>
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid="trigger"
|
||||
{...bindHover(popupState)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
{isHovered && (
|
||||
<HoverPopover
|
||||
PaperProps={{
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Popover,
|
||||
Tooltip,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import BugReportIcon from '@material-ui/icons/BugReport';
|
||||
@@ -114,19 +115,21 @@ export function EntityContextMenu(props: EntityContextMenuProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded={!!anchorEl}
|
||||
role="button"
|
||||
onClick={onOpen}
|
||||
data-testid="menu-button"
|
||||
className={classes.button}
|
||||
id="long-menu"
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
<Tooltip title="More" arrow>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded={!!anchorEl}
|
||||
role="button"
|
||||
onClick={onOpen}
|
||||
data-testid="menu-button"
|
||||
className={classes.button}
|
||||
id="long-menu"
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Popover
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={onClose}
|
||||
|
||||
@@ -118,9 +118,9 @@ export function StatusChart(props: StatusChartProps) {
|
||||
: percentOrCount;
|
||||
|
||||
return [
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{label}: {valueText}
|
||||
</span>,
|
||||
</Typography>,
|
||||
null,
|
||||
];
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ import React, { CSSProperties } from 'react';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import humanizeDuration from 'humanize-duration';
|
||||
import { capitalize } from 'lodash';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
const infoText: CSSProperties = { color: 'InfoText' };
|
||||
|
||||
@@ -60,11 +61,19 @@ function formatDateTimeShort(milliseconds: number) {
|
||||
}
|
||||
|
||||
export function labelFormatter(epoch: number) {
|
||||
return <span style={infoText}>{formatDateTimeShort(epoch)}</span>;
|
||||
return (
|
||||
<Typography component="span" style={infoText}>
|
||||
{formatDateTimeShort(epoch)}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function labelFormatterWithoutTime(epoch: number) {
|
||||
return <span style={infoText}>{formatDateShort(epoch)}</span>;
|
||||
return (
|
||||
<Typography component="span" style={infoText}>
|
||||
{formatDateShort(epoch)}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function tickFormatterX(epoch: number) {
|
||||
@@ -88,12 +97,12 @@ export function tickFormatterY(duration: number) {
|
||||
|
||||
export function tooltipValueFormatter(durationOrCount: number, name: string) {
|
||||
return [
|
||||
<span style={infoText}>
|
||||
<Typography component="span" style={infoText}>
|
||||
{capitalize(name)}:{' '}
|
||||
{name.endsWith(' count')
|
||||
? durationOrCount
|
||||
: formatDuration(durationOrCount)}
|
||||
</span>,
|
||||
</Typography>,
|
||||
null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ export const AlertInsightsHeader = ({
|
||||
<ScrollAnchor id={DefaultNavigation.AlertInsightsHeader} />
|
||||
<Typography variant="h4" align="center">
|
||||
{title}{' '}
|
||||
<span role="img" aria-label="direct-hit">
|
||||
<Typography component="span" role="img" aria-label="direct-hit">
|
||||
🎯
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
{subtitle}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { CurrencyType, Duration, GrowthType } from '../../types';
|
||||
import { ChangeStatistic } from '@backstage/plugin-cost-insights-common';
|
||||
import { rateOf } from '../../utils/currency';
|
||||
@@ -59,48 +60,52 @@ export const CostGrowth = (props: CostGrowthProps) => {
|
||||
});
|
||||
|
||||
if (engineers < engineerThreshold) {
|
||||
return <span className={classes}>Negligible</span>;
|
||||
return (
|
||||
<Typography component="span" className={classes}>
|
||||
Negligible
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
if (currency.kind === CurrencyType.USD) {
|
||||
// Do not display percentage if ratio cannot be calculated
|
||||
if (isNaN(ratio)) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
~{currency.prefix}
|
||||
{formatCurrency(converted)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
{formatPercent(ratio)} or ~{currency.prefix}
|
||||
{formatCurrency(converted)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
if (amount < 1) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
less than {indefiniteArticleOf(['a', 'an'], currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
// Do not display percentage if ratio cannot be calculated
|
||||
if (isNaN(ratio)) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
~{formatCurrency(converted, currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
{formatPercent(ratio)} or ~{formatCurrency(converted, currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -46,9 +46,9 @@ const CostInsightsHeaderNoData = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="flushed-face">
|
||||
<Typography component="span" role="img" aria-label="flushed-face">
|
||||
😳
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Well this is awkward
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -76,9 +76,9 @@ const CostInsightsHeaderAlerts = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="magnifying-glass">
|
||||
<Typography component="span" role="img" aria-label="magnifying-glass">
|
||||
🔎
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
You have {alerts} thing{alerts > 1 && 's'} to look into
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -101,9 +101,9 @@ const CostInsightsHeaderNoAlerts = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" gutterBottom align="center">
|
||||
<span role="img" aria-label="thumbs-up">
|
||||
<Typography component="span" role="img" aria-label="thumbs-up">
|
||||
👍
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Your team is doing great
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -120,9 +120,9 @@ export const CostInsightsHeaderNoGroups = () => {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="flushed-face">
|
||||
<Typography component="span" role="img" aria-label="flushed-face">
|
||||
😳
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Well this is awkward
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
Select,
|
||||
SelectProps,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Currency, CurrencyType } from '../../types';
|
||||
import { findAlways } from '../../utils/assert';
|
||||
import { useSelectStyles as useStyles } from '../../utils/styles';
|
||||
@@ -73,9 +74,9 @@ export const CurrencySelect = ({
|
||||
key={c.kind || NULL_VALUE}
|
||||
value={c.kind || NULL_VALUE}
|
||||
>
|
||||
<span role="img" aria-label={c.label}>
|
||||
<Typography component="span" role="img" aria-label={c.label}>
|
||||
{c.label}
|
||||
</span>
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
@@ -59,9 +59,14 @@ export const LegendItem = (props: PropsWithChildren<LegendItemProps>) => {
|
||||
}
|
||||
placement="top-start"
|
||||
>
|
||||
<span role="img" aria-label="help" className={classes.helpIcon}>
|
||||
<Typography
|
||||
component="span"
|
||||
role="img"
|
||||
aria-label="help"
|
||||
className={classes.helpIcon}
|
||||
>
|
||||
<HelpOutlineOutlinedIcon fontSize="small" />
|
||||
</span>
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -30,9 +30,9 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Sustainability{' '}
|
||||
<span role="img" aria-label="globe">
|
||||
<Typography component="span" role="img" aria-label="globe">
|
||||
🌎
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Reducing cloud usage improves our carbon footprint.
|
||||
@@ -44,9 +44,13 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Revenue{' '}
|
||||
<span role="img" aria-label="money-with-wings">
|
||||
<Typography
|
||||
component="span"
|
||||
role="img"
|
||||
aria-label="money-with-wings"
|
||||
>
|
||||
💸
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Keeping cloud costs well-tuned prevents infrastructure from eating
|
||||
@@ -59,9 +63,9 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Innovation{' '}
|
||||
<span role="img" aria-label="medal">
|
||||
<Typography component="span" role="img" aria-label="medal">
|
||||
🥇
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
The more we save, the more we can reinvest in speed and
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import pluralize from 'pluralize';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { KubernetesMigrationAlertCard } from '../components';
|
||||
import { CostInsightsApi } from '../../api';
|
||||
import {
|
||||
@@ -91,11 +92,11 @@ export class KubernetesMigrationAlert implements KubernetesMigrationApi {
|
||||
|
||||
get title() {
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
Consider migrating{' '}
|
||||
{pluralize('service', this.data.services.length, true)} to Kubernetes{' '}
|
||||
<Lifecycle shorthand />
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,10 @@ export const ServiceDetailsCard = () => {
|
||||
{!showServiceDetails && !loading && (
|
||||
<div className={classes.warning}>
|
||||
<WarningIcon />
|
||||
<span>This service does not exist in FireHydrant.</span>
|
||||
|
||||
<Typography component="span">
|
||||
This service does not exist in FireHydrant.
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
{showServiceDetails && (
|
||||
@@ -251,7 +254,7 @@ export const ServiceDetailsCard = () => {
|
||||
<AddIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>Declare an incident</span>
|
||||
<Typography component="span">Declare an incident</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
@@ -267,7 +270,7 @@ export const ServiceDetailsCard = () => {
|
||||
<WhatshotIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>View all incidents</span>
|
||||
<Typography component="span">View all incidents</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
@@ -284,7 +287,7 @@ export const ServiceDetailsCard = () => {
|
||||
<NotesIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>View Service Details</span>
|
||||
<Typography component="span">View Service Details</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
|
||||
@@ -18,6 +18,7 @@ import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Grid, Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { DateTime } from 'luxon';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
@@ -199,7 +200,9 @@ export const FossaCard = (props: { variant?: InfoCardVariants }) => {
|
||||
<Grid item className={classes.lastAnalyzed}>
|
||||
Based on {value.dependencyCount} Dependencies on branch{' '}
|
||||
<Tooltip title="The default branch can be changed by a FOSSA admin.">
|
||||
<span className={classes.branch}>{value.projectDefaultBranch}</span>
|
||||
<Typography className={classes.branch}>
|
||||
{value.projectDefaultBranch}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
.
|
||||
</Grid>
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Skeleton } from '@material-ui/lab';
|
||||
import { DateTime } from 'luxon';
|
||||
import * as React from 'react';
|
||||
@@ -140,11 +141,11 @@ const columns: TableColumn<FossaRow>[] = [
|
||||
DateTime.DATETIME_MED,
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{DateTime.fromISO(details.timestamp).toRelative({
|
||||
locale: 'en',
|
||||
})}
|
||||
</span>
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
)
|
||||
);
|
||||
|
||||
@@ -39,11 +39,17 @@ import { Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
const LongText = ({ text, max }: { text: string; max: number }) => {
|
||||
if (text.length < max) {
|
||||
return <span>{text}</span>;
|
||||
return (
|
||||
<Typography color="primary" component="span">
|
||||
{text}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip title={text}>
|
||||
<span>{text.slice(0, max)}...</span>
|
||||
<Typography color="primary" component="span">
|
||||
{text.slice(0, max)}...
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import { grey } from '@material-ui/core/colors';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import CallSplitIcon from '@material-ui/icons/CallSplit';
|
||||
import ChatIcon from '@material-ui/icons/Chat';
|
||||
import DynamicFeedIcon from '@material-ui/icons/DynamicFeed';
|
||||
@@ -35,29 +36,31 @@ export const Differ = ({ current, next, icon }: DifferProps) => {
|
||||
return (
|
||||
<>
|
||||
{icon && (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<Icon icon={icon} />{' '}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{!!current && (
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid={TEST_IDS.components.differ.current}
|
||||
style={{ color: grey[700] }}
|
||||
>
|
||||
{current ?? 'None'}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{current && next && <span>{' → '}</span>}
|
||||
{current && next && <Typography component="span">{' → '}</Typography>}
|
||||
|
||||
{next && (
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid={TEST_IDS.components.differ.next}
|
||||
style={{ fontWeight: 'bold' }}
|
||||
>
|
||||
{next}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
+3
-2
@@ -50,8 +50,9 @@ export function LinearProgressWithLabel(props: {
|
||||
|
||||
const CompletionEmoji = () => {
|
||||
if (status === STATUSES.ONGOING) return null;
|
||||
if (status === STATUSES.FAILURE) return <span>{` ${ICONS.FAILURE} `}</span>;
|
||||
return <span>{` ${ICONS.SUCCESS} `}</span>;
|
||||
if (status === STATUSES.FAILURE)
|
||||
return <Typography component="span">{` ${ICONS.FAILURE} `}</Typography>;
|
||||
return <Typography component="span">{` ${ICONS.SUCCESS} `}</Typography>;
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -42,6 +42,7 @@ describe('Info', () => {
|
||||
|
||||
expect(await findByText(mockReleaseBranch.name)).toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -53,6 +54,7 @@ describe('Info', () => {
|
||||
await findByText(`${mockCalverProject.owner}/${mockCalverProject.repo}`),
|
||||
).toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -63,6 +65,7 @@ describe('Info', () => {
|
||||
expect(await findByText(mockCalverProject.versioningStrategy))
|
||||
.toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -73,6 +76,7 @@ describe('Info', () => {
|
||||
expect(await findByText(mockReleaseCandidateCalver.tagName))
|
||||
.toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
|
||||
@@ -75,12 +75,13 @@ describe('useResponseSteps', () => {
|
||||
"message": <b>
|
||||
Something went wrong
|
||||
|
||||
<span
|
||||
<WithStyles(ForwardRef(Typography))
|
||||
aria-label="fire"
|
||||
component="span"
|
||||
role="img"
|
||||
>
|
||||
🔥
|
||||
</span>
|
||||
</WithStyles(ForwardRef(Typography))>
|
||||
</b>,
|
||||
"secondaryMessage": "Error message: :(",
|
||||
},
|
||||
@@ -108,12 +109,13 @@ describe('useResponseSteps', () => {
|
||||
"message": <b>
|
||||
Something went wrong
|
||||
|
||||
<span
|
||||
<WithStyles(ForwardRef(Typography))
|
||||
aria-label="fire"
|
||||
component="span"
|
||||
role="img"
|
||||
>
|
||||
🔥
|
||||
</span>
|
||||
</WithStyles(ForwardRef(Typography))>
|
||||
</b>,
|
||||
"secondaryMessage": "Error message: unknown",
|
||||
},
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { ResponseStep } from '../types/types';
|
||||
@@ -30,9 +31,9 @@ export function useResponseSteps() {
|
||||
message: (
|
||||
<b>
|
||||
Something went wrong{' '}
|
||||
<span role="img" aria-label="fire">
|
||||
<Typography component="span" role="img" aria-label="fire">
|
||||
🔥
|
||||
</span>
|
||||
</Typography>
|
||||
</b>
|
||||
),
|
||||
secondaryMessage: `Error message: ${
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
useApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { getTimeBasedGreeting } from './timeUtil';
|
||||
@@ -43,9 +44,9 @@ export const WelcomeTitle = () => {
|
||||
|
||||
return (
|
||||
<Tooltip title={greeting.language}>
|
||||
<span>{`${greeting.greeting}${
|
||||
<Typography component="span">{`${greeting.greeting}${
|
||||
profile?.displayName ? `, ${profile?.displayName}` : ''
|
||||
}!`}</span>
|
||||
}!`}</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Website, lighthouseApiRef } from '../../api';
|
||||
import useInterval from 'react-use/lib/useInterval';
|
||||
import {
|
||||
@@ -112,7 +113,9 @@ export const AuditListTable = ({ items }: { items: Website[] }) => {
|
||||
lastReport: (
|
||||
<>
|
||||
<AuditStatusIcon audit={website.lastAudit} />{' '}
|
||||
<span>{website.lastAudit.status.toLocaleUpperCase('en-US')}</span>
|
||||
<Typography component="span">
|
||||
{website.lastAudit.status.toLocaleUpperCase('en-US')}
|
||||
</Typography>
|
||||
</>
|
||||
),
|
||||
lastAuditTriggered: formatTime(website.lastAudit.timeCreated),
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Audit, AuditCompleted, LighthouseCategoryId } from '../../api';
|
||||
import { useWebsiteForEntity } from '../../hooks/useWebsiteForEntity';
|
||||
import AuditStatusIcon from '../AuditStatusIcon';
|
||||
@@ -52,7 +53,7 @@ const LighthouseCategoryScoreStatus = (props: { score: number }) => {
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return <span>N/A</span>;
|
||||
return <Typography component="span">N/A</Typography>;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -128,6 +128,12 @@ export function createFetchRailsAction(options: {
|
||||
description: 'Skip Action Text gem',
|
||||
type: 'boolean',
|
||||
},
|
||||
skipActiveRecord: {
|
||||
title: 'skipActiveRecord',
|
||||
description: 'Skip Active Record files',
|
||||
type: 'boolean',
|
||||
},
|
||||
|
||||
force: {
|
||||
title: 'force',
|
||||
description: 'Overwrite files that already exist',
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ describe('railsArgumentResolver', () => {
|
||||
[{ skipActionMailbox: true }, ['--skip-action-mailbox']],
|
||||
[{ skipActiveStorage: true }, ['--skip-active-storage']],
|
||||
[{ skipActionText: true }, ['--skip-action-text']],
|
||||
[{ skipActiveRecord: true }, ['--skip-active-record']],
|
||||
[{ force: true }, ['--force']],
|
||||
[{ webpacker: 'vue' }, ['--webpack', 'vue']],
|
||||
[{ database: 'postgresql' }, ['--database', 'postgresql']],
|
||||
|
||||
+5
@@ -57,6 +57,7 @@ export type RailsRunOptions = {
|
||||
skipBundle?: boolean;
|
||||
skipTest?: boolean;
|
||||
skipWebpackInstall?: boolean;
|
||||
skipActiveRecord?: boolean;
|
||||
template?: string;
|
||||
webpacker?: Webpacker;
|
||||
};
|
||||
@@ -84,6 +85,10 @@ export const railsArgumentResolver = (
|
||||
argumentsToRun.push('--skip-webpack-install');
|
||||
}
|
||||
|
||||
if (options?.skipActiveRecord) {
|
||||
argumentsToRun.push('--skip-active-record');
|
||||
}
|
||||
|
||||
if (options?.skipTest) {
|
||||
argumentsToRun.push('--skip-test');
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
||||
@@ -0,0 +1,160 @@
|
||||
# scaffolder-backend-module-sentry
|
||||
|
||||
Welcome to the Sentry Module for Scaffolder.
|
||||
|
||||
Here you can find all Sentry related features to improve your scaffolder:
|
||||
|
||||
## Getting started
|
||||
|
||||
You need to configure the action in your backend:
|
||||
|
||||
## From your Backstage root directory
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-sentry
|
||||
```
|
||||
|
||||
Configure the action (you can check
|
||||
the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to
|
||||
see all options):
|
||||
|
||||
```typescript
|
||||
const actions = [
|
||||
createSentryCreateProjectAction({
|
||||
integrations,
|
||||
reader: env.reader,
|
||||
containerRunner,
|
||||
}),
|
||||
];
|
||||
|
||||
return await createRouter({
|
||||
containerRunner,
|
||||
catalogClient,
|
||||
actions,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
reader: env.reader,
|
||||
});
|
||||
```
|
||||
|
||||
You need to define your Sentry API Token in your `app-config.yaml`:
|
||||
|
||||
```yaml
|
||||
scaffolder:
|
||||
sentry:
|
||||
token: ${SENTRY_TOKEN}
|
||||
```
|
||||
|
||||
After that you can use the action in your template:
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: sentry-demo
|
||||
title: Sentry template
|
||||
description: scaffolder sentry app
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
required:
|
||||
- name
|
||||
- owner
|
||||
properties:
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
description: Unique name of the component
|
||||
ui:autofocus: true
|
||||
ui:options:
|
||||
rows: 5
|
||||
owner:
|
||||
title: Owner
|
||||
type: string
|
||||
description: Owner of the component
|
||||
ui:field: OwnerPicker
|
||||
ui:options:
|
||||
catalogFilter:
|
||||
kind: Group
|
||||
system:
|
||||
title: System
|
||||
type: string
|
||||
description: System of the component
|
||||
ui:field: EntityPicker
|
||||
ui:options:
|
||||
catalogFilter:
|
||||
kind: System
|
||||
defaultKind: System
|
||||
|
||||
- title: Choose a location
|
||||
required:
|
||||
- repoUrl
|
||||
- dryRun
|
||||
properties:
|
||||
repoUrl:
|
||||
title: Repository Location
|
||||
type: string
|
||||
ui:field: RepoUrlPicker
|
||||
ui:options:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
dryRun:
|
||||
title: Only perform a dry run, don't publish anything
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
steps:
|
||||
- id: fetch
|
||||
name: Fetch
|
||||
action: fetch:template
|
||||
input:
|
||||
url: https://github.com/TEMPLATE
|
||||
values:
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: create-sentry-project
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Create Sentry Project
|
||||
action: sentry:create-project
|
||||
input:
|
||||
organizationSlug: ORG-SLUG
|
||||
teamSlug: TEAM-SLUG
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: publish
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Publish
|
||||
action: publish:github
|
||||
input:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
description: This is ${{ parameters.name }}
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
|
||||
- id: register
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Register
|
||||
action: catalog:register
|
||||
input:
|
||||
repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
|
||||
catalogInfoPath: '/catalog-info.yaml'
|
||||
|
||||
- name: Results
|
||||
if: ${{ parameters.dryRun }}
|
||||
action: debug:log
|
||||
input:
|
||||
listWorkspace: true
|
||||
|
||||
output:
|
||||
links:
|
||||
- title: Repository
|
||||
url: ${{ steps['publish'].output.remoteUrl }}
|
||||
- title: Open in catalog
|
||||
icon: catalog
|
||||
entityRef: ${{ steps['register'].output.entityRef }}
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
## API Report File for "@backstage/plugin-scaffolder-backend-module-sentry"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { Config } from '@backstage/config';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
|
||||
// @public
|
||||
export function createSentryCreateProjectAction(options: {
|
||||
config: Config;
|
||||
}): TemplateAction<{
|
||||
organizationSlug: string;
|
||||
teamSlug: string;
|
||||
name: string;
|
||||
slug?: string | undefined;
|
||||
authToken?: string | undefined;
|
||||
}>;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@backstage/plugin-scaffolder-backend-module-sentry",
|
||||
"version": "0.0.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "frontend-plugin"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"clean": "backstage-cli package clean",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
"postpack": "backstage-cli package postpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-backend": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/dev-utils": "workspace:^",
|
||||
"@backstage/test-utils": "workspace:^",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^14.0.0",
|
||||
"@types/node": "*",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
/**
|
||||
* Creates the `sentry:craete-project` Scaffolder action.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* See {@link https://backstage.io/docs/features/software-templates/writing-custom-actions}.
|
||||
*
|
||||
* @param options - Configuration of the Sentry API.
|
||||
* @public
|
||||
*/
|
||||
export function createSentryCreateProjectAction(options: { config: Config }) {
|
||||
const { config } = options;
|
||||
|
||||
return createTemplateAction<{
|
||||
organizationSlug: string;
|
||||
teamSlug: string;
|
||||
name: string;
|
||||
slug?: string;
|
||||
authToken?: string;
|
||||
}>({
|
||||
id: 'sentry:project:create',
|
||||
schema: {
|
||||
input: {
|
||||
required: ['organizationSlug', 'teamSlug', 'name'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
organizationSlug: {
|
||||
title: 'The slug of the organization the team belongs to',
|
||||
type: 'string',
|
||||
},
|
||||
teamSlug: {
|
||||
title: 'The slug of the team to create a new project for',
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
title: 'The name for the new project',
|
||||
type: 'string',
|
||||
},
|
||||
slug: {
|
||||
title:
|
||||
'Optional slug for the new project. If not provided a slug is generated from the name',
|
||||
type: 'string',
|
||||
},
|
||||
authToken: {
|
||||
title:
|
||||
'authenticate via bearer auth token. Requires scope: project:write',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async handler(ctx) {
|
||||
const { organizationSlug, teamSlug, name, slug, authToken } = ctx.input;
|
||||
|
||||
const body: any = {
|
||||
name: name,
|
||||
};
|
||||
|
||||
if (slug) {
|
||||
body.slug = slug;
|
||||
}
|
||||
|
||||
const token = authToken
|
||||
? authToken
|
||||
: config.getOptionalString('scaffolder.sentry.token');
|
||||
|
||||
if (!token) {
|
||||
throw new InputError(`No valid sentry token given`);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://sentry.io/api/0/teams/${organizationSlug}/${teamSlug}/projects/`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
);
|
||||
|
||||
const contentType = response.headers.get('content-type');
|
||||
|
||||
if (contentType !== 'application/json') {
|
||||
throw new InputError(
|
||||
`Unexpected Sentry Response Type: ${await response.text()}`,
|
||||
);
|
||||
}
|
||||
|
||||
const code = response.status;
|
||||
const result = await response.json();
|
||||
|
||||
if (code !== 201) {
|
||||
throw new InputError(`Sentry Response was: ${await result.detail}`);
|
||||
}
|
||||
|
||||
ctx.output('id', result.id);
|
||||
ctx.output('result', result);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createSentryCreateProjectAction } from './actions/createProject';
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
Box,
|
||||
Divider,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
|
||||
/**
|
||||
@@ -85,7 +86,8 @@ export const DefaultResultListItemComponent = ({
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -102,7 +104,7 @@ export const DefaultResultListItemComponent = ({
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{secondaryAction && <Box alignItems="flex-end">{secondaryAction}</Box>}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
Paper,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import LaunchIcon from '@material-ui/icons/Launch';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import {
|
||||
@@ -131,7 +132,9 @@ export const Modal = ({ toggleModal }: SearchModalProps) => {
|
||||
}}
|
||||
to={`${getSearchLink()}?query=${term}`}
|
||||
>
|
||||
<span className={classes.viewResultsLink}>View Full Results</span>
|
||||
<Typography component="span" className={classes.viewResultsLink}>
|
||||
View Full Results
|
||||
</Typography>
|
||||
<LaunchIcon color="primary" />
|
||||
</Link>
|
||||
</Grid>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
|
||||
const useStyles = makeStyles((theme: BackstageTheme) => {
|
||||
@@ -29,5 +30,9 @@ const useStyles = makeStyles((theme: BackstageTheme) => {
|
||||
|
||||
export const Value = (props: { value?: string }) => {
|
||||
const classes = useStyles();
|
||||
return <span className={classes.value}>{props.value}</span>;
|
||||
return (
|
||||
<Typography component="span" className={classes.value}>
|
||||
{props.value}
|
||||
</Typography>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ClassNameMap } from '@material-ui/core/styles/withStyles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
import { WithLink } from '../../utils/components';
|
||||
import { RadarDescription } from '../RadarDescription';
|
||||
@@ -50,17 +51,21 @@ export const RadarLegendLink = ({
|
||||
if (description) {
|
||||
return (
|
||||
<>
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
className={classes.entryLink}
|
||||
onClick={handleClickOpen}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyPress={toggle}
|
||||
>
|
||||
<span className={active ? classes.activeEntry : classes.entry}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={active ? classes.activeEntry : classes.entry}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
{open && (
|
||||
<RadarDescription
|
||||
open={open}
|
||||
@@ -75,9 +80,12 @@ export const RadarLegendLink = ({
|
||||
}
|
||||
return (
|
||||
<WithLink url={url} className={classes.entryLink}>
|
||||
<span className={active ? classes.activeEntry : classes.entry}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={active ? classes.activeEntry : classes.entry}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</Typography>
|
||||
</WithLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
import { ResultHighlight } from '@backstage/plugin-search-common';
|
||||
@@ -137,7 +138,8 @@ export const TechDocsSearchResultListItem = (
|
||||
</LinkWrapper>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -154,7 +156,7 @@ export const TechDocsSearchResultListItem = (
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -89,32 +89,30 @@ export const ProviderSettingsItem = (props: {
|
||||
primary={title}
|
||||
secondary={
|
||||
<Tooltip placement="top" arrow title={description}>
|
||||
<span>
|
||||
<Grid container spacing={6}>
|
||||
<Grid item>
|
||||
<ProviderSettingsAvatar size={48} picture={profile.picture} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm container>
|
||||
<Grid item xs container direction="column" spacing={2}>
|
||||
<Grid item xs>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="textPrimary"
|
||||
gutterBottom
|
||||
>
|
||||
{profile.displayName}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{profile.email}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{description}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container spacing={6}>
|
||||
<Grid item>
|
||||
<ProviderSettingsAvatar size={48} picture={profile.picture} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm container>
|
||||
<Grid item xs container direction="column" spacing={2}>
|
||||
<Grid item xs>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="textPrimary"
|
||||
gutterBottom
|
||||
>
|
||||
{profile.displayName}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{profile.email}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{description}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</span>
|
||||
</Grid>
|
||||
</Tooltip>
|
||||
}
|
||||
secondaryTypographyProps={{ noWrap: true, style: { width: '80%' } }}
|
||||
|
||||
Reference in New Issue
Block a user