зеркало из https://github.com/mozilla/treeherder.git
Bug 1770903 - move time-to-triage logic to backend (#7448)
* Bug 1770903 - move time-to-triage logic to backend * Bug 1770903 - Update UI countdown * Bug 1770903 - Show alert created date under push date * Address errors and reviews Co-authored-by: Alex Ionescu <aionescu@mozilla.com>
This commit is contained in:
Родитель
444dbb6c71
Коммит
496ff0080c
|
@ -421,6 +421,7 @@ def empty_alert_summary(
|
|||
prev_push_id=1,
|
||||
push_id=3,
|
||||
manually_created=True,
|
||||
created=datetime.now(),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import datetime
|
||||
|
||||
MON, TUE, WED, THU, FRI, SAT, SUN = range(1, 8)
|
||||
|
||||
|
||||
def test_alert_summary_created_monday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-30')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created monday isoweekday = 1 + OKR = 3 => 4
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == THU
|
||||
|
||||
|
||||
def test_alert_summary_created_tuesday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-31')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created tuesday isoweekday = 2 + OKR = 3 => 5
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == FRI
|
||||
|
||||
|
||||
def test_alert_summary_created_wednesday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-01')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created wednesday = 3 + OKR = 3 => 6 (saturday) => 1 (monday)
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == MON
|
||||
|
||||
|
||||
def test_alert_summary_created_thursday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-02')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created thursday = 4 + OKR = 3 => 7 (sunday) => 1 (monday) + 1 day =2
|
||||
# 1 (monday) + 1 day (1 day of OKR was saturday) = 2
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == TUE
|
||||
|
||||
|
||||
def test_alert_summary_created_friday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-03')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created friday = 5 + OKR = 3 => 8 => 1 (monday)
|
||||
# 1 (monday) + 2 (2 days of OKR were weekend) = 3 (wednesday)
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == WED
|
||||
|
||||
|
||||
def test_alert_summary_created_saturday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-04')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created saturday = 6 => 1 (monday) + OKR = 3 => 4 (thursday)
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == THU
|
||||
|
||||
|
||||
def test_alert_summary_created_sunday(test_perf_alert_summary):
|
||||
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-05')
|
||||
test_perf_alert_summary.triage_due_date = None
|
||||
|
||||
assert not test_perf_alert_summary.triage_due_date
|
||||
|
||||
test_perf_alert_summary.update_status()
|
||||
|
||||
# created sunday = 7 => 1 (monday) + OKR = 3 => 4 (thursday)
|
||||
assert test_perf_alert_summary.triage_due_date.isoweekday() == THU
|
|
@ -90,535 +90,12 @@ test("Tags modal opens from 'Edit tags'", async () => {
|
|||
expect(modal).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Alert created on Monday
|
||||
test('Alert is created on Monday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Monday
|
||||
alert.created = '2022-02-07T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-07T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
test('Alert is created on Monday, Triage to countdown shows 2 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Monday
|
||||
alert.created = '2022-02-07T11:41:31.419156';
|
||||
|
||||
// current day is set to Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-08T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 2');
|
||||
});
|
||||
|
||||
test('Alert is created on Monday, Triage to countdown shows 1 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Monday
|
||||
alert.created = '2022-02-07T11:41:31.419156';
|
||||
|
||||
// current day is set to Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-09T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 1');
|
||||
});
|
||||
|
||||
test('Alert is created on Monday, Triage to countdown shows Today', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Monday
|
||||
alert.created = '2022-02-07T11:41:31.419156';
|
||||
|
||||
// current day is set to Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-10T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Alert is created on Monday, Triage to countdown shows Overdue', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Monday
|
||||
alert.created = '2022-02-07T11:41:31.419156';
|
||||
|
||||
// current day is set to Friday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-11T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Overdue');
|
||||
});
|
||||
|
||||
// Alert created on Tuesday
|
||||
test('Alert is created on Tuesday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Tuesday
|
||||
alert.created = '2022-02-08T11:41:31.419156';
|
||||
|
||||
// current day is set to Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-08T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
test('Alert is created on Tuesday, Triage to countdown shows 2 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Tuesday
|
||||
alert.created = '2022-02-08T11:41:31.419156';
|
||||
|
||||
// current day is set to Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-09T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 2');
|
||||
});
|
||||
|
||||
test('Alert is created on Tuesday, Triage to countdown shows 1 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Tuesday
|
||||
alert.created = '2022-02-08T11:41:31.419156';
|
||||
|
||||
// current day is set to Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-10T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 1');
|
||||
});
|
||||
|
||||
test('Alert is created on Tuesday, Triage to countdown shows Today', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Tuesday
|
||||
alert.created = '2022-02-08T11:41:31.419156';
|
||||
|
||||
// current day is set to Friday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-11T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Alert is created on Tuesday, Triage to countdown shows Overdue', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Tuesday
|
||||
alert.created = '2022-02-08T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Overdue');
|
||||
});
|
||||
|
||||
// testing what the tooltip shows for the cases when the alert is created either on Wednesday, Thursday, Friday or the weekend
|
||||
|
||||
// Alert created on Wednesday
|
||||
test('Alert is created on Wednesday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-09T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
test('Alert is created on Wednesday, Triage to countdown shows 2 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-10T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 2');
|
||||
});
|
||||
|
||||
test('Alert is created on Wednesday, Triage to countdown shows 1 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Friday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-11T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 1');
|
||||
});
|
||||
|
||||
test('Alert is created on Wednesday, Triage to countdown shows Today', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Alert is created on Wednesday, Triage to countdown shows Overdue', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-15T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Overdue');
|
||||
});
|
||||
|
||||
// Alert created on Thursday
|
||||
test('Alert is created on Thursday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-10T11:41:31.419156';
|
||||
|
||||
// current day is set to Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-10T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
test('Alert is created on Thursday, Triage to countdown shows 2 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-10T11:41:31.419156';
|
||||
|
||||
// current day is set to Friday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-11T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 2');
|
||||
});
|
||||
|
||||
test('Alert is created on Thursday, Triage to countdown shows 1 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-10T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 1');
|
||||
});
|
||||
|
||||
test('Alert is created on Thursday, Triage to countdown shows Today', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-10T11:41:31.419156';
|
||||
|
||||
// current day is set to Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-15T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Alert is created on Thursday, Triage to countdown shows Overdue', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
|
||||
// current day is set to Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-16T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Overdue');
|
||||
});
|
||||
|
||||
// Alert created on Friday
|
||||
test('Alert is created on Friday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to Friday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-11T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
test('Alert is created on Friday, Triage to countdown shows 2 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 2');
|
||||
});
|
||||
|
||||
test('Alert is created on Friday, Triage to countdown shows 1 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-15T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 1');
|
||||
});
|
||||
|
||||
test('Alert is created on Friday, Triage to countdown shows Today', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-16T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Alert is created on Friday, Triage to countdown shows Overdue', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-17T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Overdue');
|
||||
});
|
||||
|
||||
// Alert is created on Saturday, it should work like the alert was created on Monday
|
||||
test('Alert is created on Saturday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Saturday
|
||||
alert.created = '2022-02-12T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
// Alert is created on Sunday, it should work like the alert was created on Monday
|
||||
test('Alert is created on Sunday, Triage to countdown shows 3 working days', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Sunday
|
||||
alert.created = '2022-02-13T11:41:31.419156';
|
||||
|
||||
// current day is set to Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Working days left: 3');
|
||||
});
|
||||
|
||||
// by showing Today status we know that the due date was calculated correctly
|
||||
|
||||
test('Showing Today status when Due date day is the same as current day and alert is created on Wednesday', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Wednesday
|
||||
alert.created = '2022-02-09T11:41:31.419156';
|
||||
alert.triage_due_date = '2022-02-14T11:41:31.419156';
|
||||
|
||||
// current day is set to equal due date which is calculated to be Monday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-14T11:41:31.419156'));
|
||||
|
@ -630,84 +107,10 @@ test('Showing Today status when Due date day is the same as current day and aler
|
|||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
expect(dueDateStatusText.slice(0, 10)).toBe('Hours left');
|
||||
});
|
||||
|
||||
test('Showing Today status when Due date day is the same as current day and alert is created on Thursday', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Thursday
|
||||
alert.created = '2022-02-10T11:41:31.419156';
|
||||
|
||||
// current day is set to equal due date which is calculated to be Tuesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-15T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Showing Today status when Due date day is the same as current day and alert is created on Friday', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Friday
|
||||
alert.created = '2022-02-11T11:41:31.419156';
|
||||
|
||||
// current day is set to equal due date which is calculated to be Wednesday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-16T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Showing Today status when Due date day is the same as current day and alert is created on Saturday', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Saturday
|
||||
alert.created = '2022-02-12T11:41:31.419156';
|
||||
|
||||
// current day is set to equal due date which is calculated to be Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-17T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
|
||||
test('Showing Today status when Due date day is the same as current day and alert is created on Sunday', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
||||
// created date day is set to Sunday
|
||||
alert.created = '2022-02-13T11:41:31.419156';
|
||||
|
||||
// current day is set to equal due date which is calculated to be Thursday
|
||||
Date.now = jest.fn(() => Date.parse('2022-02-17T11:41:31.419156'));
|
||||
|
||||
const { getByTestId } = testStatusDropdown([], alert);
|
||||
const dueDateIcon = await waitFor(() => getByTestId('triage-clock-icon'));
|
||||
|
||||
fireEvent.mouseOver(dueDateIcon);
|
||||
|
||||
const dueDateStatus = await waitFor(() => getByTestId('due-date-status'));
|
||||
const dueDateStatusText = dueDateStatus.querySelector('span').innerHTML;
|
||||
expect(dueDateStatusText).toBe('Today');
|
||||
});
|
||||
// by showing Hours left status we know that the due date was calculated correctly
|
||||
|
||||
test('Triage to countdown shows nothing when the website is accessed during the weekend', async () => {
|
||||
const alert = testAlertSummaries[0];
|
||||
|
|
|
@ -73,6 +73,7 @@ def test_alert_summaries_get(client, test_perf_alert_summary, test_perf_alert):
|
|||
'framework',
|
||||
'id',
|
||||
'created',
|
||||
'triage_due_date',
|
||||
'prev_push_id',
|
||||
'related_alerts',
|
||||
'repository',
|
||||
|
@ -133,6 +134,7 @@ def test_alert_summaries_get_onhold(
|
|||
'framework',
|
||||
'id',
|
||||
'created',
|
||||
'triage_due_date',
|
||||
'prev_push_id',
|
||||
'related_alerts',
|
||||
'repository',
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Generated by Django 3.2.13 on 2022-05-30 11:02
|
||||
from django.db import migrations, models
|
||||
|
||||
from treeherder.perf.utils import calculate_time_to_triage
|
||||
|
||||
|
||||
def update_summary_triage_due_date(apps, schema_editor):
|
||||
PerformanceAlertSummary = apps.get_model('perf', 'PerformanceAlertSummary')
|
||||
|
||||
for row in PerformanceAlertSummary.objects.all():
|
||||
row.triage_due_date = calculate_time_to_triage(row.created)
|
||||
row.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('perf', '0046_restore_cascade_perf_datum_deletion'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='performancealertsummary',
|
||||
name='triage_due_date',
|
||||
field=models.DateTimeField(default=None, null=True),
|
||||
),
|
||||
migrations.RunPython(
|
||||
update_summary_triage_due_date,
|
||||
reverse_code=migrations.RunPython.noop,
|
||||
),
|
||||
]
|
|
@ -19,6 +19,7 @@ from treeherder.model.models import (
|
|||
JobType,
|
||||
JobGroup,
|
||||
)
|
||||
from treeherder.perf.utils import calculate_time_to_triage
|
||||
from treeherder.utils import default_serializer
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -271,6 +272,7 @@ class PerformanceAlertSummary(models.Model):
|
|||
)
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||
triage_due_date = models.DateTimeField(null=True, default=None)
|
||||
first_triaged = models.DateTimeField(null=True, default=None)
|
||||
last_updated = models.DateTimeField(auto_now=True, null=True)
|
||||
|
||||
|
@ -312,6 +314,8 @@ class PerformanceAlertSummary(models.Model):
|
|||
def save(self, *args, **kwargs):
|
||||
if self.bug_number is not None and self.bug_number != self.__prev_bug_number:
|
||||
self.bug_updated = datetime.now()
|
||||
if not self.triage_due_date:
|
||||
self.triage_due_date = calculate_time_to_triage(self.created)
|
||||
super(PerformanceAlertSummary, self).save(*args, **kwargs)
|
||||
self.__prev_bug_number = self.bug_number
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import datetime
|
||||
|
||||
MON, TUE, WED, THU, FRI, SAT, SUN = range(1, 8)
|
||||
|
||||
|
||||
def calculate_time_to_triage(created, due_days=3):
|
||||
due_date = created
|
||||
|
||||
# if the alert was created in weekend, move the date to Monday
|
||||
if due_date.isoweekday() == SAT:
|
||||
due_date = due_date + datetime.timedelta(2)
|
||||
if due_date.isoweekday() == SUN:
|
||||
due_date = due_date + datetime.timedelta(1)
|
||||
|
||||
if due_date.isoweekday() + due_days < SAT:
|
||||
# add the time-to days
|
||||
due_date = due_date + datetime.timedelta(due_days)
|
||||
# if the resulted date is on weekend, skip the weekend
|
||||
elif due_date.isoweekday() + due_days in [SAT, SUN]:
|
||||
due_date = due_date + datetime.timedelta(due_days + 2)
|
||||
# if the time-to days is greater than 7 then it contains weekend(s)
|
||||
# move the due date with the numbers of weekend days
|
||||
elif due_date.isoweekday() + due_days > SUN:
|
||||
due_date += datetime.timedelta(due_days + int((due_date.isoweekday() + due_days) / 7) * 2)
|
||||
|
||||
if due_date.isoweekday() == SAT:
|
||||
due_date = due_date + datetime.timedelta(2)
|
||||
elif due_date.isoweekday() == SUN:
|
||||
due_date = due_date + datetime.timedelta(1)
|
||||
|
||||
return due_date
|
|
@ -245,6 +245,7 @@ class PerformanceAlertSummarySerializer(serializers.ModelSerializer):
|
|||
prev_push_id = serializers.ReadOnlyField()
|
||||
push_id = serializers.ReadOnlyField()
|
||||
created = serializers.ReadOnlyField()
|
||||
triage_due_date = serializers.ReadOnlyField()
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
instance.timestamp_first_triage()
|
||||
|
@ -260,6 +261,7 @@ class PerformanceAlertSummarySerializer(serializers.ModelSerializer):
|
|||
'push_id',
|
||||
'prev_push_id',
|
||||
'created',
|
||||
'triage_due_date',
|
||||
'repository',
|
||||
'framework',
|
||||
'alerts',
|
||||
|
|
|
@ -339,3 +339,5 @@ export const genericErrorMessage = 'Something went wrong';
|
|||
// Datetime format used for pushes listed in https://hg.mozilla.org/
|
||||
// e.g. Sun Feb 14 22:40:03 2021 +0000
|
||||
export const mercurialDatetimeFormat = 'ddd MMM DD HH:mm:ss YYYY ZZ';
|
||||
|
||||
export const alertsViewDatetimeFormat = 'ddd MMM DD HH:mm YYYY';
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import moment from 'moment';
|
||||
|
||||
import { getArtifactsUrl } from './url';
|
||||
import { mercurialDatetimeFormat } from './constants';
|
||||
import { alertsViewDatetimeFormat, mercurialDatetimeFormat } from './constants';
|
||||
|
||||
export const longDateFormat = {
|
||||
weekday: 'short',
|
||||
|
@ -37,6 +37,13 @@ export function toMercurialDateStr(awareDatetime) {
|
|||
return `${moment.utc(awareDatetime).format(mercurialDatetimeFormat)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { Date } awareDatetime Must contain the time zone information embedded in it
|
||||
*/
|
||||
export function toMercurialShortDateStr(awareDatetime) {
|
||||
return `${moment.utc(awareDatetime).format(alertsViewDatetimeFormat)}`;
|
||||
}
|
||||
|
||||
export const toShortDateStr = function toDateStr(timestamp) {
|
||||
return new Date(timestamp * 1000).toLocaleString('en-US', shortDateFormat);
|
||||
};
|
||||
|
|
|
@ -11,7 +11,8 @@ import {
|
|||
} from 'reactstrap';
|
||||
|
||||
import { getJobsUrl } from '../../helpers/url';
|
||||
import { toMercurialDateStr } from '../../helpers/display';
|
||||
import { toMercurialShortDateStr } from '../../helpers/display';
|
||||
import SimpleTooltip from '../../shared/SimpleTooltip';
|
||||
|
||||
import Assignee from './Assignee';
|
||||
import TagsList from './TagsList';
|
||||
|
@ -38,13 +39,25 @@ const AlertHeader = ({
|
|||
const performanceTags = alertSummary.performance_tags || [];
|
||||
const alertSummaryDatetime = new Date(alertSummary.push_timestamp * 1000);
|
||||
const formattedSummaryRevision = alertSummary.revision.slice(0, 12);
|
||||
const created = new Date(alertSummary.created.slice(0, 19));
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<AlertHeaderTitle alertSummary={alertSummary} frameworks={frameworks} />
|
||||
<Row className="font-weight-normal">
|
||||
<Col className="p-0" xs="auto">
|
||||
{toMercurialDateStr(alertSummaryDatetime)}
|
||||
<Row className="m-0 px-0 py-0">
|
||||
<SimpleTooltip
|
||||
text={toMercurialShortDateStr(alertSummaryDatetime)}
|
||||
tooltipText="Push date"
|
||||
/>
|
||||
</Row>
|
||||
<Row className="m-0 px-0 py-0">
|
||||
<SimpleTooltip
|
||||
text={toMercurialShortDateStr(created)}
|
||||
tooltipText="Alert Summary created"
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col className="p-0" xs="auto">
|
||||
<UncontrolledDropdown tag="span">
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
createQueryParams,
|
||||
bugzillaBugsApi,
|
||||
} from '../../helpers/url';
|
||||
import { timeToTriage, summaryStatusMap } from '../perf-helpers/constants';
|
||||
import { summaryStatusMap } from '../perf-helpers/constants';
|
||||
import DropdownMenuItems from '../../shared/DropdownMenuItems';
|
||||
import FilterAlertsWithVideos from '../../models/filterAlertsWithVideos';
|
||||
|
||||
|
@ -255,36 +255,18 @@ export default class StatusDropdown extends React.Component {
|
|||
alertStatus === 'investigating' ||
|
||||
(alertStatus !== status && this.isResolved(alertStatus));
|
||||
|
||||
calculateDueDate(created) {
|
||||
const createdAt = new Date(created);
|
||||
const dueDate = new Date(created);
|
||||
|
||||
/* due date is calculated by adding 3 working days to the date when the alert was created
|
||||
this means you have 3 working days with decreasing status of 3, 2, 1 working days left
|
||||
and in the fourth day the status changes to Today, this being the last day when the alert status has to change
|
||||
otherwise it becomes Overdue */
|
||||
|
||||
dueDate.setDate(dueDate.getDate() + timeToTriage);
|
||||
const numberOfWeekendDays = this.getNumberOfWeekendDays(createdAt, dueDate);
|
||||
|
||||
if (numberOfWeekendDays !== 0) {
|
||||
dueDate.setDate(dueDate.getDate() + numberOfWeekendDays);
|
||||
}
|
||||
|
||||
return dueDate;
|
||||
}
|
||||
|
||||
displayDueDateCountdown(createdAt) {
|
||||
displayDueDateCountdown() {
|
||||
const now = new Date(Date.now());
|
||||
const currentDay = now.getDay();
|
||||
const saturday = 6;
|
||||
const sunday = 0;
|
||||
const dueDate = this.calculateDueDate(createdAt);
|
||||
const dueDate = new Date(this.props.alertSummary.triage_due_date);
|
||||
|
||||
const differenceInTime = Math.abs(dueDate - now);
|
||||
const differenceInDays = Math.ceil(
|
||||
differenceInTime / (1000 * 60 * 60 * 24),
|
||||
);
|
||||
const differenceInHours = Math.ceil(differenceInTime / (1000 * 60 * 60));
|
||||
|
||||
// if the website is accessed during the weekend, nothing will be shown
|
||||
if (currentDay === saturday || currentDay === sunday) {
|
||||
|
@ -293,22 +275,18 @@ export default class StatusDropdown extends React.Component {
|
|||
}
|
||||
|
||||
if (now.getDate() === dueDate.getDate()) {
|
||||
return 'Today';
|
||||
return `Hours left: ${differenceInHours}`;
|
||||
}
|
||||
|
||||
if (now.getTime() >= dueDate.getTime()) {
|
||||
return 'Overdue';
|
||||
return `Overdue`;
|
||||
}
|
||||
|
||||
if (differenceInDays >= 4) {
|
||||
return `Working days left: ${differenceInDays - 2}`;
|
||||
return `Days left: ${differenceInDays - 2}`;
|
||||
}
|
||||
|
||||
if (this.isWeekend) {
|
||||
return `Working days left: ${differenceInDays - 2}`;
|
||||
}
|
||||
|
||||
return `Working days left: ${differenceInDays}`;
|
||||
return `Days left: ${differenceInDays}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -324,12 +302,12 @@ export default class StatusDropdown extends React.Component {
|
|||
const alertStatus = getStatus(alertSummary.status);
|
||||
const alertSummaryActiveTags = alertSummary.performance_tags || [];
|
||||
|
||||
const dueDateStatus = this.displayDueDateCountdown(alertSummary.created);
|
||||
const dueDateStatus = this.displayDueDateCountdown();
|
||||
|
||||
let dueDateClass = 'due-date-ok';
|
||||
if (dueDateStatus === 'Overdue') {
|
||||
dueDateClass = 'due-date-overdue';
|
||||
} else if (dueDateStatus === 'Today') {
|
||||
} else if (dueDateStatus.startsWith('Hours left:')) {
|
||||
dueDateClass = 'due-date-today';
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче