widgets/time-tracking-report/src/app/content.js (175 lines of code) (raw):
import React from 'react';
import PropTypes from 'prop-types';
import LoaderInline from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
import Link from '@jetbrains/ring-ui/components/link/link';
import {i18n} from 'hub-dashboard-addons/dist/localization';
import ProgressBar from '@jetbrains/ring-ui/components/progress-bar/progress-bar';
import EmptyWidget, {EmptyWidgetFaces} from '@jetbrains/hub-widget-ui/dist/empty-widget';
import withWidgetLoaderHOC from '@jetbrains/hub-widget-ui/dist/widget-title';
import withTimerHOC from '@jetbrains/hub-widget-ui/dist/timer';
import ReportModel from '../../../../components/src/report-model/report-model';
import TimeTrackingReportModel from './time-tracking-report-model';
import TimeTable from './time-table';
import TimeTableSettingsToolbar from './time-table-settings-toolbar';
class Content extends React.Component {
static propTypes = {
report: PropTypes.object,
lastDayOfWeek: PropTypes.number,
error: PropTypes.number,
youTrack: PropTypes.object,
dashboardApi: PropTypes.object,
editable: PropTypes.bool,
isIssueView: PropTypes.bool,
withDetails: PropTypes.bool,
onChangeDetailsVisibility: PropTypes.func.isRequired,
onOpenSettings: PropTypes.func,
onChangeReportGrouping: PropTypes.func,
onChangeYAxis: PropTypes.func
};
fetchYouTrack = (url, params) =>
this.props.dashboardApi.fetch(
(this.props.youTrack || {}).id, url, params
);
renderLoader() {
return <LoaderInline/>;
}
renderFatalError(message) {
const removeWidget = async () =>
await this.props.dashboardApi.removeWidget();
return (
<EmptyWidget
face={EmptyWidgetFaces.ERROR}
message={message}
>
{
this.props.editable &&
<Link
pseudo={true}
onClick={removeWidget}
>
{i18n('Remove widget')}
</Link>
}
</EmptyWidget>
);
}
renderReportError(message) {
return (
<EmptyWidget
face={EmptyWidgetFaces.OK}
message={message}
>
{
this.props.editable &&
<Link
pseudo={true}
onClick={this.props.onOpenSettings}
>
{i18n('Edit settings')}
</Link>
}
</EmptyWidget>
);
}
renderError(error) {
if (error === ReportModel.ErrorTypes.NO_YOUTRACK) {
return this.renderFatalError(
i18n('Cannot find YouTrack installation')
);
}
if (error === ReportModel.ErrorTypes.NO_REPORT) {
return this.renderReportError(
i18n('Cannot find any report')
);
}
if (error === ReportModel.ErrorTypes.CANNOT_LOAD_REPORT) {
return this.renderReportError(i18n('Cannot load selected report'));
}
if (error === ReportModel.ErrorTypes.NO_PERMISSIONS_FOR_REPORT) {
return this.renderReportError(
i18n('You don\'t have access to the report')
);
}
return this.renderFatalError(
i18n('Oops... Something went wrong =(')
);
}
renderReportBody() {
const {report, dashboardApi, isIssueView, lastDayOfWeek} = this.props;
if (
ReportModel.isReportCalculation(report) ||
ReportModel.isCalculationRequired(report)
) {
const fromPercentsCoefficient = 0.01;
const progress = Math.max(report.status.progress || 0, 0);
const progressValue = progress * fromPercentsCoefficient;
return (
<div className="report-widget__progress">
<div>{i18n('Calculating...')}</div>
<ProgressBar
className="report-widget__progress-bar"
value={progressValue}
/>
</div>
);
}
if (ReportModel.isReportError(report)) {
return this.renderReportError(report.status.errorMessage);
}
if (ReportModel.isTooBigReportDataError(report)) {
return this.renderReportError(
i18n('The report cannot be calculated: the filters in the report settings return too many issues')
);
}
if (ReportModel.isNoReportDataError(report)) {
return this.renderReportError(i18n('There aren\'t any issues that match the filters in the report settings'));
}
const columnsLegend = TimeTrackingReportModel.getColumnsLegend(report);
const columnsHeader =
TimeTrackingReportModel.getColumnsHeader(report, lastDayOfWeek);
const generalGroups =
TimeTrackingReportModel.getGeneralGroupedLines(report, isIssueView);
const detailedGroups =
TimeTrackingReportModel.getDetailedGroupedLines(report, isIssueView);
const totalSpentTime = TimeTrackingReportModel.getTotalSpentTime(report);
return (
<TimeTable
grouping={report.grouping}
fetchHub={dashboardApi.fetchHub}
fetchYouTrack={this.fetchYouTrack}
presentationControlsPanel={
<TimeTableSettingsToolbar
youTrack={this.props.youTrack}
dashboardApi={this.props.dashboardApi}
onChangeYAxis={this.props.onChangeYAxis}
onChangeReportGrouping={this.props.onChangeReportGrouping}
grouping={report.grouping}
projects={report.projects}
isIssueView={isIssueView}
disabled={!report.editable}
/>
}
columnsLegend={columnsLegend}
columnsHeader={columnsHeader}
generalGroups={generalGroups}
detailedGroups={detailedGroups}
totalSpentTime={totalSpentTime}
isIssueView={isIssueView}
homeUrl={this.props.youTrack.homeUrl}
withDetails={this.props.withDetails}
onChangeDetailsVisibility={this.props.onChangeDetailsVisibility}
/>
);
}
render() {
const {report, error} = this.props;
if (error) {
return this.renderError(error);
}
if (!report) {
return this.renderLoader();
}
return this.renderReportBody();
}
}
export default withTimerHOC(withWidgetLoaderHOC(Content));