mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: restrict edit schedule access (#2698)
This commit is contained in:
@@ -64,6 +64,7 @@ export const Workspace: FC<WorkspaceProps> = ({
|
||||
workspace={workspace}
|
||||
onDeadlineMinus={scheduleProps.onDeadlineMinus}
|
||||
onDeadlinePlus={scheduleProps.onDeadlinePlus}
|
||||
canUpdateWorkspace={canUpdateWorkspace}
|
||||
/>
|
||||
<WorkspaceActions
|
||||
workspace={workspace}
|
||||
|
||||
@@ -16,6 +16,11 @@ const THIRTY = 30
|
||||
export default {
|
||||
title: "components/WorkspaceSchedule",
|
||||
component: WorkspaceSchedule,
|
||||
argTypes: {
|
||||
canUpdateWorkspace: {
|
||||
defaultValue: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const Template: Story<WorkspaceScheduleProps> = (args) => <WorkspaceSchedule {...args} />
|
||||
@@ -40,7 +45,7 @@ NoTTL.args = {
|
||||
...Mocks.MockWorkspace,
|
||||
latest_build: {
|
||||
...Mocks.MockWorkspaceBuild,
|
||||
// a mannual shutdown has a deadline of '"0001-01-01T00:00:00Z"'
|
||||
// a manual shutdown has a deadline of '"0001-01-01T00:00:00Z"'
|
||||
// SEE: #1834
|
||||
deadline: "0001-01-01T00:00:00Z",
|
||||
},
|
||||
@@ -113,3 +118,17 @@ WorkspaceOffLong.args = {
|
||||
ttl_ms: 2 * 365 * 24 * 60 * 60 * 1000, // 2 years
|
||||
},
|
||||
}
|
||||
|
||||
export const CannotEdit = Template.bind({})
|
||||
CannotEdit.args = {
|
||||
workspace: {
|
||||
...Mocks.MockWorkspace,
|
||||
|
||||
latest_build: {
|
||||
...Mocks.MockWorkspaceBuild,
|
||||
transition: "stop",
|
||||
},
|
||||
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours
|
||||
},
|
||||
canUpdateWorkspace: false,
|
||||
}
|
||||
|
||||
@@ -33,9 +33,13 @@ export const Language = {
|
||||
|
||||
export interface WorkspaceScheduleProps {
|
||||
workspace: Workspace
|
||||
canUpdateWorkspace: boolean
|
||||
}
|
||||
|
||||
export const WorkspaceSchedule: FC<WorkspaceScheduleProps> = ({ workspace }) => {
|
||||
export const WorkspaceSchedule: FC<WorkspaceScheduleProps> = ({
|
||||
workspace,
|
||||
canUpdateWorkspace,
|
||||
}) => {
|
||||
const styles = useStyles()
|
||||
const timezone = workspace.autostart_schedule
|
||||
? extractTimezone(workspace.autostart_schedule)
|
||||
@@ -62,15 +66,17 @@ export const WorkspaceSchedule: FC<WorkspaceScheduleProps> = ({ workspace }) =>
|
||||
</span>
|
||||
</Stack>
|
||||
</div>
|
||||
<div>
|
||||
<Link
|
||||
className={styles.scheduleAction}
|
||||
component={RouterLink}
|
||||
to={`/@${workspace.owner_name}/${workspace.name}/schedule`}
|
||||
>
|
||||
{Language.editScheduleLink}
|
||||
</Link>
|
||||
</div>
|
||||
{canUpdateWorkspace && (
|
||||
<div>
|
||||
<Link
|
||||
className={styles.scheduleAction}
|
||||
component={RouterLink}
|
||||
to={`/@${workspace.owner_name}/${workspace.name}/schedule`}
|
||||
>
|
||||
{Language.editScheduleLink}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -16,6 +16,11 @@ const THIRTY = 30
|
||||
export default {
|
||||
title: "components/WorkspaceScheduleButton",
|
||||
component: WorkspaceScheduleButton,
|
||||
argTypes: {
|
||||
canUpdateWorkspace: {
|
||||
defaultValue: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const Template: Story<WorkspaceScheduleButtonProps> = (args) => (
|
||||
@@ -115,3 +120,17 @@ WorkspaceOffLong.args = {
|
||||
ttl_ms: 2 * 365 * 24 * 60 * 60 * 1000, // 2 years
|
||||
},
|
||||
}
|
||||
|
||||
export const CannotEdit = Template.bind({})
|
||||
CannotEdit.args = {
|
||||
workspace: {
|
||||
...Mocks.MockWorkspace,
|
||||
|
||||
latest_build: {
|
||||
...Mocks.MockWorkspaceBuild,
|
||||
transition: "stop",
|
||||
},
|
||||
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours
|
||||
},
|
||||
canUpdateWorkspace: false,
|
||||
}
|
||||
|
||||
@@ -54,12 +54,14 @@ export interface WorkspaceScheduleButtonProps {
|
||||
workspace: Workspace
|
||||
onDeadlinePlus: () => void
|
||||
onDeadlineMinus: () => void
|
||||
canUpdateWorkspace: boolean
|
||||
}
|
||||
|
||||
export const WorkspaceScheduleButton: React.FC<WorkspaceScheduleButtonProps> = ({
|
||||
workspace,
|
||||
onDeadlinePlus,
|
||||
onDeadlineMinus,
|
||||
canUpdateWorkspace,
|
||||
}) => {
|
||||
const anchorRef = useRef<HTMLButtonElement>(null)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
@@ -74,7 +76,7 @@ export const WorkspaceScheduleButton: React.FC<WorkspaceScheduleButtonProps> = (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.label}>
|
||||
<WorkspaceScheduleLabel workspace={workspace} />
|
||||
{shouldDisplayPlusMinus(workspace) && (
|
||||
{canUpdateWorkspace && shouldDisplayPlusMinus(workspace) && (
|
||||
<Stack direction="row" spacing={0}>
|
||||
<IconButton
|
||||
className={styles.iconButton}
|
||||
@@ -124,7 +126,7 @@ export const WorkspaceScheduleButton: React.FC<WorkspaceScheduleButtonProps> = (
|
||||
horizontal: "right",
|
||||
}}
|
||||
>
|
||||
<WorkspaceSchedule workspace={workspace} />
|
||||
<WorkspaceSchedule workspace={workspace} canUpdateWorkspace={canUpdateWorkspace} />
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user