mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
feat: Add ETA for tasks (#5535)
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
parent
44d764d832
commit
4d43763a39
7 changed files with 63 additions and 14 deletions
|
|
@ -8,6 +8,7 @@ subscription JobsSubscribe {
|
|||
description
|
||||
progress
|
||||
error
|
||||
startTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
"intersection-observer": "^0.12.2",
|
||||
"localforage": "^1.10.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"moment": "^2.30.1",
|
||||
"mousetrap": "^1.6.5",
|
||||
"mousetrap-pause": "^1.0.0",
|
||||
"normalize-url": "^4.5.1",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ import "./pluginApi";
|
|||
import { ConnectionMonitor } from "./ConnectionMonitor";
|
||||
import { PatchFunction } from "./patch";
|
||||
|
||||
import moment from "moment/min/moment-with-locales";
|
||||
|
||||
const Performers = lazyComponent(
|
||||
() => import("./components/Performers/Performers")
|
||||
);
|
||||
|
|
@ -158,6 +160,7 @@ export const App: React.FC = () => {
|
|||
});
|
||||
|
||||
setMessages(newMessages);
|
||||
moment.locale([language, defaultLocale]);
|
||||
};
|
||||
|
||||
setLocale();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,3 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Button, Card, ProgressBar } from "react-bootstrap";
|
||||
import {
|
||||
mutateStopJob,
|
||||
useJobQueue,
|
||||
useJobsSubscribe,
|
||||
} from "src/core/StashService";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import { Icon } from "src/components/Shared/Icon";
|
||||
import { useIntl } from "react-intl";
|
||||
import {
|
||||
faBan,
|
||||
faCheck,
|
||||
|
|
@ -17,10 +7,27 @@ import {
|
|||
faHourglassStart,
|
||||
faTimes,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import moment from "moment/min/moment-with-locales";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Card, ProgressBar } from "react-bootstrap";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { Icon } from "src/components/Shared/Icon";
|
||||
import {
|
||||
mutateStopJob,
|
||||
useJobQueue,
|
||||
useJobsSubscribe,
|
||||
} from "src/core/StashService";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
|
||||
type JobFragment = Pick<
|
||||
GQL.Job,
|
||||
"id" | "status" | "subTasks" | "description" | "progress" | "error"
|
||||
| "id"
|
||||
| "status"
|
||||
| "subTasks"
|
||||
| "description"
|
||||
| "progress"
|
||||
| "error"
|
||||
| "startTime"
|
||||
>;
|
||||
|
||||
interface IJob {
|
||||
|
|
@ -124,6 +131,29 @@ const Task: React.FC<IJob> = ({ job }) => {
|
|||
}
|
||||
}
|
||||
|
||||
function maybeRenderETA() {
|
||||
if (
|
||||
job.status === GQL.JobStatus.Running &&
|
||||
job.startTime !== null &&
|
||||
job.startTime !== undefined &&
|
||||
job.progress !== null &&
|
||||
job.progress !== undefined &&
|
||||
job.progress > 0
|
||||
) {
|
||||
const now = new Date();
|
||||
const start = new Date(job.startTime);
|
||||
const nowMS = now.valueOf();
|
||||
const startMS = start.valueOf();
|
||||
const estimatedLength = (nowMS - startMS) / job.progress;
|
||||
const estLenStr = moment.duration(estimatedLength).humanize();
|
||||
return (
|
||||
<span className="job-eta">
|
||||
<FormattedMessage id="eta" />: {estLenStr}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function maybeRenderSubTasks() {
|
||||
if (
|
||||
job.status === GQL.JobStatus.Running ||
|
||||
|
|
@ -159,9 +189,12 @@ const Task: React.FC<IJob> = ({ job }) => {
|
|||
<Icon icon={faTimes} />
|
||||
</Button>
|
||||
<div className={`job-status ${getStatusClass()}`}>
|
||||
<div>
|
||||
{getStatusIcon()}
|
||||
<span>{job.description}</span>
|
||||
<div className="job-description">
|
||||
<div>
|
||||
{getStatusIcon()}
|
||||
<span>{job.description}</span>
|
||||
</div>
|
||||
{maybeRenderETA()}
|
||||
</div>
|
||||
<div>{maybeRenderProgress()}</div>
|
||||
{maybeRenderSubTasks()}
|
||||
|
|
|
|||
|
|
@ -293,6 +293,11 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.job-description {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stop:not(:disabled),
|
||||
.stopping .fa-icon,
|
||||
.cancelled .fa-icon {
|
||||
|
|
|
|||
|
|
@ -1054,6 +1054,7 @@
|
|||
"loading_type": "Error loading {type}",
|
||||
"something_went_wrong": "Something went wrong."
|
||||
},
|
||||
"eta": "ETA",
|
||||
"ethnicity": "Ethnicity",
|
||||
"existing_value": "existing value",
|
||||
"eye_color": "Eye Colour",
|
||||
|
|
|
|||
|
|
@ -5818,6 +5818,11 @@ mkdirp@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
moment@^2.30.1:
|
||||
version "2.30.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
||||
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
||||
|
||||
moment@~2.29.1:
|
||||
version "2.29.4"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
|
||||
|
|
|
|||
Loading…
Reference in a new issue