Merge pull request #1440 from scm-manager/feature/unify_key_views

Feature/unify key views
This commit is contained in:
René Pfeuffer
2020-11-26 11:03:30 +01:00
committed by GitHub
19 changed files with 71 additions and 46 deletions

View File

@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add tooltips to short links on repository overview ([#1441](https://github.com/scm-manager/scm-manager/pull/1441))
- Show the date of the last commit for branches in the frontend ([#1439](https://github.com/scm-manager/scm-manager/pull/1439))
- Unify and add description to key view across user settings ([#1440](https://github.com/scm-manager/scm-manager/pull/1440))
## [2.10.1] - 2020-11-24
### Fixed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 285 KiB

View File

@@ -13,7 +13,7 @@ eingegeben werden. Danach muss das neue Passwort zweimal eingegeben werden.
## Öffentliche Schlüssel
Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen Schlüssel hinterlegt werden.
Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen GPG Schlüssel hinterlegt werden.
Zudem können hier die vom SCM-Manager erstellten Signaturschlüssel heruntergeladen werden.
## API Schlüssel

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 275 KiB

View File

@@ -11,9 +11,9 @@ Here the password for the current account can be changed when it is a local acco
external system). To authorize the change, the current password has to be put first. Then the new password has to be
entered twice.
## Öffentliche Schlüssel
## Public Keys
To check signatures for example for commits, public keys can be stored here. Additionally the keys created by
To check signatures (for example for commits), gpg public keys can be stored here. Additionally the keys created by
SCM-Manager can be accessed here, too.
## API keys

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 263 KiB

View File

@@ -79,15 +79,22 @@
}
},
"publicKey": {
"subtitle": "Öffentliche Schlüssel",
"description": "Zum Prüfen von Signaturen für z. B. Commits können hier die entsprechenden öffentlichen GPG Schlüssel hinterlegt werden. Zudem können hier die vom SCM-Manager erstellten Signaturschlüssel heruntergeladen werden.",
"noStoredKeys": "Es wurden keine Schlüssel gefunden.",
"displayName": "Anzeigename",
"raw": "Schlüssel",
"created": "Eingetragen an",
"addKey": "Schlüssel hinzufügen",
"raw": "Schlüssel",
"download": "Herunterladen",
"delete": "Löschen",
"download": "Herunterladen"
"addSubtitle": "Neuen Schlüssel hinzufügen",
"addKey": "Schlüssel hinzufügen"
},
"apiKey": {
"subtitle": "API Schlüssel",
"text1": "Erstelle und verwalte Personal Access Token um auf die REST API zuzugreifen oder diese als Passwort für SCM-Clients zu nutzen. Die Rechte der Token sind auf Repositories und die gewählte Rolle beschränkt.",
"manageRoles": "Sie können die Rollenberechtigungen in der Administration unter „Berechtigungsrollen“ einsehen und neue Rollen anlegen.",
"text2": "Um den Token in REST-Abfragen zu nutzen, übergeben Sie diesen als Cookie mit dem Namen „X-Bearer-Token“. Sie können den Token auch anstelle Ihres Passworts nutzen, um sich mit SCM-Clients anzumelden.",
"noStoredKeys": "Es wurden keine Schlüssel gefunden.",
"displayName": "Anzeigename",
"permissionRole": {
@@ -95,12 +102,10 @@
"help": "Mit der Rolle können Sie die Berechtigung für diesen Schlüssel einschränken"
},
"created": "Eingetragen an",
"addSubtitle": "Neuen Schlüssel hinzufügen",
"addKey": "Schlüssel hinzufügen",
"delete": "Löschen",
"download": "Herunterladen",
"text1": "Erstelle und verwalte Personal Access Token um auf die REST API zuzugreifen oder diese als Passwort für SCM-Clients zu nutzen. Die Rechte der Token sind auf Repositories und die gewählte Rolle beschränkt.",
"manageRoles": "Sie können die Rollenberechtigungen in der Administration unter „Berechtigungsrollen“ einsehen und neue Rollen anlegen.",
"text2": "Um den Token in REST-Abfragen zu nutzen, übergeben Sie diesen als Cookie mit dem Namen „X-Bearer-Token“. Sie können den Token auch anstelle Ihres Passworts nutzen, um sich mit SCM-Clients anzumelden.",
"modal": {
"title": "Schlüssel erzeugt",
"text1": "Ihr neuer API-Schlüssel ist bereit. Sie können diesen als Token für Zugriffe auf die REST-Schnittstelle nutzen oder anstelle Ihres Passworts zum Login mit SCM-Clients nutzen.",

View File

@@ -79,15 +79,22 @@
}
},
"publicKey": {
"subtitle": "Public Keys",
"description": "To check signatures (for example for commits), gpg public keys can be stored here. Additionally the keys created by SCM-Manager can be accessed here, too.",
"noStoredKeys": "No keys found.",
"displayName": "Display Name",
"raw": "Key",
"created": "Created on",
"addKey": "Add key",
"raw": "Key",
"download": "Download",
"delete": "Delete",
"download": "Download"
"addSubtitle": "Add new key",
"addKey": "Add key"
},
"apiKey": {
"subtitle": "API Keys",
"text1": "Create and manage personal access tokens to access the REST API or use as a password for SCM clients. The privileges of these tokens are limited to repositories and the selected role.",
"manageRoles": "You may view and create roles in the administration view “Permission Roles”.",
"text2": "To use the token in a REST request, pass it as a cookie named “X-Bearer-Token”. You may use the token as your password for SCM clients, too.",
"noStoredKeys": "No keys found.",
"displayName": "Display Name",
"permissionRole": {
@@ -95,12 +102,10 @@
"help": "The api key will be restricted to permissions of this role"
},
"created": "Created on",
"addSubtitle": "Add new key",
"addKey": "Add key",
"delete": "Delete",
"download": "Download",
"text1": "Create and manage personal access tokens to access the REST API or use as a password for SCM clients. The privileges of these tokens are limited to repositories and the selected role.",
"manageRoles": "You may view and create roles in the administration view “Permission Roles”.",
"text2": "To use the token in a REST request, pass it as a cookie named “X-Bearer-Token”. You may use the token as your password for SCM clients, too.",
"modal": {
"title": "Key created",
"text1": "Your new API key is ready. You can use it as a bearer token for REST calls or as a password for SCM clients.",

View File

@@ -23,7 +23,7 @@
*/
import React, { FC, useEffect, useState } from "react";
import { apiClient, ErrorNotification, InputField, Level, Loading, SubmitButton } from "@scm-manager/ui-components";
import { apiClient, ErrorNotification, InputField, Level, Loading, SubmitButton, Subtitle } from "@scm-manager/ui-components";
import { useTranslation } from "react-i18next";
import { CONTENT_TYPE_API_KEY } from "./SetApiKeys";
import { connect } from "react-redux";
@@ -105,6 +105,8 @@ const AddApiKey: FC<Props> = ({
return (
<>
<hr />
<Subtitle subtitle={t("apiKey.addSubtitle")} />
{newKeyModal}
<InputField label={t("apiKey.displayName")} value={displayName} onChange={setDisplayName} />
<RoleSelector

View File

@@ -39,8 +39,8 @@ export const ApiKeyEntry: FC<Props> = ({ apiKey, onDelete }) => {
if (apiKey?._links?.delete) {
deleteButton = (
<a className="level-item" onClick={() => onDelete((apiKey._links.delete as Link).href)}>
<span className="icon is-small">
<Icon name="trash" className="fas" title={t("apiKey.delete")} />
<span className="icon">
<Icon name="trash" title={t("apiKey.delete")} color="inherit" />
</span>
</a>
);
@@ -52,7 +52,7 @@ export const ApiKeyEntry: FC<Props> = ({ apiKey, onDelete }) => {
<td>{apiKey.displayName}</td>
<td>{apiKey.permissionRole}</td>
<td className="is-hidden-mobile">
<DateFromNow date={apiKey.created}/>
<DateFromNow date={apiKey.created} />
</td>
<td className="is-darker">{deleteButton}</td>
</tr>

View File

@@ -25,11 +25,10 @@
import { Collection, Links, User, Me } from "@scm-manager/ui-types";
import React, { FC, useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { apiClient, ErrorNotification, Loading } from "@scm-manager/ui-components";
import { apiClient, ErrorNotification, Loading, Subtitle } from "@scm-manager/ui-components";
import ApiKeyTable from "./ApiKeyTable";
import AddApiKey from "./AddApiKey";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
export type ApiKeysCollection = Collection & {
_embedded: {
@@ -51,10 +50,6 @@ type Props = {
user: User | Me;
};
const Subtitle = styled.div`
margin-bottom: 1rem;
`;
const SetApiKeys: FC<Props> = ({ user }) => {
const [t] = useTranslation("users");
const [error, setError] = useState<undefined | Error>();
@@ -94,14 +89,13 @@ const SetApiKeys: FC<Props> = ({ user }) => {
return (
<>
<div className={"media-content"}>
<p>{t("apiKey.text1")} <Link to={"/admin/roles/"}>{t("apiKey.manageRoles")}</Link></p>
<p>{t("apiKey.text2")}</p>
</div>
<hr />
<Subtitle subtitle={t("apiKey.subtitle")} />
<p>
{t("apiKey.text1")} <Link to={"/admin/roles/"}>{t("apiKey.manageRoles")}</Link>
</p>
<p>{t("apiKey.text2")}</p>
<br />
<ApiKeyTable apiKeys={apiKeys} onDelete={onDelete} />
<hr />
<Subtitle className={"media-content"}><h2 className={"title is-4"}>Create new key</h2></Subtitle>
{createLink && <AddApiKey createLink={createLink} refresh={fetchApiKeys} />}
</>
);

View File

@@ -23,7 +23,6 @@
*/
import React, { FC, useState } from "react";
import { User, Link, Links, Collection } from "@scm-manager/ui-types/src";
import {
ErrorNotification,
InputField,
@@ -31,7 +30,8 @@ import {
Textarea,
SubmitButton,
apiClient,
Loading
Loading,
Subtitle
} from "@scm-manager/ui-components";
import { useTranslation } from "react-i18next";
import { CONTENT_TYPE_PUBLIC_KEY } from "./SetPublicKeys";
@@ -77,6 +77,8 @@ const AddPublicKey: FC<Props> = ({ createLink, refresh }) => {
return (
<>
<hr />
<Subtitle subtitle={t("publicKey.addSubtitle")} />
<InputField label={t("publicKey.displayName")} value={displayName} onChange={setDisplayName} />
<Textarea name="raw" label={t("publicKey.raw")} value={raw} onChange={setRaw} />
<Level

View File

@@ -22,24 +22,28 @@
* SOFTWARE.
*/
import React, {FC} from "react";
import {DateFromNow, DeleteButton} from "@scm-manager/ui-components";
import {PublicKey} from "./SetPublicKeys";
import {useTranslation} from "react-i18next";
import {Link} from "@scm-manager/ui-types";
import React, { FC } from "react";
import { DateFromNow, Icon } from "@scm-manager/ui-components";
import { PublicKey } from "./SetPublicKeys";
import { useTranslation } from "react-i18next";
import { Link } from "@scm-manager/ui-types";
type Props = {
publicKey: PublicKey;
onDelete: (link: string) => void;
};
export const PublicKeyEntry: FC<Props> = ({publicKey, onDelete}) => {
export const PublicKeyEntry: FC<Props> = ({ publicKey, onDelete }) => {
const [t] = useTranslation("users");
let deleteButton;
if (publicKey?._links?.delete) {
deleteButton = (
<DeleteButton label={t("publicKey.delete")} action={() => onDelete((publicKey._links.delete as Link).href)}/>
<a className="level-item" onClick={() => onDelete((publicKey._links.delete as Link).href)}>
<span className="icon">
<Icon name="trash" title={t("publicKey.delete")} color="inherit" />
</span>
</a>
);
}
@@ -48,11 +52,18 @@ export const PublicKeyEntry: FC<Props> = ({publicKey, onDelete}) => {
<tr>
<td>{publicKey.displayName}</td>
<td className="is-hidden-mobile">
<DateFromNow date={publicKey.created}/>
<DateFromNow date={publicKey.created} />
</td>
<td className="is-hidden-mobile">{publicKey._links?.raw ?
<a href={(publicKey._links.raw as Link).href}>{publicKey.id}</a> : publicKey.id}</td>
<td>{deleteButton}</td>
<td className="is-hidden-mobile">
{publicKey._links?.raw ? (
<a title={t("publicKey.download")} href={(publicKey._links.raw as Link).href}>
{publicKey.id}
</a>
) : (
publicKey.id
)}
</td>
<td className="is-darker">{deleteButton}</td>
</tr>
</>
);

View File

@@ -24,9 +24,10 @@
import { Collection, Link, Links, User, Me } from "@scm-manager/ui-types";
import React, { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import AddPublicKey from "./AddPublicKey";
import PublicKeyTable from "./PublicKeyTable";
import { apiClient, ErrorNotification, Loading } from "@scm-manager/ui-components";
import { apiClient, ErrorNotification, Loading, Subtitle } from "@scm-manager/ui-components";
export type PublicKeysCollection = Collection & {
_embedded: {
@@ -49,6 +50,7 @@ type Props = {
};
const SetPublicKeys: FC<Props> = ({ user }) => {
const [t] = useTranslation("users");
const [error, setError] = useState<undefined | Error>();
const [loading, setLoading] = useState(false);
const [publicKeys, setPublicKeys] = useState<PublicKeysCollection | undefined>(undefined);
@@ -86,6 +88,9 @@ const SetPublicKeys: FC<Props> = ({ user }) => {
return (
<>
<Subtitle subtitle={t("publicKey.subtitle")} />
<p>{t("publicKey.description")}</p>
<br />
<PublicKeyTable publicKeys={publicKeys} onDelete={onDelete} />
{createLink && <AddPublicKey createLink={createLink} refresh={fetchPublicKeys} />}
</>