feat: add configurable edit link next to revision

This commit is contained in:
Mathias Schopmans
2024-03-06 14:03:58 +01:00
committed by Mathias Schopmans
parent 25a714e9f6
commit b7efe8060f
9 changed files with 74 additions and 22 deletions

View File

@@ -60,7 +60,7 @@ The ideal logo is 150px x 60px. For reference have a look at [public/logo.svg](.
Copy the [`config.json`](./data/config.json) next to the `package.json` and adapt it to your needs.
| Attribute | Description |
| --------- | --------------------------------------------------------------------------------- |
| --------- | ------------------------------------------------------------------------------------------------------------------------------ |
| basePath | Set if hosting under a sub-path, otherwise set it to `/`. Default is `/techradar` |
| colors | A map of colors for the radar. Can be any valid CSS color value |
| quadrants | Config of the 4 quadrants of the radar. See config below. |
@@ -70,6 +70,7 @@ Copy the [`config.json`](./data/config.json) next to the `package.json` and adap
| social | Social links in the footer. See config below |
| imprint | URL to the legal information |
| labels | Configure the labels to change the texts and labels of the radar |
| editUrl | (optional) If set, an edit button will be shown next to the revision.<br/> You can use placeholders for `{id}` and `{release}` |
#### `config.quadrants`

View File

@@ -1,5 +1,6 @@
{
"basePath": "/techradar",
"editUrl": "https://github.dev/AOEpeople/techradar/blob/main/radar/{release}/{id}.md",
"colors": {
"foreground": "#fcf2e6",
"background": "#113521",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "aoe_technology_radar",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "aoe_technology_radar",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.5",
"hasInstallScript": true,
"bin": {
"techradar": "bin/techradar.sh"

View File

@@ -1,6 +1,6 @@
{
"name": "aoe_technology_radar",
"version": "4.0.0-alpha.4",
"version": "4.0.0-alpha.5",
"private": true,
"bin": {
"techradar": "./bin/techradar.sh"

View File

@@ -9,10 +9,27 @@
margin: 0 30px 0 0;
}
.editLink {
position: absolute;
top: 10px;
right: 10px;
display: block;
width: 20px;
height: 20px;
opacity: 0;
transition: opacity 0.2s;
}
.revision {
padding: 30px 0 15px 35px;
margin-left: 5px;
margin-left: 20px;
border-left: 1px solid var(--border);
&:hover {
.editLink {
opacity: 1;
}
}
}
.release {
@@ -31,7 +48,7 @@
margin: -15px 0 0 -60px;
}
.icon {
.notMaintainedIcon {
fill: currentColor;
width: 24px;
height: 24px;
@@ -44,6 +61,7 @@
}
.content {
position: relative;
background: var(--content);
color: var(--text);
border-radius: 6px;

View File

@@ -1,9 +1,9 @@
import styles from "./ItemDetail.module.css";
import { RingBadge } from "@/components/Badge/Badge";
import Attention from "@/components/Icons/Attention";
import { Attention, Edit } from "@/components/Icons";
import { Tag } from "@/components/Tags/Tags";
import { getLabel, getReleases } from "@/lib/data";
import { getEditUrl, getLabel, getReleases } from "@/lib/data";
import { Item } from "@/lib/types";
import { cn } from "@/lib/utils";
@@ -31,14 +31,19 @@ export function ItemDetail({ item }: ItemProps) {
{notMaintainedText && isNotMaintained(item.release) && (
<div className={cn(styles.revision, styles.hint)}>
<span className={styles.release}>
<Attention className={styles.icon} />
<Attention className={styles.notMaintainedIcon} />
</span>
<div className={styles.content}>{notMaintainedText}</div>
</div>
)}
<Revision release={item.release} ring={item.ring} body={item.body} />
<Revision
id={item.id}
release={item.release}
ring={item.ring}
body={item.body}
/>
{item.revisions?.map((revision, index) => (
<Revision key={index} {...revision} />
<Revision key={index} id={item.id} {...revision} />
))}
</div>
</>
@@ -46,13 +51,15 @@ export function ItemDetail({ item }: ItemProps) {
}
interface RevisionProps {
id: string;
release: string;
ring: string;
body?: string;
}
function Revision({ release, ring, body }: RevisionProps) {
function Revision({ id, release, ring, body }: RevisionProps) {
const date = new Date(release);
const editLink = getEditUrl({ id, release });
const formattedDate = date.toLocaleDateString("en-US", {
month: "short",
year: "numeric",
@@ -65,6 +72,11 @@ function Revision({ release, ring, body }: RevisionProps) {
<div className={styles.content}>
<RingBadge className={styles.ring} ring={ring} size="large" />
{body ? <div dangerouslySetInnerHTML={{ __html: body }} /> : null}
{editLink && (
<a href={editLink} target="_blank" className={styles.editLink}>
<Edit />
</a>
)}
</div>
</div>
);

6
src/icons/edit.svg Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m18.988 2.012 3 3L19.701 7.3l-3-3zM8 16h3l7.287-7.287-3-3L8 13z"/>
<path
d="M19 19H8.158c-.026 0-.053.01-.079.01-.033 0-.066-.009-.1-.01H5V5h6.847l2-2H5c-1.103 0-2 .896-2 2v14c0 1.104.897 2 2 2h14a2 2 0 0 0 2-2v-8.668l-2 2V19z"/>
</svg>

After

Width:  |  Height:  |  Size: 360 B

View File

@@ -1,6 +1,7 @@
import config from "../../data/config.json";
import data from "../../data/data.json";
import { format } from "@/lib/format";
import { Flag, Item, Quadrant, Ring } from "@/lib/types";
export function getLabel(key: keyof typeof config.labels) {
@@ -47,6 +48,11 @@ export function getTags(): string[] {
return data.tags;
}
export function getEditUrl(props: { id: string; release: string }) {
if (!config.editUrl) return "";
return format(config.editUrl, props);
}
export function getQuadrants(): Quadrant[] {
return config.quadrants.map((q, i) => ({ ...q, position: i + 1 }));
}

View File

@@ -1,5 +1,13 @@
import { getAppName } from "@/lib/data";
// Replaces placeholders in a string with values from a context object
// e.g. format("Hello {name}.", {name: "World"}) => "Hello World."
export function format(text: string, context: Record<string, any>): string {
return text.replace(/{(\w+)}/g, (match, key) => {
return context[key] || match;
});
}
// Format the title of the page
export function formatTitle(...title: string[]): string {
return [...title, getAppName()].join(" | ");