diff --git a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx index b1fa8834..cc6ee209 100644 --- a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx +++ b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx @@ -42,7 +42,7 @@ const SchedulesFilters = (props: SchedulesFiltersProps) => { return (
- + = (props) => { return (
-
); }; diff --git a/grafana-plugin/src/containers/RotationForm/RotationForm.module.css b/grafana-plugin/src/containers/RotationForm/RotationForm.module.css index 26042e17..a37c588e 100644 --- a/grafana-plugin/src/containers/RotationForm/RotationForm.module.css +++ b/grafana-plugin/src/containers/RotationForm/RotationForm.module.css @@ -22,6 +22,9 @@ padding: 6px 10px; z-index: 1; color: #fff; + width: 330px; + overflow: hidden; + white-space: nowrap; } .working-hours { diff --git a/grafana-plugin/src/containers/Rotations/Rotations.tsx b/grafana-plugin/src/containers/Rotations/Rotations.tsx index a309cbc1..fe8eb348 100644 --- a/grafana-plugin/src/containers/Rotations/Rotations.tsx +++ b/grafana-plugin/src/containers/Rotations/Rotations.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { SelectableValue } from '@grafana/data'; -import { ValuePicker, HorizontalGroup, Button } from '@grafana/ui'; +import { ValuePicker, HorizontalGroup, Button, Tooltip } from '@grafana/ui'; import cn from 'classnames/bind'; import dayjs from 'dayjs'; import { observer } from 'mobx-react'; @@ -13,7 +13,7 @@ import Rotation from 'containers/Rotation/Rotation'; import RotationForm from 'containers/RotationForm/RotationForm'; import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; import { getColor, getFromString } from 'models/schedule/schedule.helpers'; -import { Layer, Schedule, Shift } from 'models/schedule/schedule.types'; +import { Layer, Schedule, ScheduleType, Shift } from 'models/schedule/schedule.types'; import { Timezone } from 'models/timezone/timezone.types'; import { WithStoreProps } from 'state/types'; import { UserAction } from 'state/userAction'; @@ -87,6 +87,11 @@ class Rotations extends Component { options.push({ label: 'New Layer', value: nextPriority }); + const schedule = store.scheduleStore.items[scheduleId]; + + const isTypeReadOnly = + schedule && (schedule?.type === ScheduleType.Ical || schedule?.type === ScheduleType.Calendar); + return ( <>
@@ -98,11 +103,21 @@ class Rotations extends Component {
{disabled ? ( - - - + isTypeReadOnly ? ( + +
+ +
+
+ ) : ( + + + + ) ) : ( 1; + const schedule = store.scheduleStore.items[scheduleId]; + + const isTypeReadOnly = + schedule && (schedule?.type === ScheduleType.Ical || schedule?.type === ScheduleType.Calendar); + return ( <>
@@ -80,11 +85,21 @@ class ScheduleOverrides extends Component
- - - + {isTypeReadOnly ? ( + +
+ +
+
+ ) : ( + + + + )}
diff --git a/grafana-plugin/src/models/user/user.ts b/grafana-plugin/src/models/user/user.ts index d790ed8e..3db546fc 100644 --- a/grafana-plugin/src/models/user/user.ts +++ b/grafana-plugin/src/models/user/user.ts @@ -19,6 +19,8 @@ export class UserStore extends BaseStore { @observable.shallow items: { [pk: string]: User } = {}; + itemsCurrentlyUpdating = {}; + @observable notificationPolicies: any = {}; @@ -87,12 +89,20 @@ export class UserStore extends BaseStore { @action async updateItem(userPk: User['pk']) { + if (this.itemsCurrentlyUpdating[userPk]) { + return; + } + + this.itemsCurrentlyUpdating[userPk] = true; + const user = await this.getById(userPk); this.items = { ...this.items, [user.pk]: { ...user, timezone: getTimezone(user) }, }; + + delete this.itemsCurrentlyUpdating[userPk]; } @action diff --git a/grafana-plugin/src/pages/schedule/Schedule.tsx b/grafana-plugin/src/pages/schedule/Schedule.tsx index 8ac61496..1f155226 100644 --- a/grafana-plugin/src/pages/schedule/Schedule.tsx +++ b/grafana-plugin/src/pages/schedule/Schedule.tsx @@ -6,7 +6,6 @@ import { Button, HorizontalGroup, VerticalGroup, IconButton, ToolbarButton, Icon import { PluginPage } from 'PluginPage'; import cn from 'classnames/bind'; import dayjs from 'dayjs'; -import { omit } from 'lodash-es'; import { observer } from 'mobx-react'; import PageErrorHandlingWrapper from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper'; @@ -138,16 +137,16 @@ class SchedulePage extends React.Component )} - {schedule?.type === ScheduleType.Ical && ( - - + + + {(schedule?.type === ScheduleType.Ical || schedule?.type === ScheduleType.Calendar) && ( - - )} + )} +
- {schedule?.type !== ScheduleType.API && ( - - Ical and API/Terraform schedules are read-only - - )}
return async () => { await scheduleStore.reloadIcal(scheduleId); - scheduleStore.updateItem(scheduleId); - this.updateEventsFor(scheduleId); + store.scheduleStore.updateOncallShifts(scheduleId); + this.updateEvents(); }; }; - updateEventsFor = async (scheduleId: Schedule['id'], withEmpty = true, with_gap = true) => { - const { store } = this.props; - const { id } = getQueryParams(); - - const { scheduleStore } = store; - - store.scheduleStore.scheduleToScheduleEvents = omit(store.scheduleStore.scheduleToScheduleEvents, [scheduleId]); - - await scheduleStore.updateScheduleEvents( - scheduleId, - withEmpty, - with_gap, - dayjs().format('YYYY-MM-DD').toString(), - dayjs.tz.guess() - ); - - await store.scheduleStore.updateOncallShifts(id); - await this.updateEvents(); - }; - handleDelete = () => { const { store } = this.props; const { id: scheduleId } = getQueryParams(); diff --git a/grafana-plugin/src/pages/schedules/Schedules.module.css b/grafana-plugin/src/pages/schedules/Schedules.module.css index c1fce1b8..bb044563 100644 --- a/grafana-plugin/src/pages/schedules/Schedules.module.css +++ b/grafana-plugin/src/pages/schedules/Schedules.module.css @@ -1,6 +1,7 @@ .schedule { position: relative; margin: 20px 0; + max-width: calc(100vw - 104px); } .title {