/* * MIT License * * Copyright (c) 2020-present Cloudogu GmbH and Contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import React from "react"; import { WithTranslation, withTranslation } from "react-i18next"; import styled from "styled-components"; import { Plugin } from "@scm-manager/ui-types"; import { CardColumn, Icon } from "@scm-manager/ui-components"; import PluginAvatar from "./PluginAvatar"; import PluginModal from "./PluginModal"; export const PluginAction = { INSTALL: "install", UPDATE: "update", UNINSTALL: "uninstall" }; type Props = WithTranslation & { plugin: Plugin; refresh: () => void; }; type State = { showInstallModal: boolean; showUpdateModal: boolean; showUninstallModal: boolean; }; const ActionbarWrapper = styled.div` & span + span { margin-left: 0.5rem; } `; const IconWrapper = styled.span` margin-bottom: 0 !important; padding: 0.5rem; border: 1px solid #cdcdcd; // $dark-25 border-radius: 4px; cursor: pointer; pointer-events: all; &:hover { border-color: #9a9a9a; // $dark-50 } `; class PluginEntry extends React.Component { constructor(props: Props) { super(props); this.state = { showInstallModal: false, showUpdateModal: false, showUninstallModal: false }; } createAvatar = (plugin: Plugin) => { return ; }; toggleModal = (showModal: string) => { const oldValue = this.state[showModal]; this.setState({ [showModal]: !oldValue }); }; createFooterRight = (plugin: Plugin) => { return {plugin.author}; }; isInstallable = () => { const { plugin } = this.props; return plugin._links && plugin._links.install && plugin._links.install.href; }; isUpdatable = () => { const { plugin } = this.props; return plugin._links && plugin._links.update && plugin._links.update.href; }; isUninstallable = () => { const { plugin } = this.props; return plugin._links && plugin._links.uninstall && plugin._links.uninstall.href; }; createActionbar = () => { const { t } = this.props; return ( {this.isInstallable() && ( this.toggleModal("showInstallModal")}> )} {this.isUninstallable() && ( this.toggleModal("showUninstallModal")}> )} {this.isUpdatable() && ( this.toggleModal("showUpdateModal")}> )} ); }; renderModal = () => { const { plugin, refresh } = this.props; if (this.state.showInstallModal && this.isInstallable()) { return ( this.toggleModal("showInstallModal")} /> ); } else if (this.state.showUpdateModal && this.isUpdatable()) { return ( this.toggleModal("showUpdateModal")} /> ); } else if (this.state.showUninstallModal && this.isUninstallable()) { return ( this.toggleModal("showUninstallModal")} /> ); } else { return null; } }; createPendingSpinner = () => { const { plugin } = this.props; return ; }; render() { const { plugin } = this.props; const avatar = this.createAvatar(plugin); const actionbar = this.createActionbar(); const footerRight = this.createFooterRight(plugin); const modal = this.renderModal(); return ( <> this.toggleModal("showInstallModal") : null} avatar={avatar} title={plugin.displayName ? plugin.displayName : plugin.name} description={plugin.description} contentRight={plugin.pending || plugin.markedForUninstall ? this.createPendingSpinner() : actionbar} footerRight={footerRight} /> {modal} ); } } export default withTranslation("admin")(PluginEntry);