Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: responsive setup #351

Merged
merged 14 commits into from
Mar 31, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default function LogViewConsoleManager(props) {
switch (state.compState) {
case STATES.ERROR:
return (
<NonLogsContainer style={{ padding: '25px 60px' }}>
<NonLogsContainer className={cx('no-logs')}>
<div className={cx('error-wrapper')}>
<SystemMessage intent="danger">
{getLogsErrorContent({
Expand All @@ -144,7 +144,7 @@ export default function LogViewConsoleManager(props) {
);
case STATES.NO_LOGS_AVAILABLE:
return (
<NonLogsContainer style={{ padding: '25px 60px' }}>
<NonLogsContainer className={cx('no-logs')}>
<SystemMessage intent={getIntentFromStepStatus(state.stepData.status)}>
{getNoLogsContent({
buildStatus: state.buildStatus,
Expand Down Expand Up @@ -176,8 +176,7 @@ export default function LogViewConsoleManager(props) {
showDownloadBtn={state.stepData?.stopped && state.compState === STATES.RESOLVED}
showFollowLogsBtn={state.compState === STATES.STREAM_ON}
logsBlobName={logsBlobName}
showHeader={consoleProps.showHeader}
showFooter={consoleProps.showFooter}
{...consoleProps}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@
margin-top: 10px;
}
}

.no-logs {
padding: 25px 60px;
@include sm-down {
padding: 0;
}
}
68 changes: 51 additions & 17 deletions src/components/pages/build/log-view/log-view.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import classNames from 'classnames/bind';
import React from 'react';
import React, { useCallback, useState, useLayoutEffect } from 'react';
import { useParams } from 'react-router-dom';

import Modal, { useModal } from 'components/shared/modal';

import ConsoleManager from './console-manager';
import css from './log-view.module.scss';
import StageNav from './stage-nav';
Expand All @@ -16,26 +18,58 @@ const LogView = (props) => {
isDataLoading,
data,
} = props;
const [isModalShowing, toggleModal] = useModal();
const [shouldHandleStepClick, setShouldHandleStepClick] = useState(false);
const handleStepClick = useCallback(() => (shouldHandleStepClick ? toggleModal() : {}), [shouldHandleStepClick, toggleModal]);

useLayoutEffect(() => {
if (window.innerWidth < 768) {
setShouldHandleStepClick(true);
}
}, []);

return (
<section className={cx('page-wrapper')}>
<div className={cx('inner')}>
<StageNav
isDataLoading={isDataLoading}
className={cx('navbar')}
stages={data?.stages}
/>
<div className={cx('logs')}>
<ConsoleManager
<>
<section className={cx('page-wrapper')}>
<div className={cx('inner')}>
<StageNav
isDataLoading={isDataLoading}
hasBuildDebugMode={data?.debug || false}
buildStatus={data?.status}
stageStatus={data?.stages?.[stage - 1]?.status}
stageName={data?.stages?.[stage - 1]?.name}
stepData={data?.stages?.[stage - 1]?.steps?.[step - 1]}
className={cx('navbar')}
stages={data?.stages}
onStepClick={handleStepClick}
/>
<div className={cx('logs')}>
<ConsoleManager
isDataLoading={isDataLoading}
hasBuildDebugMode={data?.debug || false}
buildStatus={data?.status}
stageStatus={data?.stages?.[stage - 1]?.status}
stageName={data?.stages?.[stage - 1]?.name}
stepData={data?.stages?.[stage - 1]?.steps?.[step - 1]}
/>
</div>
</div>
</div>
</section>
</section>
<Modal
isShowing={isModalShowing}
mode="fullscreen"
hide={toggleModal}
>
<ConsoleManager
consoleProps={{
showCloseBtn: true,
onCloseBtnClick: toggleModal,
className: cx('console-mobile'),
}}
isDataLoading={isDataLoading}
hasBuildDebugMode={data?.debug || false}
buildStatus={data?.status}
stageStatus={data?.stages?.[stage - 1]?.status}
stageName={data?.stages?.[stage - 1]?.name}
stepData={data?.stages?.[stage - 1]?.steps?.[step - 1]}
/>
</Modal>
</>
);
};

Expand Down
14 changes: 14 additions & 0 deletions src/components/pages/build/log-view/log-view.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
.navbar {
width: 400px;
overflow-y: scroll;
@include sm-down {
width: 100%;
}
}

.logs {
flex: 1;
@include sm-down {
display: none;
}
}

.page-wrapper {
Expand All @@ -22,3 +28,11 @@
padding-right: 60px;
}
}

.console-mobile {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
4 changes: 4 additions & 0 deletions src/components/pages/build/log-view/stage-nav/stage-nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function StageNav(props) {
isDataLoading,
stages = [],
className,
onStepClick,
} = props;
const {
namespace, name, build, stage = 1,
Expand Down Expand Up @@ -82,6 +83,7 @@ export default function StageNav(props) {
name={name}
build={build}
stageInPath={stage}
onStepClick={onStepClick}
/>
);
})}
Expand All @@ -102,6 +104,7 @@ const StageDefault = (props) => {
namespace,
build,
stageInPath,
onStepClick,
} = props;
const [isExpanded, setIsExpanded] = useState(stageNumber == stageInPath);
const toggleIsExpanded = () => setIsExpanded((prev) => !prev);
Expand Down Expand Up @@ -147,6 +150,7 @@ const StageDefault = (props) => {
}}
to={`/${namespace}/${name}/${build}/${stageNumber}/${stepIndex + 1}`}
exact
onClick={onStepClick}
>
<Status className={cx('status')} status={status} />
<span className={cx('name')}>{stepName}</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "styles/_variables.scss";
@import "styles/mixins.scss";

.wrapper {
display: flex;
Expand All @@ -7,6 +8,9 @@
* {
font-family: $font-family-primary;
}
@include sm-down {
width: 100%;
}
}

.header {
Expand All @@ -30,6 +34,9 @@
letter-spacing: 0.2px;
color: #9293ab;
}
@include sm-down {
padding: 14px 20px;
}
}

.inner {
Expand All @@ -38,6 +45,10 @@
align-self: flex-start;
position: relative;
min-height: 500px;
@include md-down {
min-height: unset;
height: auto !important;
}
}
.stage {
background: #ffffff;
Expand Down Expand Up @@ -78,7 +89,7 @@
transition: transform 0.2s ease;
margin-right: 10px;
&-disabled {
stroke: #96a5be;
stroke: #96a5be;
}
}
&-expanded {
Expand Down Expand Up @@ -218,6 +229,9 @@
text-overflow: ellipsis;
white-space: nowrap;
max-width: 180px;
@include xxs-down {
max-width: 145px;
}
}
}
}
1 change: 1 addition & 0 deletions src/components/pages/home/repos-recent/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './repos-recent';
85 changes: 85 additions & 0 deletions src/components/pages/home/repos-recent/repos-recent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import classNames from 'classnames/bind';
import { formatDistanceStrict } from 'date-fns';
import PropTypes from 'prop-types';
import React from 'react';
import { Link } from 'react-router-dom';

import Avatar from 'components/shared/avatar';
import { Label } from 'components/shared/label';
import Status from 'components/shared/status';

import styles from './repos-recent.module.scss';

const cx = classNames.bind(styles);

const ReposRecent = (props) => {
const { repos } = props;
return (
<div className={cx('cards')}>
{!!repos?.length && props.repos.map(({
namespace, name, build, id,
}) => (
<Link to={`/${namespace}/${name}`} key={id}>
<div className={cx('card')}>
<div className={cx('header')}>
<h3 className={cx('title')}>
<span className={cx('namespace')}>{namespace}</span>
<span>{name}</span>
</h3>
<Status status={build?.status} className={cx('status')} />
</div>
<div className={cx('body')}>
<Label
event={build?.event}
commit={build?.after}
branch={build?.target}
environment={build?.deploy_to}
refs={build?.ref}
/>
<span>{build?.title || build?.message}</span>
</div>
<div className={cx('footer')}>
<div>
<Avatar
className={cx('avatar')}
path={build?.author_avatar}
alt={build?.sender}
text={build?.sender}
/>
</div>
{build && (
<div>{formatDistanceStrict(new Date(build.created * 1000), new Date(), { addSuffix: true })}</div>
)}
</div>
</div>
</Link>
))}
</div>
);
};

ReposRecent.propTypes = {
repos: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number,
namespace: PropTypes.string,
name: PropTypes.string,
build: PropTypes.shape({
status: PropTypes.string,
event: PropTypes.string,
sender: PropTypes.string,
author_avatar: PropTypes.string,
deploy_to: PropTypes.string,
title: PropTypes.string,
message: PropTypes.string,
after: PropTypes.string,
ref: PropTypes.string,
created: PropTypes.number,
}),
})),
};

ReposRecent.defaultProps = {
repos: [],
};

export default ReposRecent;
Loading