Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2,524 changes: 2,258 additions & 266 deletions apps/developer-docs/docs/.vitepress/config.mts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<script setup lang="ts">
import { computed } from "vue";
import { useRoute } from "vitepress";

type Version = {
label: string;
value: string;
/** Path prefix identifying a page as belonging to this version. */
prefix: string;
/** Where switching to this version lands. */
entry: string;
};

const VERSIONS: Version[] = [
{
label: "v2",
value: "v2",
prefix: "/api-reference/v2/",
entry: "/api-reference/v2/introduction",
},
{
label: "v1",
value: "v1",
prefix: "/api-reference/v1/",
entry: "/api-reference/v1/introduction",
},
];

const route = useRoute();

/** Strip the .html the dev server and non-cleanUrl hosts append. */
const path = computed(() => route.path.replace(/\.html$/, ""));

const isApiReference = computed(() => path.value.startsWith("/api-reference/"));

/** v2 is the default for any unversioned /api-reference/ path. */
const current = computed(
() => VERSIONS.find((v) => path.value.startsWith(v.prefix))?.value ?? "v2",
);
</script>

<template>
<!--
Plain links, not a <select>: Vue's SSR drops `selected` on options inside a
bound select, so a dropdown would render the wrong version before hydration
and would not work at all without JS. Each link navigates to that version's
entry page, and the sidebar tree swaps via the path-prefix keys in config.mts.
-->
<nav v-if="isApiReference" class="api-version-switcher" aria-label="API version">
<span class="api-version-switcher-label">API version</span>

<div class="api-version-switcher-options">
<a
v-for="version in VERSIONS"
:key="version.value"
class="api-version-switcher-option"
:class="{ 'is-active': version.value === current }"
:href="version.entry"
:aria-current="version.value === current ? 'true' : undefined"
>
{{ version.label }}
<span v-if="version.value === 'v2'" class="api-version-switcher-tag">latest</span>
</a>
</div>
</nav>
</template>

<style scoped>
.api-version-switcher {
display: flex;
flex-direction: column;
gap: 8px;
padding-bottom: 16px;
margin-bottom: 16px;
border-bottom: 1px solid var(--vp-c-divider);
}

.api-version-switcher-label {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--vp-c-text-3);
}

.api-version-switcher-options {
display: flex;
gap: 4px;
padding: 3px;
background-color: var(--vp-c-bg-alt);
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
}

.api-version-switcher-option {
display: inline-flex;
flex: 1;
gap: 5px;
align-items: baseline;
justify-content: center;
padding: 5px 8px;
font-size: 13px;
font-weight: 500;
line-height: 1.4;
color: var(--vp-c-text-2);
text-decoration: none;
border-radius: 6px;
transition:
color 0.2s,
background-color 0.2s;
}

.api-version-switcher-option:hover {
color: var(--vp-c-text-1);
}

.api-version-switcher-option.is-active {
color: var(--vp-c-text-1);
background-color: var(--vp-c-bg);
box-shadow: 0 1px 2px rgb(0 0 0 / 8%);
}

.api-version-switcher-option:focus-visible {
outline: 2px solid var(--vp-c-brand-1);
outline-offset: 1px;
}

.api-version-switcher-tag {
font-size: 10px;
font-weight: 500;
letter-spacing: 0.02em;
color: var(--vp-c-text-3);
}

.api-version-switcher-option.is-active .api-version-switcher-tag {
color: var(--vp-c-brand-1);
}
</style>
36 changes: 31 additions & 5 deletions apps/developer-docs/docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,42 @@
* developers.plane.so theme = shared Plane docs theme (@plane/docs-theme, packages/theme)
* + developer-docs specifics (API reference components/layout).
*/
import { onMounted, watch, nextTick } from "vue";
import { h, onMounted, watch, nextTick } from "vue";
import { useRoute } from "vitepress";
import { createPlaneTheme } from "@plane/docs-theme";
import ApiParam from "./components/ApiParam.vue";
import ApiVersionSwitcher from "./components/ApiVersionSwitcher.vue";
import CodePanel from "./components/CodePanel.vue";
import ResponsePanel from "./components/ResponsePanel.vue";
import "./site.css";

/**
* Prose pages under `/api-reference/` (the introductions and the v2 concept
* guides) keep the normal doc layout; only endpoint pages go wide.
*/
const API_PROSE_PAGES = [
"introduction",
"authentication",
"pagination",
"filtering-and-ordering",
"expanding-relations",
"sparse-fields",
"errors",
"work-item-type-modes",
"migrating-from-v1",
];

/** Toggle `.api-page` on `.VPDoc` for API reference pages (two-column layout, no aside). */
function updateApiPageClass() {
if (typeof document === "undefined") return;
const path = window.location.pathname;
const isApiPage =
path.includes("/api-reference/") &&
!path.endsWith("/introduction") &&
!path.endsWith("/introduction.html");
const slug =
path
.replace(/\.html$/, "")
.replace(/\/$/, "")
.split("/")
.pop() ?? "";
const isApiPage = path.includes("/api-reference/") && !API_PROSE_PAGES.includes(slug);
document.querySelector(".VPDoc")?.classList.toggle("api-page", isApiPage);
}

Expand All @@ -31,6 +51,12 @@ export default createPlaneTheme({
monoIcon: "/logo/favicon-32x32.png",
},
components: { ApiParam, CodePanel, ResponsePanel },
layoutSlots: {
// Renders above the sidebar nav; the component hides itself outside
// /api-reference/. Switching version navigates to that version's entry page,
// which swaps the whole sidebar tree via the path-prefix keys in config.mts.
"sidebar-nav-before": () => h(ApiVersionSwitcher),
},
setup() {
const route = useRoute();
onMounted(() => nextTick(updateApiPageClass));
Expand Down
29 changes: 29 additions & 0 deletions apps/developer-docs/docs/api-reference/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: API Reference
description: Plane REST API reference. Redirects to the current API version, v2.
keywords: plane api, rest api reference, plane api v2
aside: false
outline: false
---

<script setup>
import { onMounted } from "vue";
import { useRouter } from "vitepress";

const TARGET = "/api-reference/v2/introduction";
const router = useRouter();

// Production redirects are handled by vercel.json; this covers `pnpm dev`,
// `pnpm preview`, and any host that serves the static build without them.
onMounted(() => {
router.go(TARGET);
});
</script>

# API Reference

Redirecting to the current API version…

If you are not redirected automatically, continue to the [Plane API v2 reference](/api-reference/v2/introduction).

Looking for the previous version? See the [v1 reference](/api-reference/v1/introduction).
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords: plane, plane api, rest api, api integration, assets, uploads, files

Assets let you upload and manage files used across user profiles and workspaces, including images and other binary resources.

[Learn more about using the Plane API](https://developers.plane.so/api-reference/introduction)
[Learn more about using the Plane API](https://developers.plane.so/api-reference/v1/introduction)

<div class="api-two-column">
<div class="api-left">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Allows you to manage file attachments associated with work items and Intake work

## Upload process

1. Get the [upload credentials](/api-reference/issue-attachments/get-upload-credentials).
2. [Upload the file](/api-reference/issue-attachments/upload-file) to storage.
3. [Complete attachment upload](/api-reference/issue-attachments/complete-upload) to notify server.
1. Get the [upload credentials](/api-reference/v1/issue-attachments/get-upload-credentials).
2. [Upload the file](/api-reference/v1/issue-attachments/upload-file) to storage.
3. [Complete attachment upload](/api-reference/v1/issue-attachments/complete-upload) to notify server.

<div class="api-two-column">
<div class="api-left">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords: plane, plane api, rest api, api integration, project labels, workspace

Project labels define reusable classifications that can be attached to projects across a workspace.

[Learn more about Projects](https://developers.plane.so/api-reference/project/overview)
[Learn more about Projects](https://developers.plane.so/api-reference/v1/project/overview)

<div class="api-two-column">
<div class="api-left">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords: plane, plane api, rest api, api integration, workspace features, featu

Workspace features control which major Plane capabilities are enabled for a workspace.

[Learn more about using the Plane API](https://developers.plane.so/api-reference/introduction)
[Learn more about using the Plane API](https://developers.plane.so/api-reference/v1/introduction)

<div class="api-two-column">
<div class="api-left">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords: plane, plane api, rest api, api integration, workspace invitations, me

Workspace invitations let admins invite users to join a workspace with specific access settings.

[Learn more about Members](https://developers.plane.so/api-reference/members/overview)
[Learn more about Members](https://developers.plane.so/api-reference/v1/members/overview)

<div class="api-two-column">
<div class="api-left">
Expand Down
Loading
Loading