mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
feat: add open in coder docs, fix missing templates (#4124)
* docs: add open in coder
This adds new documentation for the "Open in Coder" button that admins
can use to get their developers up and running faster.
* fix: display error if template not found
Previously, we weren't handling a case where we tried to get a template
that returned a 404 from the backend.
Now we handle that case in our state machine and display the error
message from the API on the frontend.
* feat: support template query param in index
This adds support to navigate directly to a template from the index by
using the `?template=<name>` query param.
* Revert "feat: support template query param in index"
This reverts commit bad7ffb677
.
We decided to use the `/template/path` route instead.
* fixup!: docs: add open in coder
* docs: add open in coder to dogfood readme
* Update docs/admin/open-in-coder.md
Co-authored-by: Ben Potter <ben@coder.com>
* Update docs/admin/open-in-coder.md
Co-authored-by: Ben Potter <ben@coder.com>
* Update docs/admin/open-in-coder.md
Co-authored-by: Ben Potter <ben@coder.com>
This commit is contained in:
27
docs/admin/open-in-coder.md
Normal file
27
docs/admin/open-in-coder.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Open in Coder Button
|
||||
|
||||
Add a Markdown button to your project's `README.md` to get your developers up and running with Coder with a few clicks.
|
||||
|
||||
A basic example looks like this:
|
||||
|
||||
```markdown
|
||||
[](https://<deployment-url>/templates/<template-name>)
|
||||
```
|
||||
|
||||
which renders like this:
|
||||
|
||||

|
||||
|
||||
You can customize this to take developers directly to your team's template. Read on to learn more.
|
||||
|
||||
### Customization
|
||||
|
||||
The underlying link for this button consists of the following pieces:
|
||||
- <deployment-url>: where your Coder deployment lives i.e. https://dev.coder.com
|
||||
- <template-name>: name of template i.e. coder
|
||||
|
||||
### template name
|
||||
|
||||
A template to redirect your developers to after they authenticate on your deployment.
|
||||
|
||||
Example: https://dev.coder.com/templates/coder
|
@ -188,6 +188,11 @@
|
||||
"title": "Enterprise",
|
||||
"description": "Learn how to enable Enterprise features.",
|
||||
"path": "./admin/enterprise.md"
|
||||
},
|
||||
{
|
||||
"title": "Open in Coder Button",
|
||||
"description": "Learn how to create an 'Open in Coder' button.",
|
||||
"path": "./admin/open-in-coder.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
# dogfood template
|
||||
|
||||
[](https://dev.coder.com/templates/coder)
|
||||
|
||||
Ammar is this template's admin.
|
||||
|
||||
## Personalization
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import { useMachine, useSelector } from "@xstate/react"
|
||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog"
|
||||
import { ErrorSummary } from "components/ErrorSummary/ErrorSummary"
|
||||
import { Margins } from "components/Margins/Margins"
|
||||
import { FC, useContext } from "react"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import { Navigate, useParams } from "react-router-dom"
|
||||
@ -22,6 +25,7 @@ const useTemplateName = () => {
|
||||
}
|
||||
|
||||
export const TemplatePage: FC<React.PropsWithChildren<unknown>> = () => {
|
||||
const styles = useStyles()
|
||||
const organizationId = useOrganizationId()
|
||||
const templateName = useTemplateName()
|
||||
const [templateState, templateSend] = useMachine(templateMachine, {
|
||||
@ -38,6 +42,7 @@ export const TemplatePage: FC<React.PropsWithChildren<unknown>> = () => {
|
||||
templateVersions,
|
||||
deleteTemplateError,
|
||||
templateDAUs,
|
||||
getTemplateError,
|
||||
} = templateState.context
|
||||
const xServices = useContext(XServiceContext)
|
||||
const permissions = useSelector(xServices.authXService, selectPermissions)
|
||||
@ -48,6 +53,16 @@ export const TemplatePage: FC<React.PropsWithChildren<unknown>> = () => {
|
||||
templateSend("DELETE")
|
||||
}
|
||||
|
||||
if (templateState.matches("error") && Boolean(getTemplateError)) {
|
||||
return (
|
||||
<Margins>
|
||||
<div className={styles.errorBox}>
|
||||
<ErrorSummary error={getTemplateError} />
|
||||
</div>
|
||||
</Margins>
|
||||
)
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />
|
||||
}
|
||||
@ -88,4 +103,10 @@ export const TemplatePage: FC<React.PropsWithChildren<unknown>> = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
errorBox: {
|
||||
padding: theme.spacing(3),
|
||||
},
|
||||
}))
|
||||
|
||||
export default TemplatePage
|
||||
|
@ -25,6 +25,7 @@ interface TemplateContext {
|
||||
templateVersions?: TemplateVersion[]
|
||||
templateDAUs: TemplateDAUsResponse
|
||||
deleteTemplateError?: Error | unknown
|
||||
getTemplateError?: Error | unknown
|
||||
}
|
||||
|
||||
type TemplateEvent = { type: "DELETE" } | { type: "CONFIRM_DELETE" } | { type: "CANCEL_DELETE" }
|
||||
@ -71,6 +72,12 @@ export const templateMachine =
|
||||
target: "initialInfo",
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: "assignGetTemplateError",
|
||||
target: "error",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
initialInfo: {
|
||||
@ -211,6 +218,9 @@ export const templateMachine =
|
||||
deleted: {
|
||||
type: "final",
|
||||
},
|
||||
error: {
|
||||
type: "final",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -257,6 +267,9 @@ export const templateMachine =
|
||||
assignActiveTemplateVersion: assign({
|
||||
activeTemplateVersion: (_, event) => event.data,
|
||||
}),
|
||||
assignGetTemplateError: assign({
|
||||
getTemplateError: (_, event) => event.data,
|
||||
}),
|
||||
assignTemplateResources: assign({
|
||||
templateResources: (_, event) => event.data,
|
||||
}),
|
||||
|
Reference in New Issue
Block a user