Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(js): add Download and QR Popup buttons to collapsed build blocks
Browse files Browse the repository at this point in the history
add square logo

allow click anywhere outside modal to close

test something

Signed-off-by: Elizabeth Kelen <erskelen@gmail.com>
ekelen committed Oct 12, 2020

Verified

This commit was signed with the committer’s verified signature.
neo1973 Markus Härer
1 parent 237b097 commit 6f14360
Showing 6 changed files with 210 additions and 77 deletions.
12 changes: 12 additions & 0 deletions web/src/assets/svg/yolo-logo-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion web/src/ui/components/Build/ArtifactRow.js
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ const ArtifactRowKindIcon = ({ color, kind = '' }) => (
/>
)

const QrCode = ({ artifactPlistSignedUrl, closeAction }) => (
export const QrCode = ({ artifactPlistSignedUrl, closeAction }) => (
<QRCodeModal closeAction={closeAction}>
<QRCode
value={`itms-services://?action=download-manifest&url=${process.env.API_SERVER}${artifactPlistSignedUrl}`}
3 changes: 1 addition & 2 deletions web/src/ui/components/Build/BuildBlockHeader.js
Original file line number Diff line number Diff line change
@@ -74,8 +74,7 @@ const ChevronIcon = ({ theme, collapsed, toggleCollapsed }) => (
<div
className={styles.headerChevronToggler}
style={{ color: theme.text.blockTitle }}
onClick={(e) => {
e.stopPropagation()
onClick={() => {
toggleCollapsed(!collapsed)
}}
>
246 changes: 179 additions & 67 deletions web/src/ui/components/Build/BuildContainer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { faQrcode } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { get } from 'lodash'
import React, { useContext, useState } from 'react'
import { Download } from 'react-feather'
import { ARTIFACT_KIND_NAMES, BRANCH, BUILD_STATE } from '../../../constants'
import { GlobalContext } from '../../../store/GlobalStore'
import { ThemeContext } from '../../../store/ThemeStore'
@@ -10,9 +12,13 @@ import {
getStrEquNormalized,
} from '../../../util/getters'
import { getArtifactKindIcon } from '../../styleTools/brandIcons'
import { tagColorStyles } from '../../styleTools/buttonStyler'
import {
primaryButtonColors,
tagColorStyles,
} from '../../styleTools/buttonStyler'
import ShowingOlderBuildsTag from '../ShowingOlderBuildsTag'
import Tag from '../Tag/Tag'
import { QrCode } from './ArtifactRow'
import styles from './Build.module.scss'
import BuildAndMrContainer from './BuildAndMrContainer'
import BuildBlockHeader from './BuildBlockHeader'
@@ -63,13 +69,114 @@ const AnyRunningBuildTags = ({ hasRunningBuilds, allBuildsForMr, theme }) => has
</Tag>
)

const LatestBuildQrButton = ({ onClick, theme, artifactPlistSignedUrl }) => artifactPlistSignedUrl && (
<div
onClick={(e) => {
onClick()
e.stopPropagation()
}}
className="btn btn-sm"
style={{
...primaryButtonColors(theme),
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
title="Show QR code"
>
<FontAwesomeIcon
icon={faQrcode}
size="lg"
color={theme.text.btnPrimary}
style={{
marginTop: 0,
marginBottom: 0,
}}
/>
</div>
)

const DlButtonSmall = ({ buildHasArtifacts, theme }) => buildHasArtifacts && (
<>
{buildHasArtifacts.map((artifact, i) => {
const {
plist_signed_url: artifactPlistSignedUrl = '',
dl_artifact_signed_url: artifactDlArtifactSignedUrl = '',
kind: artifactKind = '',
} = artifact

const fullPlistSignedUrl = artifactPlistSignedUrl
&& `itms-services://?action=download-manifest&url=${process.env.API_SERVER}${artifactPlistSignedUrl}`

const fullDlArtifactSignedUrl = artifactDlArtifactSignedUrl
&& `${process.env.API_SERVER}${artifactDlArtifactSignedUrl}`

const hasDlUrl = fullPlistSignedUrl || fullDlArtifactSignedUrl
return (
<a
key={`${artifactPlistSignedUrl}=${i}`}
href={hasDlUrl}
className="btn btn-sm"
style={{
...primaryButtonColors(theme),
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
title={hasDlUrl}
>
<Download size="1rem" style={{ marginRight: '0.3rem' }} />
{`.${ARTIFACT_KIND_NAMES[artifactKind]}`}
</a>
)
})}
</>
)

const LatestBuildStateTags = ({
collapsed,
theme,
buildState,
buildId,
buildHasArtifacts,
allBuildsForMr,
hasRunningBuilds,
}) => {
const [showingQrModal, toggleShowQrModal] = useState(false)
const firstArtifactPlistSignedUrl = buildHasArtifacts?.find((a) => a.kind === ARTIFACT_KIND_NAMES.IPA)
?.plist_signed_url || null
return (
collapsed && (
<>
{showingQrModal && firstArtifactPlistSignedUrl && (
<QrCode
artifactPlistSignedUrl={firstArtifactPlistSignedUrl}
closeAction={() => toggleShowQrModal(false)}
/>
)}
<BuildStateTag {...{ theme, buildState, buildId }} />
<LatestBuildArtifactsIcons {...{ theme, buildHasArtifacts }} />
<AnyRunningBuildTags {...{ hasRunningBuilds, allBuildsForMr, theme }} />
<DlButtonSmall {...{ buildHasArtifacts, theme }} />
<LatestBuildQrButton
onClick={() => toggleShowQrModal(true)}
theme={theme}
artifactPlistSignedUrl={firstArtifactPlistSignedUrl}
/>
<ShowingOlderBuildsTag nOlderBuilds={allBuildsForMr.length - 1} />
</>
)
)
}

const BuildContainer = React.memo(
({
build, toCollapse, hasRunningBuilds, isLatestMaster = false,
}) => {
const { state } = useContext(GlobalContext)
const [collapsed, setCollapsed] = useState(toCollapse)
const [showingAllBuilds, toggleShowingAllBuilds] = useState(false)

const { theme } = useContext(ThemeContext)

const toggleCollapsed = () => setCollapsed(!collapsed)
@@ -105,75 +212,80 @@ const BuildContainer = React.memo(

const isMasterBuildBranch = getStrEquNormalized(buildBranch, BRANCH.MASTER)

const LatestBuildStateTags = () => collapsed && (
<>
<BuildStateTag {...{ theme, buildState, buildId }} />
<LatestBuildArtifactsIcons {...{ theme, buildHasArtifacts }} />
<ShowingOlderBuildsTag nOlderBuilds={allBuildsForMr.length - 1} />
<AnyRunningBuildTags
{...{ hasRunningBuilds, allBuildsForMr, theme }}
/>
</>
)

return (
<div className={styles.buildBlock}>
<div
className="card"
style={{
backgroundColor: theme.bg.block,
boxShadow: theme.shadowStyle.block,
...tablerOverrides.card,
}}
key={buildId}
onClick={() => {
if (collapsed) {
toggleCollapsed()
}
}}
>
<BuildBlockHeader
{...{
buildAuthorName,
buildAuthorAvatarUrl,
buildAuthorId,
buildHasMr,
buildId,
buildShortId,
collapsed,
isMasterBuildBranch,
isLatestMaster,
mrId,
mrTitle,
mrShortId,
mrState,
toggleCollapsed,
projectOwnerId,
projectOwnerAvatarUrl,
...{ childrenLatestBuildTags: <LatestBuildStateTags /> },
<>
<div className={styles.buildBlock}>
<div
className="card"
style={{
backgroundColor: theme.bg.block,
boxShadow: theme.shadowStyle.block,
...tablerOverrides.card,
}}
/>
{!collapsed
&& allBuildsForMr
.filter((bIdx, i) => showingAllBuilds ? Number.isInteger(bIdx) : i === 0)
.map((buildidx, i) => (
<BuildAndMrContainer
build={state.builds[buildidx]}
buildHasMr={buildHasMr}
hasRunningBuilds={hasRunningBuilds}
isLatestBuild={i === 0}
key={i}
nOlderBuilds={
i === 0 && getIsArrayWithN(allBuildsForMr, 2)
? allBuildsForMr.length - 1
: 0
}
showingAllBuilds={showingAllBuilds}
toggleShowingAllBuilds={toggleShowingAllBuilds}
/>
))}
key={buildId}
onClick={() => {
if (collapsed) {
toggleCollapsed()
}
}}
>
<BuildBlockHeader
{...{
buildAuthorName,
buildAuthorAvatarUrl,
buildAuthorId,
buildHasMr,
buildId,
buildShortId,
collapsed,
isMasterBuildBranch,
isLatestMaster,
mrId,
mrTitle,
mrShortId,
mrState,
toggleCollapsed,
projectOwnerId,
projectOwnerAvatarUrl,
...{
childrenLatestBuildTags: (
<LatestBuildStateTags
{...{
collapsed,
theme,
buildState,
buildId,
buildHasArtifacts,
allBuildsForMr,
hasRunningBuilds,
}}
/>
),
},
}}
/>
{!collapsed
&& allBuildsForMr
.filter((bIdx, i) => showingAllBuilds ? Number.isInteger(bIdx) : i === 0)
.map((buildidx, i) => (
<BuildAndMrContainer
build={state.builds[buildidx]}
buildHasMr={buildHasMr}
hasRunningBuilds={hasRunningBuilds}
isLatestBuild={i === 0}
key={i}
nOlderBuilds={
i === 0 && getIsArrayWithN(allBuildsForMr, 2)
? allBuildsForMr.length - 1
: 0
}
showingAllBuilds={showingAllBuilds}
toggleShowingAllBuilds={toggleShowingAllBuilds}
/>
))}
</div>
</div>
</div>
</>
)
},
)
22 changes: 16 additions & 6 deletions web/src/ui/components/MessageModal/MessageModal.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import React from 'react'
import './MessageModal.scss'

const MessageModal = ({ children }) => (
const MessageModal = ({ children, onClose = () => {} }) => (
<>
<div className="faded" />
<div
className="faded"
onClick={(e) => {
e.stopPropagation()
onClose()
}}
/>
<div className="MessageModal">
<div className="modal modal-blur fade show">
<div
className="modal modal-blur fade show"
onClick={(e) => {
e.stopPropagation()
onClose()
}}
>
<div className="modal-dialog" role="document">
<div className="modal-content">
{children}
</div>
<div className="modal-content">{children}</div>
</div>
</div>
</div>
2 changes: 1 addition & 1 deletion web/src/ui/components/QRCodeModal.js
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import React from 'react'
import MessageModal from './MessageModal/MessageModal'

const QRCodeModal = ({ closeAction, children }) => (
<MessageModal>
<MessageModal onClose={closeAction}>
<div style={{ width: 'auto' }}>
{children}
<div className="modal-footer">

0 comments on commit 6f14360

Please sign in to comment.