Closes#17791
This PR adds ability to cancel workspace builds that are in "pending"
status.
Breaking changes:
- CancelWorkspaceBuild method in codersdk now accepts an optional
request parameter
API:
- Added `expect_status` query parameter to the cancel workspace build
endpoint
- This parameter ensures the job hasn't changed state before canceling
- API returns `412 Precondition Failed` if the job is not in the
expected status
- Valid values: `running` or `pending`
- Wrapped the entire cancel method in a database transaction
UI:
- Added confirmation dialog to the `Cancel` button, since it's a
destructive operation


- Enabled cancel action for pending workspaces (`expect_status=pending`
is sent if workspace is in pending status)

---------
Co-authored-by: Dean Sheather <dean@deansheather.com>
resolve#18361
Its possible for a dynamic parameter option value to be an empty string
which will cause the following error in the Radix Select component. The
solution is to handle empty strings so that they are not set directly in
the component.
`Uncaught Error: A <Select.Item /> must have a value prop that is not an
empty string. This is because the Select value can be set to an empty
string to clear the selection and show the placeholder.`
```
data "coder_parameter" "radio" {
name = "radio"
display_name = "An example of a radio input"
description = "The next parameter supports a single value."
type = "string"
form_type = "dropdown"
order = 1
default = ""
option {
name = "Empty"
value = ""
}
}
```
Alternate fix for https://github.com/coder/coder/issues/18080
Modifies wsbuilder to complete the provisioner job and mark the
workspace as deleted if it is clear that no provisioner will be able to
pick up the delete build.
This has a significant advantage of not deviating too much from the
current semantics of `POST /api/v2/workspacebuilds`.
https://github.com/coder/coder/pull/18460 ends up returning a 204 on
orphan delete due to no build being created.
Downside is that we have to duplicate some responsibilities of
provisionerdserver in wsbuilder.
There is a slight gotcha to this approach though: if you stop a
provisioner and then immediately try to orphan-delete, the job will
still be created because of the provisioner heartbeat interval. However
you can cancel it and try again.
Fixes https://github.com/coder/coder/issues/17840
NOTE: calling this out as a breaking change so that it is highly visible
in the changelog.
* CLI: Modifies `coder update` to stop the workspace if already running.
* UI: Modifies "update" button to always stop the workspace if already
running.
"Idle" is more accurate than "complete" since:
1. AgentAPI only knows if the screen is active; it has no way of knowing
if the task is complete.
2. The LLM might be done with its current prompt, but that does not mean
the task is complete either (it likely needs refinement).
The "complete" state will be reserved for future definition.
Additionally, in the case where the screen goes idle but the LLM never
reported a status update, we can get an idle icon without a message, and
it looks kinda janky in the UI so if there is no message I display the
state text.
Closes https://github.com/coder/internal/issues/699
resolves#17709
FYI, blink created a first draft which was heavily modified.
## Summary
This PR implements ephemeral parameter handling for workspace
start/restart operations when templates use dynamic parameters
(`use_classic_parameter_flow = false`).
<img width="522" alt="Screenshot 2025-06-18 at 14 35 54"
src="https://github.com/user-attachments/assets/450527c0-cc88-4fc3-b0fa-170bdeb5ea51"
/>
<img width="327" alt="Screenshot 2025-06-18 at 14 35 43"
src="https://github.com/user-attachments/assets/ea74bf8e-d127-489d-b406-edfc5ec1e9a8"
/>

## Changes
### 1. EphemeralParametersDialog Component
- **New**: `site/src/components/EphemeralParametersDialog/`
- Shows a dialog when starting/restarting workspaces with ephemeral
parameters
- Lists ephemeral parameters with names and descriptions
- Provides options to continue without setting values or navigate to
parameters page
### 2. WorkspaceReadyPage Updates
- Added `checkEphemeralParameters()` function using
`API.getDynamicParameters`
- Modified `handleStart` and `handleRestart` to check for ephemeral
parameters
- Only triggers for templates with `use_classic_parameter_flow = false`
- Shows dialog if ephemeral parameters exist, otherwise proceeds
normally
### 3. BuildParametersPopover Updates
- Added special UI for non-classic parameter flow templates with
ephemeral parameters
- Lists ephemeral parameters with descriptions
- Explains that users must use the workspace parameters page
- Provides direct link to `WorkspaceParametersPageExperimental`
---------
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: jaaydenh <1858163+jaaydenh@users.noreply.github.com>
Co-authored-by: Jaayden Halko <jaayden@coder.com>
This removes the opt-in and opt-out buttons for dynamic parameters on
the create workspace page and the workspace parameters settings page.
---------
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
Set the form parameters using autofill parameters based on the workspace
build parameters for the latest build
---------
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
Normally parameters had red text for error diagnostics. The goal here is
to make errors more obvious when the form_type is error meaning the
parameter could not be processed correctly.
<img width="543" alt="Screenshot 2025-05-27 at 18 35 50"
src="https://github.com/user-attachments/assets/2265553e-34a3-4526-8209-6253d541f784"
/>
Relates to https://github.com/coder/coder/issues/15432
* Adds a storybook entry for zero values in provisioner timings.
* Coerces a 'zero' start time to an 'instant'.
* Improves timing chart handling for large timeframes. Previously, this
would have caused the tab to run out of memory when encountering a
`time.Time{}`.
* Render 'instants' as 'invalid' in timing chart.
This change replaces date-fns with dayjs throughout the codebase for
more consistent date/time handling and to reduce bundle size. It also
tries to make the formatting and usage consistent.
**Why dayjs over date-fns?**
Just because we were using dayjs more broadly. Its formatting
capabilities, were also easier to extend.
The goal is to better integrate the activity column data with the
existent data:
- Make the message one line, the full message is in the tooltip, and
display the state at the bottom. This way, it is visually consistent
with the other columns like status, name and template.
- Moved the app, and uri, to the actions column, instead of showing them
together with the message in the activity column.
**Previous:**
<img width="1512" alt="Screenshot 2025-05-21 at 17 28 46"
src="https://github.com/user-attachments/assets/ea9188a5-d82e-416c-b961-edf0104f66c6"
/>
**After:**
<img width="1512" alt="Screenshot 2025-05-21 at 17 28 57"
src="https://github.com/user-attachments/assets/f50dbe82-cd3e-4448-9fa2-bde9193166d6"
/>
This adds a few fixes to get presets working correctly with dynamic
params
1. Changes to preset params need to be rendered and displayed correctly
2. Changes to preset params need to be sent to the websocket
3. Changes to preset params need to be marked as touched so they won't
be automatically changed later because of dynamic defaults. Dynamic
defaults means any default parameter value can be changed by the
websocket response unless edited by the user, set by autofill or set by
a preset.
We are starting to add app links in many places in the UI, and to make
it consistent, this PR extracts the most core logic into the
modules/apps for reuse.
Related to https://github.com/coder/coder/issues/17311