diff --git a/CHANGELOG.md b/CHANGELOG.md index eb72250afd..f69732ae4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Generation of email addresses for users, where none is configured ([#1370](https://github.com/scm-manager/scm-manager/pull/1370)) - Automatic user converter for external users ([#1380](https://github.com/scm-manager/scm-manager/pull/1380)) +- Source code fullscreen view ([#1376](https://github.com/scm-manager/scm-manager/pull/1376)) + +## [2.6.3] - 2020-10-16 +### Fixed +- Missing default permission to manage public gpg keys ([#1377](https://github.com/scm-manager/scm-manager/pull/1377)) ## [2.7.1] - 2020-10-14 ### Fixed @@ -363,3 +368,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [2.6.0]: https://www.scm-manager.org/download/2.6.0 [2.6.1]: https://www.scm-manager.org/download/2.6.1 [2.6.2]: https://www.scm-manager.org/download/2.6.2 +[2.6.3]: https://www.scm-manager.org/download/2.6.3 +[2.7.0]: https://www.scm-manager.org/download/2.7.0 +[2.7.1]: https://www.scm-manager.org/download/2.7.1 diff --git a/Jenkinsfile b/Jenkinsfile index 2ef5929e09..c6dc70b8d7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,7 +7,8 @@ import com.cloudogu.ces.cesbuildlib.* node('docker') { - mainBranch = 'develop' + developmentBranch = 'develop' + mainBranch = 'master' properties([ // Keep only the last 10 build to preserve space @@ -51,9 +52,9 @@ node('docker') { sh "git config 'remote.origin.fetch' '+refs/heads/*:refs/remotes/origin/*'" sh "git fetch --all" - // merge release branch into master - sh "git checkout master" - sh "git reset --hard origin/master" + // merge release branch into main branch + sh "git checkout ${mainBranch}" + sh "git reset --hard origin/${mainBranch}" sh "git merge --ff-only ${env.BRANCH_NAME}" // set tag @@ -87,7 +88,7 @@ node('docker') { sonarQube.analyzeWith(mvn) } - if (isBuildSuccessful() && (isMainBranch() || isReleaseBranch())) { + if (isBuildSuccessful() && (isDevelopmentBranch() || isReleaseBranch())) { def commitHash = git.getCommitHash() def imageVersion = mvn.getVersion() @@ -143,20 +144,28 @@ node('docker') { } stage('Presentation Environment') { - build job: 'scm-manager/next-scm.cloudogu.com', propagate: false, wait: false, parameters: [ - string(name: 'changeset', value: commitHash), - string(name: 'imageTag', value: imageVersion) - ] + // we don't use developmentBranch, because we only want the lastest version of develop branch on + // next-scm. We don't want a support branch or something similar on the presentation environment. + if ("develop".equals(env.BRANCH_NAME)) { + build job: 'scm-manager/next-scm.cloudogu.com', propagate: false, wait: false, parameters: [ + string(name: 'changeset', value: commitHash), + string(name: 'imageTag', value: imageVersion) + ] + } } if (isReleaseBranch()) { stage('Update Repository') { // merge changes into develop - sh "git checkout develop" + sh "git checkout ${developmentBranch}" + // TODO what if we have a conflict // e.g.: someone has edited the changelog during the release - sh "git merge master" + if (!developmentBranch.equals(mainBranch)) { + sh "git merge ${mainBranch}" + } + // set versions for maven packages mvn "build-helper:parse-version versions:set -DgenerateBackupPoms=false -DnewVersion='\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0-SNAPSHOT'" @@ -176,8 +185,10 @@ node('docker') { // push changes back to remote repository withCredentials([usernamePassword(credentialsId: 'cesmarvin-github', usernameVariable: 'GIT_AUTH_USR', passwordVariable: 'GIT_AUTH_PSW')]) { - sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin master --tags" - sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin develop --tags" + sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin ${mainBranch} --tags" + if (!developmentBranch.equals(mainBranch)) { + sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin develop --tags" + } sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin :${env.BRANCH_NAME}" } } @@ -189,6 +200,7 @@ node('docker') { } } +String developmentBranch String mainBranch Maven setupMavenBuild() { @@ -201,7 +213,7 @@ Maven setupMavenBuild() { mvn.additionalArgs += " -Dscm-it.logbackConfiguration=${logConf}" mvn.additionalArgs += " -Dsonar.coverage.exclusions=**/*.test.ts,**/*.test.tsx,**/*.stories.tsx" - if (isMainBranch() || isReleaseBranch()) { + if (isDevelopmentBranch() || isReleaseBranch()) { // Release starts javadoc, which takes very long, so do only for certain branches mvn.additionalArgs += ' -DperformRelease' // JDK8 is more strict, we should fix this before the next release. Right now, this is just not the focus, yet. @@ -218,8 +230,8 @@ String getReleaseVersion() { return env.BRANCH_NAME.substring("release/".length()); } -boolean isMainBranch() { - return mainBranch.equals(env.BRANCH_NAME) +boolean isDevelopmentBranch() { + return developmentBranch.equals(env.BRANCH_NAME) } void withGPGEnvironment(def closure) { diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index eec24b0966..55f0977dc9 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -3951,6 +3951,23 @@ exports[`Storyshots Diff Binaries 1`] = ` +
+ + + + + +
@@ -4219,6 +4236,23 @@ exports[`Storyshots Diff Collapsed 1`] = ` +
+ + + + + +
@@ -4315,6 +4349,23 @@ exports[`Storyshots Diff Collapsed 1`] = `
+
+ + + + + +
@@ -4411,6 +4462,23 @@ exports[`Storyshots Diff Collapsed 1`] = `
+
+ + + + + +
@@ -4507,6 +4575,23 @@ exports[`Storyshots Diff Collapsed 1`] = `
+
+ + + + + +
@@ -4603,6 +4688,23 @@ exports[`Storyshots Diff Collapsed 1`] = `
+
+ + + + + +
@@ -4699,6 +4801,23 @@ exports[`Storyshots Diff Collapsed 1`] = `
+
+ + + + + +
@@ -4804,6 +4923,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = `
+
+ + + + + +
@@ -4862,6 +4998,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = ` +
+ + + + + +
@@ -5703,6 +5856,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = ` +
+ + + + + +
@@ -6140,6 +6310,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = ` +
+ + + + + +
@@ -6577,6 +6764,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = ` +
+ + + + + +
@@ -6635,6 +6839,23 @@ exports[`Storyshots Diff CollapsingWithFunction 1`] = ` +
+ + + + + +
@@ -6702,6 +6923,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -7266,6 +7504,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -8107,6 +8362,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -8544,6 +8816,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -8981,6 +9270,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -10025,6 +10331,23 @@ exports[`Storyshots Diff Default 1`] = ` +
+ + + + + +
@@ -10546,6 +10869,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -11147,6 +11487,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -12085,6 +12442,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -12594,6 +12968,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -13103,6 +13494,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -14302,6 +14710,23 @@ exports[`Storyshots Diff Expandable 1`] = ` +
+ + + + + +
@@ -14860,6 +15285,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -15428,6 +15870,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -16273,6 +16732,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -16714,6 +17190,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -17155,6 +17648,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -18203,6 +18713,23 @@ exports[`Storyshots Diff File Annotation 1`] = ` +
+ + + + + +
@@ -18728,6 +19255,23 @@ exports[`Storyshots Diff File Controls 1`] = ` +
+ + + + + +
@@ -19310,6 +19854,23 @@ exports[`Storyshots Diff File Controls 1`] = `
+
+ + + + + +
@@ -20169,6 +20730,23 @@ exports[`Storyshots Diff File Controls 1`] = `
+
+ + + + + +
@@ -20624,6 +21202,23 @@ exports[`Storyshots Diff File Controls 1`] = `
+
+ + + + + +
@@ -21079,6 +21674,23 @@ exports[`Storyshots Diff File Controls 1`] = `
+
+ + + + + +
@@ -22141,6 +22753,23 @@ exports[`Storyshots Diff File Controls 1`] = `
+
+ + + + + +
@@ -22680,6 +23309,23 @@ exports[`Storyshots Diff Hunks 1`] = `
+
+ + + + + +
@@ -23508,6 +24154,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -24084,6 +24747,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -24937,6 +25617,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -25374,6 +26071,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -25811,6 +26525,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -26855,6 +27586,23 @@ exports[`Storyshots Diff Line Annotation 1`] = ` +
+ + + + + +
@@ -27388,6 +28136,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -27992,6 +28757,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -28895,6 +29677,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -29362,6 +30161,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -29829,6 +30645,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -30949,6 +31782,23 @@ exports[`Storyshots Diff OnClick 1`] = ` +
+ + + + + +
@@ -31506,6 +32356,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -32163,6 +33030,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -33094,6 +33978,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -33583,6 +34484,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -34072,6 +34990,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -35285,6 +36220,23 @@ exports[`Storyshots Diff Side-By-Side 1`] = ` +
+ + + + + +
@@ -35879,6 +36831,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -36443,6 +37412,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -37284,6 +38270,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -37721,6 +38724,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -38158,6 +39178,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -39202,6 +40239,23 @@ exports[`Storyshots Diff SyntaxHighlighting 1`] = ` +
+ + + + + +
@@ -39723,6 +40777,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
@@ -40324,6 +41395,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
@@ -41262,6 +42350,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
@@ -41771,6 +42876,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
@@ -42280,6 +43402,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
@@ -43479,6 +44618,23 @@ exports[`Storyshots Diff WithLinkToFile 1`] = ` +
+ + + + + +
diff --git a/scm-ui/ui-components/src/buttons/OpenInFullscreenButton.tsx b/scm-ui/ui-components/src/buttons/OpenInFullscreenButton.tsx new file mode 100644 index 0000000000..c1cd1c6da2 --- /dev/null +++ b/scm-ui/ui-components/src/buttons/OpenInFullscreenButton.tsx @@ -0,0 +1,79 @@ +/* + * 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 * as React from "react"; +import { FC, ReactNode, useState } from "react"; +import { useTranslation } from "react-i18next"; +import styled from "styled-components"; +import FullscreenModal from "../modals/FullscreenModal"; +import Tooltip from "../Tooltip"; + +type Props = { + modalTitle: string; + modalBody: ReactNode; + tooltipStyle?: "tooltipComponent" | "htmlTitle"; +}; + +const Button = styled.a` + width: 50px; + &:hover { + color: #33b2e8; + } +`; + +const OpenInFullscreenButton: FC = ({ modalTitle, modalBody, tooltipStyle = "tooltipComponent" }) => { + const [t] = useTranslation("repos"); + const [showModal, setShowModal] = useState(false); + + const tooltip = t("diff.fullscreen.open"); + const content = ( + <> + + {showModal && ( + setShowModal(false)} + body={modalBody} + active={showModal} + /> + )} + + ); + + if (tooltipStyle === "htmlTitle") { + return <>{content}; + } + return ( + + {content} + + ); +}; + +export default OpenInFullscreenButton; diff --git a/scm-ui/ui-components/src/buttons/index.ts b/scm-ui/ui-components/src/buttons/index.ts index 3949b333fe..cc7307572d 100644 --- a/scm-ui/ui-components/src/buttons/index.ts +++ b/scm-ui/ui-components/src/buttons/index.ts @@ -33,4 +33,5 @@ export { default as SubmitButton } from "./SubmitButton"; export { default as DownloadButton } from "./DownloadButton"; export { default as ButtonGroup } from "./ButtonGroup"; export { default as ButtonAddons } from "./ButtonAddons"; +export { default as OpenInFullscreenButton } from "./OpenInFullscreenButton"; export { default as RemoveEntryOfTableButton } from "./RemoveEntryOfTableButton"; diff --git a/scm-ui/ui-components/src/modals/FullscreenModal.tsx b/scm-ui/ui-components/src/modals/FullscreenModal.tsx new file mode 100644 index 0000000000..72951da5ca --- /dev/null +++ b/scm-ui/ui-components/src/modals/FullscreenModal.tsx @@ -0,0 +1,52 @@ +/* + * 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 * as React from "react"; +import { FC, ReactNode } from "react"; +import { useTranslation } from "react-i18next"; +import { Modal } from "./Modal"; +import Button from "../buttons/Button"; +import styled from "styled-components"; + +type Props = { + title: string; + closeFunction: () => void; + body: ReactNode; + active: boolean; +}; + +const FullSizedModal = styled(Modal)` + & .modal-card { + width: 98%; + max-height: 97vh; + } +`; + +const FullscreenModal: FC = ({ title, closeFunction, body, active }) => { + const [t] = useTranslation("repos"); + const footer =