Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions docs/.vitepress/theme/components/ApiParam.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
<script setup>
import { ref } from 'vue'
import { ref } from "vue";

defineProps({
name: String,
type: String,
required: Boolean
})
required: Boolean,
});

const isExpanded = ref(true)
const isExpanded = ref(true);
</script>

<template>
<div class="api-param">
<div class="param-row" @click="isExpanded = !isExpanded">
<span class="expand-icon" :class="{ expanded: isExpanded }">
<svg width="8" height="8" viewBox="0 0 8 8">
<path d="M2 1L6 4L2 7" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path
d="M2 1L6 4L2 7"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<code class="param-name">{{ name }}</code>
Expand Down
35 changes: 16 additions & 19 deletions docs/.vitepress/theme/components/Card.vue

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/.vitepress/theme/components/CardGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
defineProps({
cols: {
type: [Number, String],
default: 2
}
})
default: 2,
},
});
</script>

<template>
Expand All @@ -13,7 +13,7 @@ defineProps({
:class="{
'card-group-2': cols == 2,
'card-group-3': cols == 3,
'card-group-4': cols == 4
'card-group-4': cols == 4,
}"
>
<slot />
Expand Down
49 changes: 26 additions & 23 deletions docs/.vitepress/theme/components/CodePanel.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
<script setup>
import { ref } from 'vue'
import { ref } from "vue";

const props = defineProps({
title: {
type: String,
default: ''
default: "",
},
languages: {
type: Array,
default: () => ['cURL', 'Python', 'JavaScript']
}
})
default: () => ["cURL", "Python", "JavaScript"],
},
});

const activeTab = ref(props.languages[0])
const copied = ref(false)
const activeTab = ref(props.languages[0]);
const copied = ref(false);

const copyCode = async () => {
const activeContent = document.querySelector('.code-content:not(.is-hidden) pre code')
const activeContent = document.querySelector(".code-content:not(.is-hidden) pre code");
if (activeContent) {
await navigator.clipboard.writeText(activeContent.textContent)
copied.value = true
setTimeout(() => copied.value = false, 2000)
await navigator.clipboard.writeText(activeContent.textContent);
copied.value = true;
setTimeout(() => (copied.value = false), 2000);
}
}
};
</script>

<template>
Expand All @@ -43,22 +43,25 @@ const copyCode = async () => {
</div>
</div>
<button class="copy-btn" @click="copyCode" title="Copy code">
<svg v-if="!copied" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
<svg
v-if="!copied"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
</svg>
<svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2">
<polyline points="20 6 9 17 4 12"/>
<polyline points="20 6 9 17 4 12" />
</svg>
</button>
</div>
<div class="code-body">
<div
v-for="lang in languages"
:key="lang"
class="code-content"
:class="{ 'is-hidden': activeTab !== lang }"
>
<div v-for="lang in languages" :key="lang" class="code-content" :class="{ 'is-hidden': activeTab !== lang }">
<slot :name="lang.toLowerCase().replace(/\s+/g, '')" />
</div>
</div>
Expand Down Expand Up @@ -179,7 +182,7 @@ const copyCode = async () => {
display: none;
}

.code-content :deep(div[class*='language-']) {
.code-content :deep(div[class*="language-"]) {
margin: 0 !important;
border-radius: 0 !important;
border: none !important;
Expand Down
60 changes: 32 additions & 28 deletions docs/.vitepress/theme/components/CookieConsent.vue
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted } from "vue";

const STORAGE_KEY = 'plane-docs-cookie-consent'
const showBanner = ref(false)
const STORAGE_KEY = "plane-docs-cookie-consent";
const showBanner = ref(false);

function getConsent(): string | null {
try {
return localStorage.getItem(STORAGE_KEY)
return localStorage.getItem(STORAGE_KEY);
} catch {
return null
return null;
}
}

function grantConsent() {
if (typeof window === 'undefined') return
if (typeof window === "undefined") return;

// Google Analytics
if (typeof window.gtag === 'function') {
window.gtag('consent', 'update', {
analytics_storage: 'granted'
})
if (typeof window.gtag === "function") {
window.gtag("consent", "update", {
analytics_storage: "granted",
});
}

// PostHog (may not be loaded if VITE_POSTHOG_KEY is unset)
if (window.posthog?.opt_in_capturing) {
window.posthog.opt_in_capturing()
window.posthog.opt_in_capturing();
}
}

function denyConsent() {
if (typeof window === 'undefined') return
if (typeof window === "undefined") return;

// Google Analytics — consent stays denied by default, no update needed

// PostHog (may not be loaded if VITE_POSTHOG_KEY is unset)
if (window.posthog?.opt_out_capturing) {
window.posthog.opt_out_capturing()
window.posthog.opt_out_capturing();
}
}

function accept() {
try {
localStorage.setItem(STORAGE_KEY, 'granted')
localStorage.setItem(STORAGE_KEY, "granted");
} catch {}
grantConsent()
showBanner.value = false
grantConsent();
showBanner.value = false;
}

function decline() {
try {
localStorage.setItem(STORAGE_KEY, 'denied')
localStorage.setItem(STORAGE_KEY, "denied");
} catch {}
denyConsent()
showBanner.value = false
denyConsent();
showBanner.value = false;
}

onMounted(() => {
const consent = getConsent()
if (consent === 'granted') {
grantConsent()
} else if (consent === 'denied') {
denyConsent()
const consent = getConsent();
if (consent === "granted") {
grantConsent();
} else if (consent === "denied") {
denyConsent();
} else {
showBanner.value = true
showBanner.value = true;
}
})
});
</script>

<template>
Expand Down Expand Up @@ -157,10 +157,14 @@ onMounted(() => {

/* Transition */
.consent-enter-active {
transition: opacity 0.3s ease, transform 0.3s ease;
transition:
opacity 0.3s ease,
transform 0.3s ease;
}
.consent-leave-active {
transition: opacity 0.2s ease, transform 0.2s ease;
transition:
opacity 0.2s ease,
transform 0.2s ease;
}
.consent-enter-from {
opacity: 0;
Expand Down
52 changes: 30 additions & 22 deletions docs/.vitepress/theme/components/ResponsePanel.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
<script setup>
import { ref } from 'vue'
import { ref } from "vue";

const props = defineProps({
status: {
type: [String, Number],
default: '200'
}
})
default: "200",
},
});

const copied = ref(false)
const copied = ref(false);

const copyCode = async (event) => {
const panel = event.target.closest('.response-panel')
const codeBlock = panel?.querySelector('pre code')
const panel = event.target.closest(".response-panel");
const codeBlock = panel?.querySelector("pre code");
if (codeBlock) {
await navigator.clipboard.writeText(codeBlock.textContent)
copied.value = true
setTimeout(() => copied.value = false, 2000)
await navigator.clipboard.writeText(codeBlock.textContent);
copied.value = true;
setTimeout(() => (copied.value = false), 2000);
}
}
};

const statusClass = () => {
const code = parseInt(props.status)
if (code >= 200 && code < 300) return 'status-success'
if (code >= 400 && code < 500) return 'status-warning'
if (code >= 500) return 'status-error'
return ''
}
const code = parseInt(props.status);
if (code >= 200 && code < 300) return "status-success";
if (code >= 400 && code < 500) return "status-warning";
if (code >= 500) return "status-error";
return "";
};
</script>

<template>
Expand All @@ -37,12 +37,20 @@ const statusClass = () => {
<span class="status-code" :class="statusClass()">{{ status }}</span>
</div>
<button class="copy-btn" @click="copyCode" title="Copy response">
<svg v-if="!copied" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
<svg
v-if="!copied"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
</svg>
<svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2">
<polyline points="20 6 9 17 4 12"/>
<polyline points="20 6 9 17 4 12" />
</svg>
</button>
</div>
Expand Down Expand Up @@ -135,7 +143,7 @@ const statusClass = () => {
background: #374151;
}

.response-body :deep(div[class*='language-']) {
.response-body :deep(div[class*="language-"]) {
margin: 0 !important;
border-radius: 0 !important;
border: none !important;
Expand Down
Loading
Loading