mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 08:25:44 +01:00
Add new extension point for repository avatars (#1614)
Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
@@ -33,6 +33,7 @@ The following extension points are provided for the frontend:
|
|||||||
### profile.route
|
### profile.route
|
||||||
### profile.setting
|
### profile.setting
|
||||||
### repo-config.route
|
### repo-config.route
|
||||||
|
### repo-config.details
|
||||||
### repos.branch-details.information
|
### repos.branch-details.information
|
||||||
### repos.content.metadata
|
### repos.content.metadata
|
||||||
- Location: At meta data view for file
|
- Location: At meta data view for file
|
||||||
@@ -46,13 +47,13 @@ The following extension points are provided for the frontend:
|
|||||||
### repositoryRole.role-details.information
|
### repositoryRole.role-details.information
|
||||||
### repository.setting
|
### repository.setting
|
||||||
### repos.repository-avatar
|
### repos.repository-avatar
|
||||||
|
### repos.repository-avatar.primary
|
||||||
- Location: At each repository in repository overview
|
- Location: At each repository in repository overview
|
||||||
- can be used to add avatar for each repository (e.g., to mark repository type)
|
- can be used to add avatar for each repository (e.g., to mark repository type)
|
||||||
|
|
||||||
### repos.repository-details.information
|
### repos.repository-details.information
|
||||||
- Location: At bottom of a single repository view
|
- Location: At bottom of a single repository view
|
||||||
- can be used to show detailed information about the repository (how to clone, e.g.)
|
- can be used to show detailed information about the repository (how to clone, e.g.)
|
||||||
|
|
||||||
### repos.sources.view
|
### repos.sources.view
|
||||||
### roles.route
|
### roles.route
|
||||||
### user.route
|
### user.route
|
||||||
|
|||||||
2
gradle/changelog/repository-avatar-extensionpoint.yaml
Normal file
2
gradle/changelog/repository-avatar-extensionpoint.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- type: added
|
||||||
|
description: New extension points for custom repository avatars ([#1614](https://github.com/scm-manager/scm-manager/pull/1614))
|
||||||
@@ -55824,7 +55824,7 @@ exports[`Storyshots RepositoryEntry Archived 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -55975,7 +55975,7 @@ exports[`Storyshots RepositoryEntry Avatar EP 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -56120,7 +56120,7 @@ exports[`Storyshots RepositoryEntry Before Title EP 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -56268,7 +56268,7 @@ exports[`Storyshots RepositoryEntry Default 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -56413,7 +56413,7 @@ exports[`Storyshots RepositoryEntry Exporting 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -56564,7 +56564,7 @@ exports[`Storyshots RepositoryEntry MultiRepositoryTags 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
@@ -56721,7 +56721,7 @@ exports[`Storyshots RepositoryEntry Quick Link EP 1`] = `
|
|||||||
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
className="CardColumn__AvatarWrapper-sc-1w6lsih-1 lhzEPm media-left"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="image is-64x64"
|
className="RepositoryAvatar__Avatar-uh53vb-0 igMDhE image is-64x64"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
|
|||||||
@@ -27,10 +27,12 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { File } from "@scm-manager/ui-types";
|
import { File } from "@scm-manager/ui-types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleFile: (file: File) => void;
|
handleFile: (file: File, event?: ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
filenamePlaceholder?: string;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FileUpload: FC<Props> = ({ handleFile }) => {
|
const FileUpload: FC<Props> = ({ handleFile, filenamePlaceholder = "", disabled = false }) => {
|
||||||
const [t] = useTranslation("commons");
|
const [t] = useTranslation("commons");
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
|
|
||||||
@@ -41,21 +43,26 @@ const FileUpload: FC<Props> = ({ handleFile }) => {
|
|||||||
className="file-input"
|
className="file-input"
|
||||||
type="file"
|
type="file"
|
||||||
name="resume"
|
name="resume"
|
||||||
|
disabled={disabled}
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
||||||
const uploadedFile = event?.target?.files![0];
|
const uploadedFile = event?.target?.files![0];
|
||||||
// @ts-ignore the uploaded file doesn't match our types
|
// @ts-ignore the uploaded file doesn't match our types
|
||||||
setFile(uploadedFile);
|
setFile(uploadedFile);
|
||||||
// @ts-ignore the uploaded file doesn't match our types
|
// @ts-ignore the uploaded file doesn't match our types
|
||||||
handleFile(uploadedFile);
|
handleFile(uploadedFile, event);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span className="file-cta">
|
<span className="file-cta">
|
||||||
<span className="file-icon">
|
<span className="file-icon">
|
||||||
<i className="fas fa-arrow-circle-up" />
|
<i className="fas fa-arrow-circle-up" />
|
||||||
</span>
|
</span>
|
||||||
<span className="file-label">{t("fileUpload.label")}</span>
|
<span className="file-label has-text-weight-bold">{t("fileUpload.label")}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="file-name">{file?.name || ""}</span>
|
{file?.name ? (
|
||||||
|
<span className="file-name">{file?.name}</span>
|
||||||
|
) : (
|
||||||
|
<span className="file-name has-text-weight-light has-text-grey-light ">{filenamePlaceholder}</span>
|
||||||
|
)}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ type Props = {
|
|||||||
closeFunction: () => void;
|
closeFunction: () => void;
|
||||||
body: ReactNode;
|
body: ReactNode;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
|
closeButtonLabel?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FullSizedModal = styled(Modal)`
|
const FullSizedModal = styled(Modal)`
|
||||||
@@ -42,9 +43,9 @@ const FullSizedModal = styled(Modal)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FullscreenModal: FC<Props> = ({ title, closeFunction, body, active }) => {
|
const FullscreenModal: FC<Props> = ({ title, closeFunction, body, active, closeButtonLabel }) => {
|
||||||
const [t] = useTranslation("repos");
|
const [t] = useTranslation("repos");
|
||||||
const footer = <Button label={t("diff.fullscreen.close")} action={closeFunction} color="grey" />;
|
const footer = <Button label={closeButtonLabel || t("diff.fullscreen.close")} action={closeFunction} color="grey" />;
|
||||||
|
|
||||||
return <FullSizedModal title={title} closeFunction={closeFunction} body={body} footer={footer} active={active} />;
|
return <FullSizedModal title={title} closeFunction={closeFunction} body={body} footer={footer} active={active} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,31 +21,42 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import React from "react";
|
import React, { FC } from "react";
|
||||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||||
import { Repository } from "@scm-manager/ui-types";
|
import { Repository } from "@scm-manager/ui-types";
|
||||||
import { Image } from "@scm-manager/ui-components";
|
import { Image } from "@scm-manager/ui-components";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
const Avatar = styled.p`
|
||||||
|
border-radius: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
repository: Repository;
|
repository: Repository;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RepositoryAvatar extends React.Component<Props> {
|
const renderExtensionPoint = (repository: Repository) => {
|
||||||
render() {
|
return (
|
||||||
const { repository } = this.props;
|
<ExtensionPoint
|
||||||
return (
|
name="repos.repository-avatar.primary"
|
||||||
<p className="image is-64x64">
|
props={{
|
||||||
<ExtensionPoint
|
repository
|
||||||
name="repos.repository-avatar"
|
}}
|
||||||
props={{
|
>
|
||||||
repository
|
<ExtensionPoint
|
||||||
}}
|
name="repos.repository-avatar"
|
||||||
>
|
props={{
|
||||||
<Image src="/images/blib.jpg" alt="Logo" />
|
repository
|
||||||
</ExtensionPoint>
|
}}
|
||||||
</p>
|
>
|
||||||
);
|
<Image src="/images/blib.jpg" alt="Logo" />
|
||||||
}
|
</ExtensionPoint>
|
||||||
}
|
</ExtensionPoint>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const RepositoryAvatar: FC<Props> = ({ repository }) => {
|
||||||
|
return <Avatar className="image is-64x64">{renderExtensionPoint(repository)}</Avatar>;
|
||||||
|
};
|
||||||
|
|
||||||
export default RepositoryAvatar;
|
export default RepositoryAvatar;
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ const EditRepo: FC<Props> = ({ repository }) => {
|
|||||||
<Subtitle subtitle={t("repositoryForm.subtitle")} />
|
<Subtitle subtitle={t("repositoryForm.subtitle")} />
|
||||||
<ErrorNotification error={error} />
|
<ErrorNotification error={error} />
|
||||||
<RepositoryForm repository={repository} loading={isLoading} modifyRepository={update} />
|
<RepositoryForm repository={repository} loading={isLoading} modifyRepository={update} />
|
||||||
|
<ExtensionPoint name="repo-config.details" props={extensionProps} renderAll={true}/>
|
||||||
{repository._links.exportInfo && <ExportRepository repository={repository} />}
|
{repository._links.exportInfo && <ExportRepository repository={repository} />}
|
||||||
<ExtensionPoint name="repo-config.route" props={extensionProps} renderAll={true} />
|
<ExtensionPoint name="repo-config.route" props={extensionProps} renderAll={true} />
|
||||||
<RepositoryDangerZone repository={repository} indexLinks={indexLinks} />
|
<RepositoryDangerZone repository={repository} indexLinks={indexLinks} />
|
||||||
|
|||||||
Reference in New Issue
Block a user