minor fix
This commit is contained in:
parent
5b38b8deaf
commit
e1360ced6c
4 changed files with 156 additions and 120 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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[] } = {
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue