minor fix

This commit is contained in:
Maxim 2022-10-12 08:54:20 +01:00
parent 5b38b8deaf
commit e1360ced6c
4 changed files with 156 additions and 120 deletions

View file

@ -62,10 +62,12 @@ const TimelineMarks: FC<TimelineMarksProps> = (props) => {
</svg>
)}
{momentsToRender.map((m, i) => {
const isCurrentDay = currentMoment.isSame(m.moment, 'day');
return (
<div key={i} className={cx('weekday')}>
<div className={cx('weekday-title')}>
<Text type="secondary" strong={currentMoment.isSame(m.moment, 'day')}>
<Text type="secondary" strong={isCurrentDay}>
{m.moment.format('ddd D MMM')}
</Text>
</div>

View file

@ -5,6 +5,18 @@ import { PRIVATE_CHANNEL_NAME } from 'models/slack_channel/slack_channel.config'
import { DEFAULT_USER_ROLES } from 'models/user/user.config';
const commonFields: FormItem[] = [
{
name: 'team',
label: 'Assign to team',
type: FormItemType.GSelect,
extra: {
modelName: 'grafanaTeamStore',
displayField: 'name',
valueField: 'id',
showSearch: true,
allowClear: true,
},
},
{
name: 'slack_channel_id',
label: 'Slack channel',
@ -19,6 +31,19 @@ const commonFields: FormItem[] = [
description:
'Calendar parsing errors and notifications about the new on-call shift will be published in this channel.',
},
{
name: 'user_group',
label: 'Slack user group',
type: FormItemType.GSelect,
extra: {
modelName: 'userGroupStore',
displayField: 'handle',
showSearch: true,
allowClear: true,
},
description:
'Group members will be automatically updated with current on-call. In case you want to ping on-call with @group_name.',
},
{
name: 'notify_oncall_shift_freq',
label: 'Notification frequency',
@ -67,37 +92,12 @@ const commonFields: FormItem[] = [
},
description: 'Specify how to notify a team member when their shift is the next one scheduled',
},
{
name: 'user_group',
label: 'Slack user group',
type: FormItemType.GSelect,
extra: {
modelName: 'userGroupStore',
displayField: 'handle',
showSearch: true,
allowClear: true,
},
description:
'Group members will be automatically updated with current on-call. In case you want to ping on-call with @group_name.',
},
// {
// name: 'send_empty_shifts_report',
// normalize: (value) => Boolean(value),
// label: 'Send reports about empty shifts to Slack',
// type: FormItemType.Switch,
// },
{
name: 'team',
label: 'Assign to team',
type: FormItemType.GSelect,
extra: {
modelName: 'grafanaTeamStore',
displayField: 'name',
valueField: 'id',
showSearch: true,
allowClear: true,
},
},
];
export const iCalForm: { name: string; fields: FormItem[] } = {

View file

@ -78,10 +78,10 @@ const ScheduleForm = observer((props: ScheduleFormProps) => {
>
<div className={cx('content')}>
<VerticalGroup>
<Text type="secondary">
{/*<Text type="secondary">
Manage on-call schedules using your favourite calendar app, such as Google Calendar or Microsoft Outlook. To
schedule on-call shifts create a new calendar and use events with the teammates usernames
</Text>
</Text>*/}
<GForm form={formConfig} data={data} onSubmit={handleSubmit} />
<WithPermissionControl userAction={UserAction.UpdateSchedules}>
<Button form={formConfig.name} type="submit">

View file

@ -28,6 +28,7 @@ import WithConfirm from 'components/WithConfirm/WithConfirm';
import Rotations from 'containers/Rotations/Rotations';
import ScheduleFinal from 'containers/Rotations/ScheduleFinal';
import ScheduleOverrides from 'containers/Rotations/ScheduleOverrides';
import ScheduleForm from 'containers/ScheduleForm/ScheduleForm';
import UsersTimezones from 'containers/UsersTimezones/UsersTimezones';
import { Shift } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
@ -48,6 +49,7 @@ interface SchedulePageState {
renderType: string;
shiftIdToShowRotationForm?: Shift['id'];
shiftIdToShowOverridesForm?: Shift['id'];
showEditForm: boolean;
}
const INITIAL_TIMEZONE = 'UTC'; // todo check why doesn't work
@ -64,6 +66,7 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
renderType: 'timeline',
shiftIdToShowRotationForm: undefined,
shiftIdToShowOverridesForm: undefined,
showEditForm: false,
};
}
@ -96,8 +99,14 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
render() {
const { store } = this.props;
const { startMoment, schedulePeriodType, renderType, shiftIdToShowRotationForm, shiftIdToShowOverridesForm } =
this.state;
const {
startMoment,
schedulePeriodType,
renderType,
shiftIdToShowRotationForm,
shiftIdToShowOverridesForm,
showEditForm,
} = this.state;
const { query } = this.props;
const { id: scheduleId } = query;
@ -108,18 +117,19 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
const schedule = scheduleStore.items[scheduleId];
return (
<div className={cx('root')}>
<VerticalGroup spacing="lg">
<div className={cx('header')}>
<HorizontalGroup justify="space-between">
<HorizontalGroup>
<PluginLink query={{ page: 'schedules-new' }}>
<IconButton style={{ marginTop: '5px' }} name="arrow-left" size="xl" />
</PluginLink>
<Text.Title editable editModalTitle="Schedule name" level={2} onTextChange={this.handleNameChange}>
{schedule?.name}
</Text.Title>
{/*<ScheduleCounter
<>
<div className={cx('root')}>
<VerticalGroup spacing="lg">
<div className={cx('header')}>
<HorizontalGroup justify="space-between">
<HorizontalGroup>
<PluginLink query={{ page: 'schedules-new' }}>
<IconButton style={{ marginTop: '5px' }} name="arrow-left" size="xl" />
</PluginLink>
<Text.Title editable editModalTitle="Schedule name" level={2} onTextChange={this.handleNameChange}>
{schedule?.name}
</Text.Title>
{/*<ScheduleCounter
type="link"
count={5}
tooltipTitle="Used in escalations"
@ -139,60 +149,66 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
tooltipTitle="Warnings"
tooltipContent="Schedule has unassigned time periods during next 7 days"
/>*/}
</HorizontalGroup>
<HorizontalGroup spacing="lg">
{users && (
<HorizontalGroup>
<Text type="secondary">Current timezone:</Text>
<UserTimezoneSelect value={currentTimezone} users={users} onChange={this.handleTimezoneChange} />
</HorizontalGroup>
)}
{/*<ScheduleQuality quality={0.89} />*/}
{/*<ToolbarButton icon="copy" tooltip="Copy" />
</HorizontalGroup>
<HorizontalGroup spacing="lg">
{users && (
<HorizontalGroup>
<Text type="secondary">Current timezone:</Text>
<UserTimezoneSelect value={currentTimezone} users={users} onChange={this.handleTimezoneChange} />
</HorizontalGroup>
)}
{/*<ScheduleQuality quality={0.89} />*/}
{/*<ToolbarButton icon="copy" tooltip="Copy" />
<ToolbarButton icon="brackets-curly" tooltip="Code" />
<ToolbarButton icon="share-alt" tooltip="Share" />
*/}
<HorizontalGroup>
<ToolbarButton icon="cog" tooltip="Settings" />
<WithConfirm>
<ToolbarButton icon="trash-alt" tooltip="Delete" onClick={this.handleDelete} />
</WithConfirm>
<HorizontalGroup>
<ToolbarButton
icon="cog"
tooltip="Settings"
onClick={() => {
this.setState({ showEditForm: true });
}}
/>
<WithConfirm>
<ToolbarButton icon="trash-alt" tooltip="Delete" onClick={this.handleDelete} />
</WithConfirm>
</HorizontalGroup>
</HorizontalGroup>
</HorizontalGroup>
</HorizontalGroup>
</div>
<div className={cx('users-timezones')}>
<UsersTimezones
onCallNow={schedule?.on_call_now || []}
userIds={
scheduleStore.relatedUsers[scheduleId] ? Object.keys(scheduleStore.relatedUsers[scheduleId]) : []
}
tz={currentTimezone}
onTzChange={this.handleTimezoneChange}
/>
</div>
</div>
<div className={cx('users-timezones')}>
<UsersTimezones
onCallNow={schedule?.on_call_now || []}
userIds={
scheduleStore.relatedUsers[scheduleId] ? Object.keys(scheduleStore.relatedUsers[scheduleId]) : []
}
tz={currentTimezone}
onTzChange={this.handleTimezoneChange}
/>
</div>
{/* <div className={'current-time'} />*/}
<div className={cx('rotations')}>
<div className={cx('controls')}>
<HorizontalGroup justify="space-between">
<HorizontalGroup>
<Button variant="secondary" onClick={this.handleTodayClick}>
Today
</Button>
<HorizontalGroup spacing="xs">
<Button variant="secondary" onClick={this.handleLeftClick}>
<Icon name="angle-left" />
</Button>
<Button variant="secondary" onClick={this.handleRightClick}>
<Icon name="angle-right" />
{/* <div className={'current-time'} />*/}
<div className={cx('rotations')}>
<div className={cx('controls')}>
<HorizontalGroup justify="space-between">
<HorizontalGroup>
<Button variant="secondary" onClick={this.handleTodayClick}>
Today
</Button>
<HorizontalGroup spacing="xs">
<Button variant="secondary" onClick={this.handleLeftClick}>
<Icon name="angle-left" />
</Button>
<Button variant="secondary" onClick={this.handleRightClick}>
<Icon name="angle-right" />
</Button>
</HorizontalGroup>
<Text.Title style={{ marginLeft: '8px' }} level={4} type="primary">
{startMoment.format('DD MMM')} - {startMoment.add(6, 'day').format('DD MMM')}
</Text.Title>
</HorizontalGroup>
<Text.Title style={{ marginLeft: '8px' }} level={4} type="primary">
{startMoment.format('DD MMM')} - {startMoment.add(6, 'day').format('DD MMM')}
</Text.Title>
</HorizontalGroup>
{/*<HorizontalGroup width="auto">
{/*<HorizontalGroup width="auto">
<RadioButtonGroup
options={[
{ label: 'Day', value: 'day' },
@ -218,42 +234,60 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
onChange={this.handleRenderTypeChange}
/>
</HorizontalGroup>*/}
</HorizontalGroup>
</HorizontalGroup>
</div>
<ScheduleFinal
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onClick={this.handleShowForm}
/>
<Rotations
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onCreate={this.handleCreateRotation}
onUpdate={this.handleUpdateRotation}
onDelete={this.handleDeleteRotation}
shiftIdToShowRotationForm={shiftIdToShowRotationForm}
onShowRotationForm={this.handleShowRotationForm}
disabled={shiftIdToShowRotationForm || shiftIdToShowOverridesForm}
/>
<ScheduleOverrides
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onCreate={this.handleCreateOverride}
onUpdate={this.handleUpdateOverride}
onDelete={this.handleDeleteOverride}
shiftIdToShowRotationForm={shiftIdToShowOverridesForm}
onShowRotationForm={this.handleShowOverridesForm}
disabled={shiftIdToShowRotationForm || shiftIdToShowOverridesForm}
/>
</div>
<ScheduleFinal
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onClick={this.handleShowForm}
/>
<Rotations
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onCreate={this.handleCreateRotation}
onUpdate={this.handleUpdateRotation}
onDelete={this.handleDeleteRotation}
shiftIdToShowRotationForm={shiftIdToShowRotationForm}
onShowRotationForm={this.handleShowRotationForm}
disabled={shiftIdToShowRotationForm || shiftIdToShowOverridesForm}
/>
<ScheduleOverrides
scheduleId={scheduleId}
currentTimezone={currentTimezone}
startMoment={startMoment}
onCreate={this.handleCreateOverride}
onUpdate={this.handleUpdateOverride}
onDelete={this.handleDeleteOverride}
shiftIdToShowRotationForm={shiftIdToShowOverridesForm}
onShowRotationForm={this.handleShowOverridesForm}
disabled={shiftIdToShowRotationForm || shiftIdToShowOverridesForm}
/>
</div>
</VerticalGroup>
</div>
</VerticalGroup>
</div>
{showEditForm && (
<ScheduleForm
id={schedule.id}
onUpdate={this.update}
onHide={() => {
this.setState({ showEditForm: false });
}}
/>
)}
</>
);
}
update = () => {
const { store, query } = this.props;
const { id: scheduleId } = query;
const { scheduleStore } = store;
return scheduleStore.updateItem(scheduleId);
};
handleShowForm = async (shiftId: Shift['id'] | 'new') => {
const {
store: { scheduleStore },