Skip to content

Commit

Permalink
Merge pull request #4426 from grafana/dev
Browse files Browse the repository at this point in the history
v1.5.4
  • Loading branch information
mderynck authored May 30, 2024
2 parents 404121e + 08d1e00 commit d7bf353
Show file tree
Hide file tree
Showing 35 changed files with 950 additions and 599 deletions.
2 changes: 2 additions & 0 deletions engine/apps/alerts/tasks/check_escalation_finished.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ def check_escalation_finished_task() -> None:
if total_alert_groups_count == 0
else (total_alert_groups_count - failed_alert_groups_count) / total_alert_groups_count * 100
)
task_logger.info(f"Alert groups that failed escalation: {failed_alert_groups_count}")
task_logger.info(f"Alert groups total: {total_alert_groups_count}")
task_logger.info(f"Alert group notifications success ratio: {success_ratio:.2f}")

if alert_group_ids_that_failed_audit:
Expand Down
7 changes: 6 additions & 1 deletion engine/apps/slack/models/slack_usergroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ def update_or_create_slack_usergroup_from_slack(cls, slack_id: str, slack_team_i
sc = SlackClient(slack_team_identity)
usergroups = sc.usergroups_list()["usergroups"]

usergroup = [ug for ug in usergroups if ug["id"] == slack_id][0]
try:
usergroup = [ug for ug in usergroups if ug["id"] == slack_id][0]
except IndexError:
# user group not found
return

try:
members = sc.usergroups_users_list(usergroup=usergroup["id"])["users"]
except SlackAPIError:
Expand Down
21 changes: 21 additions & 0 deletions engine/apps/slack/tests/test_user_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,27 @@ def test_update_or_create_slack_usergroup_from_slack(
assert usergroup.is_active


@patch.object(
SlackClient,
"usergroups_list",
return_value=build_slack_response(
{
"ok": True,
"usergroups": [{"id": "test_slack_id", "name": "test_name", "handle": "test_handle", "date_delete": 0}],
}
),
)
@pytest.mark.django_db
def test_update_or_create_slack_usergroup_from_slack_group_not_found(
mock_usergroups_list, make_organization_with_slack_team_identity
):
organization, slack_team_identity = make_organization_with_slack_team_identity()
SlackUserGroup.update_or_create_slack_usergroup_from_slack("other_id", slack_team_identity)

# no group is created, no error is raised
assert SlackUserGroup.objects.count() == 0


@patch.object(
SlackClient,
"usergroups_users_list",
Expand Down
8 changes: 0 additions & 8 deletions grafana-plugin/.config/webpack/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,6 @@ const config = async (env): Promise<Configuration> => {
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.s[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpe?g|gif|svg)$/,
type: 'asset/resource',
Expand Down
31 changes: 31 additions & 0 deletions grafana-plugin/e2e-tests/schedules/scheduleView.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { scheduleViewToDaysInOneRow } from 'models/schedule/schedule.helpers';
import { ScheduleView } from 'models/schedule/schedule.types';
import { HTML_ID } from 'utils/DOM';

import { expect, test } from '../fixtures';
import { generateRandomValue } from '../utils/forms';
import { createOnCallScheduleWithRotation } from '../utils/schedule';

test.skip('schedule view (week/2 weeks/month) toggler works', async ({ adminRolePage }) => {
const { page, userName } = adminRolePage;

const onCallScheduleName = generateRandomValue();
await createOnCallScheduleWithRotation(page, onCallScheduleName, userName);

// ScheduleView.OneWeek is selected by default
expect(await page.getByLabel(ScheduleView.OneWeek, { exact: true }).isChecked()).toBe(true);

expect(await page.locator(`#${HTML_ID.SCHEDULE_FINAL} .TEST_weekday`).count()).toStrictEqual(
scheduleViewToDaysInOneRow[ScheduleView.OneWeek]
);

await page.getByLabel(ScheduleView.TwoWeeks, { exact: true }).click();
expect(await page.getByLabel(ScheduleView.TwoWeeks, { exact: true }).isChecked()).toBe(true);
expect(await page.locator(`#${HTML_ID.SCHEDULE_FINAL} .TEST_weekday`).count()).toStrictEqual(
scheduleViewToDaysInOneRow[ScheduleView.TwoWeeks]
);

await page.getByLabel(ScheduleView.OneMonth, { exact: true }).click();
expect(await page.getByLabel(ScheduleView.OneMonth, { exact: true }).isChecked()).toBe(true);
expect(await page.locator(`#${HTML_ID.SCHEDULE_FINAL} .TEST_weekday`).count()).toBeGreaterThanOrEqual(28);
});
2 changes: 2 additions & 0 deletions grafana-plugin/src/assets/style/vars.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
--hover-selected: #f4f5f5;
--background-canvas: #f4f5f5;
--background-secondary: #f4f5f5;
--background-disabled: rgba(204, 204, 220, 0.11);
--border-medium-color: rgba(36, 41, 46, 0.3);
--border-medium: 1px solid rgba(36, 41, 46, 0.3);
--border-strong: 1px solid rgba(36, 41, 46, 0.4);
Expand Down Expand Up @@ -61,6 +62,7 @@
--oncall-icon-stroke-color: #181b1f;
--background-canvas: #111217;
--background-secondary: #22252b;
--background-disabled: rgba(204, 204, 220, 0.04);
--border-medium-color: rgba(204, 204, 220, 0.15);
--border-medium: 1px solid rgba(204, 204, 220, 0.15);
--border-strong: 1px solid rgba(204, 204, 220, 0.25);
Expand Down
25 changes: 0 additions & 25 deletions grafana-plugin/src/containers/Rotation/Rotation.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
position: relative;
}

.root:last-child .timeline {
padding-bottom: 0;
}

.slots {
width: 100%;
display: flex;
Expand All @@ -39,10 +35,6 @@
opacity: 0.5;
}

.slots__animate {
transition: transform 500ms ease;
}

.current-time {
position: absolute;
left: 450px;
Expand All @@ -64,11 +56,6 @@
margin: 0 2px;
}

.slots--tutorial {
position: absolute;
background: rgba(61, 113, 217, 0.15);
}

.pointer {
position: absolute;
top: -9px;
Expand All @@ -82,15 +69,3 @@
transform: scale(1);
opacity: 1;
}

.tutorial-slot {
width: 175px;
height: 28px;
border-radius: 2px;
margin: 0 1px;
padding: 4px;
}

.tutorial-slot--active {
box-shadow: var(--shadows-z3);
}
34 changes: 19 additions & 15 deletions grafana-plugin/src/containers/Rotation/Rotation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useMemo, useState } from 'react';
import React, { FC, useMemo } from 'react';

import { HorizontalGroup, LoadingPlaceholder } from '@grafana/ui';
import cn from 'classnames/bind';
Expand All @@ -9,11 +9,10 @@ import hash from 'object-hash';
import { ScheduleFiltersType } from 'components/ScheduleFilters/ScheduleFilters.types';
import { Text } from 'components/Text/Text';
import { ScheduleSlot } from 'containers/ScheduleSlot/ScheduleSlot';
import { Event, RotationFormLiveParams, ShiftSwap } from 'models/schedule/schedule.types';
import { scheduleViewToDaysInOneRow } from 'models/schedule/schedule.helpers';
import { Event, ScheduleView, ShiftSwap } from 'models/schedule/schedule.types';
import { useStore } from 'state/useStore';

import { RotationTutorial } from './RotationTutorial';

import styles from './Rotation.module.css';

const cx = cn.bind(styles);
Expand All @@ -28,27 +27,26 @@ interface RotationProps {
handleAddShiftSwap?: (id: 'new', params: Partial<ShiftSwap>) => void;
handleOpenSchedule?: (event: Event) => void;
onShiftSwapClick?: (swapId: ShiftSwap['id']) => void;
days?: number;
transparent?: boolean;
tutorialParams?: RotationFormLiveParams;
simplified?: boolean;
filters?: ScheduleFiltersType;
getColor?: (event: Event) => string;
onSlotClick?: (event: Event) => void;
emptyText?: string;
showScheduleNameAsSlotTitle?: boolean;
startDate?: dayjs.Dayjs;
scheduleView?: ScheduleView;
}

export const Rotation: FC<RotationProps> = observer((props) => {
const {
timezoneStore: { calendarStartDate, getDateInSelectedTimezone },
scheduleStore: { scheduleView: storeScheduleView },
} = useStore();
const {
events,
color: propsColor,
days = 7,
transparent = false,
tutorialParams,
onClick,
handleAddOverride,
handleAddShiftSwap,
Expand All @@ -60,18 +58,24 @@ export const Rotation: FC<RotationProps> = observer((props) => {
onSlotClick,
emptyText,
showScheduleNameAsSlotTitle,
startDate: propsStartDate,
scheduleView: propsScheduleView,
} = props;

const [animate, _setAnimate] = useState<boolean>(true);
const scheduleView = propsScheduleView || storeScheduleView;

const startDate = propsStartDate || calendarStartDate;

const days = scheduleViewToDaysInOneRow[scheduleView];

const handleRotationClick = (event: React.MouseEvent<HTMLDivElement>) => {
const rect = event.currentTarget.getBoundingClientRect();
const x = event.clientX - rect.left; //x position within the element.
const width = event.currentTarget.offsetWidth;

const dayOffset = Math.floor((x / width) * 7);
const dayOffset = Math.floor((x / width) * scheduleViewToDaysInOneRow[scheduleView]);

const shiftStart = calendarStartDate.add(dayOffset, 'day');
const shiftStart = startDate.add(dayOffset, 'day');
const shiftEnd = shiftStart.add(1, 'day');

onClick(shiftStart, shiftEnd);
Expand Down Expand Up @@ -134,27 +138,27 @@ export const Rotation: FC<RotationProps> = observer((props) => {

const firstShift = events[0];
const firstShiftOffset = getDateInSelectedTimezone(firstShift.start).diff(
getDateInSelectedTimezone(calendarStartDate),
getDateInSelectedTimezone(startDate),
'seconds'
);
const base = 60 * 60 * 24 * days;

return firstShiftOffset / base;
}, [events, calendarStartDate]);
}, [events, startDate]);

return (
<div className={cx('root')} onClick={onClick && handleRotationClick}>
<div className={cx('timeline')}>
{tutorialParams && <RotationTutorial {...tutorialParams} />}
{events ? (
events.length ? (
<div
className={cx('slots', { slots__animate: animate, slots__transparent: transparent })}
className={cx('slots', { slots__transparent: transparent })}
style={{ transform: `translate(${x * 100}%, 0)` }}
>
{events.map((event) => {
return (
<ScheduleSlot
scheduleView={scheduleView}
key={hash(event)}
event={event}
color={propsColor || getColor(event)}
Expand Down
117 changes: 0 additions & 117 deletions grafana-plugin/src/containers/Rotation/RotationTutorial.tsx

This file was deleted.

Loading

0 comments on commit d7bf353

Please sign in to comment.