mirror of
https://github.com/pterodactyl/documentation.git
synced 2025-12-11 14:00:27 -06:00
Merge branch 'master' of https://github.com/pterodactyl/documentation
This commit is contained in:
commit
11461e29a0
@ -2,7 +2,23 @@ module.exports = {
|
|||||||
base: '/',
|
base: '/',
|
||||||
title: 'Pterodactyl',
|
title: 'Pterodactyl',
|
||||||
description: 'The open-source server management solution.',
|
description: 'The open-source server management solution.',
|
||||||
ga: 'UA-87324178-1',
|
plugins: [
|
||||||
|
['@vuepress/google-analytics', {
|
||||||
|
ga: 'UA-12345678-9'
|
||||||
|
},],
|
||||||
|
['@vuepress/search', {
|
||||||
|
searchMaxSuggestions: 10
|
||||||
|
}],
|
||||||
|
['vuepress-plugin-container', {
|
||||||
|
type: 'warning',
|
||||||
|
}],
|
||||||
|
['vuepress-plugin-container', {
|
||||||
|
type: 'tip',
|
||||||
|
}],
|
||||||
|
['vuepress-plugin-container', {
|
||||||
|
type: 'danger',
|
||||||
|
}],
|
||||||
|
],
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
serve: {
|
serve: {
|
||||||
hot: {
|
hot: {
|
||||||
@ -111,24 +127,63 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
title: 'Panel',
|
title: 'Panel',
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
|
path: '/panel/',
|
||||||
|
currentVersion: '0.7',
|
||||||
|
versions: [
|
||||||
|
{
|
||||||
|
name: '0.7',
|
||||||
|
status: 'stable',
|
||||||
children: [
|
children: [
|
||||||
'/panel/getting_started',
|
'/getting_started',
|
||||||
'/panel/webserver_configuration',
|
'/webserver_configuration',
|
||||||
'/panel/upgrading',
|
'/upgrading',
|
||||||
'/panel/configuration',
|
'/configuration',
|
||||||
'/panel/troubleshooting',
|
'/troubleshooting',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '1.0',
|
||||||
|
status: 'beta',
|
||||||
|
children: [
|
||||||
|
'/getting_started',
|
||||||
|
'/webserver_configuration'
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Daemon',
|
title: 'Daemon',
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
|
path: '/daemon/',
|
||||||
|
currentVersion: '0.6',
|
||||||
|
versions: [
|
||||||
|
{
|
||||||
|
name: '0.6',
|
||||||
children: [
|
children: [
|
||||||
'/daemon/installing',
|
'/installing',
|
||||||
'/daemon/upgrading',
|
'/upgrading',
|
||||||
'/daemon/configuration',
|
'/configuration',
|
||||||
'/daemon/kernel_modifications',
|
'/kernel_modifications',
|
||||||
'/daemon/debian_8_docker',
|
'/debian_8_docker',
|
||||||
'/daemon/standalone_sftp',
|
'/standalone_sftp',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Wings',
|
||||||
|
collapsable: false,
|
||||||
|
path: '/wings/',
|
||||||
|
currentVersion: '',
|
||||||
|
versions: [
|
||||||
|
{
|
||||||
|
name: '1.0',
|
||||||
|
status: 'beta',
|
||||||
|
children: [
|
||||||
|
'/installing',
|
||||||
|
'/upgrading',
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
41
.vuepress/enhanceApp.js
Normal file
41
.vuepress/enhanceApp.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
export default ({
|
||||||
|
Vue, // the version of Vue being used in the VuePress app
|
||||||
|
options, // the options for the root Vue instance
|
||||||
|
router, // the router instance for the app
|
||||||
|
siteData, // site metadata
|
||||||
|
isServer // is this enhancement applied in server-rendering or client
|
||||||
|
}) => {
|
||||||
|
findVersionedPaths(siteData.themeConfig.sidebar).forEach(vp => {
|
||||||
|
router.addRoutes(
|
||||||
|
router.options.routes.map(route => {
|
||||||
|
if (route.path.startsWith(vp.path + vp.currentVersion)) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
path: route.path.replace(vp.currentVersion, "current"),
|
||||||
|
redirect: route.path
|
||||||
|
}, {
|
||||||
|
path: route.path.replace(vp.currentVersion + "/", ""),
|
||||||
|
redirect: route.path
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}).filter(x => x).flat()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function findVersionedPaths(paths) {
|
||||||
|
return Object.entries(paths).map(([path, children]) => {
|
||||||
|
return children
|
||||||
|
.filter(child => Array.isArray(child.versions))
|
||||||
|
.map(child => ({ ...child, path: pathJoin(path, child.path) }))
|
||||||
|
}).flat()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/29855282/4430124
|
||||||
|
function pathJoin(...parts) {
|
||||||
|
var separator = '/';
|
||||||
|
var replace = new RegExp(separator + '{1,}', 'g');
|
||||||
|
return parts.join(separator).replace(replace, separator);
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="container z-10">
|
<div class="container z-10">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<div>
|
<div>
|
||||||
<img class="max-w-xl w-full" src="https://cdn.pterodactyl.io/logos/new/pterodactyl_logo_transparent.png" alt="Pterodactyl">
|
<img class="max-w-xl w-full inline-block" src="https://cdn.pterodactyl.io/logos/new/pterodactyl_logo_transparent.png" alt="Pterodactyl">
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<a class="btn hidden md:inline-block" href="https://demo.pterodactyl.io" target="_blank" rel="nofollow noopener">Demo</a>
|
<a class="btn hidden md:inline-block" href="https://demo.pterodactyl.io" target="_blank" rel="nofollow noopener">Demo</a>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
while exposing a beautiful and intuitive UI to administrators and users. Stop wasting time fiddling
|
while exposing a beautiful and intuitive UI to administrators and users. Stop wasting time fiddling
|
||||||
with other systems — make game servers a first class citizen on your platform.
|
with other systems — make game servers a first class citizen on your platform.
|
||||||
</h3>
|
</h3>
|
||||||
<img class="max-w-lg w-full m-4" :src="$withBase('frontpage/mockup-macbook-grey.png')"></div>
|
<img class="max-w-lg w-full m-4 inline-block" :src="$withBase('frontpage/mockup-macbook-grey.png')"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section bg-blue text-grey-lightest">
|
<div class="section bg-blue text-grey-lightest">
|
||||||
<div class="container text-center">
|
<div class="container text-center">
|
||||||
@ -116,7 +116,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">MIT Licensed | Copyright © 2015 - 2019 Dane Everitt & Contributors.</div>
|
<div class="footer">MIT Licensed | Copyright © 2015 - 2020 Dane Everitt & Contributors.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="theme-container"
|
<div
|
||||||
|
class="theme-container"
|
||||||
:class="pageClasses"
|
:class="pageClasses"
|
||||||
@touchstart="onTouchStart"
|
@touchstart="onTouchStart"
|
||||||
@touchend="onTouchEnd">
|
@touchend="onTouchEnd"
|
||||||
|
>
|
||||||
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar" />
|
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar" />
|
||||||
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
||||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
||||||
@ -21,13 +23,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from "vue";
|
||||||
import nprogress from 'nprogress';
|
import nprogress from "nprogress";
|
||||||
import Home from './Home.vue';
|
import Home from "./Home.vue";
|
||||||
import Navbar from './Navbar.vue';
|
import Navbar from "./Navbar.vue";
|
||||||
import Page from './Page.vue';
|
import Page from "./Page.vue";
|
||||||
import Sidebar from './Sidebar.vue';
|
import Sidebar from "./Sidebar.vue";
|
||||||
import { resolveSidebarItems } from './util';
|
import { resolveSidebarItems } from "./util";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Home, Page, Sidebar, Navbar },
|
components: { Home, Page, Sidebar, Navbar },
|
||||||
@ -41,9 +43,7 @@
|
|||||||
shouldShowNavbar() {
|
shouldShowNavbar() {
|
||||||
const { themeConfig } = this.$site;
|
const { themeConfig } = this.$site;
|
||||||
const { frontmatter } = this.$page;
|
const { frontmatter } = this.$page;
|
||||||
if (
|
if (frontmatter.navbar === false || themeConfig.navbar === false) {
|
||||||
frontmatter.navbar === false ||
|
|
||||||
themeConfig.navbar === false) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@ -75,9 +75,9 @@
|
|||||||
const userPageClass = this.$page.frontmatter.pageClass;
|
const userPageClass = this.$page.frontmatter.pageClass;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'no-navbar': ! this.shouldShowNavbar,
|
"no-navbar": !this.shouldShowNavbar,
|
||||||
'sidebar-open': this.isSidebarOpen,
|
"sidebar-open": this.isSidebarOpen,
|
||||||
'no-sidebar': ! this.shouldShowSidebar
|
"no-sidebar": !this.shouldShowSidebar
|
||||||
},
|
},
|
||||||
userPageClass
|
userPageClass
|
||||||
];
|
];
|
||||||
@ -85,7 +85,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('scroll', this.onScroll);
|
window.addEventListener("scroll", this.onScroll);
|
||||||
|
|
||||||
// configure progress bar
|
// configure progress bar
|
||||||
nprogress.configure({ showSpinner: false });
|
nprogress.configure({ showSpinner: false });
|
||||||
@ -105,7 +105,7 @@
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
toggleSidebar(to) {
|
toggleSidebar(to) {
|
||||||
this.isSidebarOpen = typeof to === 'boolean' ? to : ! this.isSidebarOpen;
|
this.isSidebarOpen = typeof to === "boolean" ? to : !this.isSidebarOpen;
|
||||||
},
|
},
|
||||||
// side swipe
|
// side swipe
|
||||||
onTouchStart(e) {
|
onTouchStart(e) {
|
||||||
@ -130,4 +130,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="prismjs/themes/prism-tomorrow.css"></style>
|
<style src="prismjs/themes/prism-tomorrow.css"></style>
|
||||||
<style src="./styles/main.css" lang="postcss"></style>
|
<style lang="postcss">
|
||||||
|
@import "./styles/main.css";
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="nav">
|
<header class="nav">
|
||||||
<SidebarButton class="block md:hidden flex-no-shrink" @toggle-sidebar="$emit('toggle-sidebar')"/>
|
<SidebarButton
|
||||||
|
class="block md:hidden flex-no-shrink"
|
||||||
|
@toggle-sidebar="$emit('toggle-sidebar')"
|
||||||
|
/>
|
||||||
<div class="logo-container">
|
<div class="logo-container">
|
||||||
<router-link :to="$localePath" class="home-link">
|
<router-link :to="$localePath" class="home-link">
|
||||||
<img class="logo"
|
<img class="logo" v-if="$site.themeConfig.logo" :src="$withBase($site.themeConfig.logo)" />
|
||||||
v-if="$site.themeConfig.logo"
|
<span
|
||||||
:src="$withBase($site.themeConfig.logo)">
|
class="site-name hidden md:inline"
|
||||||
<span class="site-name hidden md:inline"
|
|
||||||
v-if="$siteTitle"
|
v-if="$siteTitle"
|
||||||
:class="{ 'can-hide': $site.themeConfig.logo }">
|
:class="{ 'can-hide': $site.themeConfig.logo }"
|
||||||
{{ $siteTitle }}
|
>{{ $siteTitle }}</span>
|
||||||
</span>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
@ -23,20 +24,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SidebarButton from './SidebarButton.vue';
|
import SidebarButton from "./SidebarButton.vue";
|
||||||
import AlgoliaSearchBox from '@AlgoliaSearchBox';
|
import SearchBox from "./SearchBox.vue";
|
||||||
import SearchBox from './SearchBox.vue';
|
import NavLinks from "./NavLinks.vue";
|
||||||
import NavLinks from './NavLinks.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
components: { SidebarButton, NavLinks, SearchBox },
|
||||||
computed: {
|
computed: {}
|
||||||
algolia() {
|
|
||||||
return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {};
|
|
||||||
},
|
|
||||||
isAlgoliaSearch() {
|
|
||||||
return this.algolia && this.algolia.apiKey && this.algolia.indexName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<slot name="top" />
|
<slot name="top" />
|
||||||
<Content :custom="false"/>
|
<Content class="content" :custom="false" />
|
||||||
<div class="page-edit">
|
<div class="page-edit">
|
||||||
<div class="edit-link" v-if="editLink">
|
<div class="edit-link" v-if="editLink">
|
||||||
<a :href="editLink" target="_blank" rel="noopener noreferrer">{{ editLinkText }}</a>
|
<a :href="editLink" target="_blank" rel="noopener noreferrer">{{ editLinkText }}</a>
|
||||||
@ -16,7 +16,8 @@
|
|||||||
<p class="inner"></p>
|
<p class="inner"></p>
|
||||||
<div class="prev">
|
<div class="prev">
|
||||||
<span v-if="prev">
|
<span v-if="prev">
|
||||||
← <router-link v-if="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
←
|
||||||
|
<router-link v-if="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="next">
|
<div class="next">
|
||||||
@ -30,10 +31,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { resolvePage, normalize, outboundRE, endingSlashRE } from './util';
|
import { resolvePage, normalize, outboundRE, endingSlashRE } from "./util";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['sidebarItems'],
|
props: ["sidebarItems"],
|
||||||
computed: {
|
computed: {
|
||||||
lastUpdated() {
|
lastUpdated() {
|
||||||
if (this.$page.lastUpdated) {
|
if (this.$page.lastUpdated) {
|
||||||
@ -41,13 +42,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
lastUpdatedText() {
|
lastUpdatedText() {
|
||||||
if (typeof this.$themeLocaleConfig.lastUpdated === 'string') {
|
if (typeof this.$themeLocaleConfig.lastUpdated === "string") {
|
||||||
return this.$themeLocaleConfig.lastUpdated;
|
return this.$themeLocaleConfig.lastUpdated;
|
||||||
}
|
}
|
||||||
if (typeof this.$site.themeConfig.lastUpdated === 'string') {
|
if (typeof this.$site.themeConfig.lastUpdated === "string") {
|
||||||
return this.$site.themeConfig.lastUpdated;
|
return this.$site.themeConfig.lastUpdated;
|
||||||
}
|
}
|
||||||
return 'Last Updated';
|
return "Last Updated";
|
||||||
},
|
},
|
||||||
prev() {
|
prev() {
|
||||||
const prev = this.$page.frontmatter.prev;
|
const prev = this.$page.frontmatter.prev;
|
||||||
@ -76,16 +77,16 @@
|
|||||||
const {
|
const {
|
||||||
repo,
|
repo,
|
||||||
editLinks,
|
editLinks,
|
||||||
docsDir = '',
|
docsDir = "",
|
||||||
docsBranch = 'master',
|
docsBranch = "master",
|
||||||
docsRepo = repo
|
docsRepo = repo
|
||||||
} = this.$site.themeConfig;
|
} = this.$site.themeConfig;
|
||||||
|
|
||||||
let path = normalize(this.$page.path);
|
let path = normalize(this.$page.path);
|
||||||
if (endingSlashRE.test(path)) {
|
if (endingSlashRE.test(path)) {
|
||||||
path += 'README.md';
|
path += "README.md";
|
||||||
} else {
|
} else {
|
||||||
path += '.md';
|
path += ".md";
|
||||||
}
|
}
|
||||||
if (docsRepo && editLinks) {
|
if (docsRepo && editLinks) {
|
||||||
return this.createEditLink(repo, docsRepo, docsDir, docsBranch, path);
|
return this.createEditLink(repo, docsRepo, docsDir, docsBranch, path);
|
||||||
@ -103,13 +104,11 @@
|
|||||||
createEditLink(repo, docsRepo, docsDir, docsBranch, path) {
|
createEditLink(repo, docsRepo, docsDir, docsBranch, path) {
|
||||||
const bitbucket = /bitbucket.org/;
|
const bitbucket = /bitbucket.org/;
|
||||||
if (bitbucket.test(repo)) {
|
if (bitbucket.test(repo)) {
|
||||||
const base = outboundRE.test(docsRepo)
|
const base = outboundRE.test(docsRepo) ? docsRepo : repo;
|
||||||
? docsRepo
|
|
||||||
: repo;
|
|
||||||
return (
|
return (
|
||||||
base.replace(endingSlashRE, '') +
|
base.replace(endingSlashRE, "") +
|
||||||
`/${docsBranch}` +
|
`/${docsBranch}` +
|
||||||
(docsDir ? '/' + docsDir.replace(endingSlashRE, '') : '') +
|
(docsDir ? "/" + docsDir.replace(endingSlashRE, "") : "") +
|
||||||
path +
|
path +
|
||||||
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
|
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
|
||||||
);
|
);
|
||||||
@ -120,9 +119,9 @@
|
|||||||
: `https://github.com/${docsRepo}`;
|
: `https://github.com/${docsRepo}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
base.replace(endingSlashRE, '') +
|
base.replace(endingSlashRE, "") +
|
||||||
`/edit/${docsBranch}` +
|
`/edit/${docsBranch}` +
|
||||||
(docsDir ? '/' + docsDir.replace(endingSlashRE, '') : '') +
|
(docsDir ? "/" + docsDir.replace(endingSlashRE, "") : "") +
|
||||||
path
|
path
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -140,15 +139,15 @@
|
|||||||
function find(page, items, offset) {
|
function find(page, items, offset) {
|
||||||
const res = [];
|
const res = [];
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (item.type === 'group') {
|
if (item.type === "group") {
|
||||||
res.push(...item.children || []);
|
res.push(...(item.children || []));
|
||||||
} else {
|
} else {
|
||||||
res.push(item);
|
res.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
const cur = res[i];
|
const cur = res[i];
|
||||||
if (cur.type === 'page' && cur.path === page.path) {
|
if (cur.type === "page" && cur.path === page.path) {
|
||||||
return res[i + offset];
|
return res[i + offset];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,14 +11,18 @@
|
|||||||
@blur="focused = false"
|
@blur="focused = false"
|
||||||
@keyup.enter="go(focusIndex)"
|
@keyup.enter="go(focusIndex)"
|
||||||
@keyup.up="onUp"
|
@keyup.up="onUp"
|
||||||
@keyup.down="onDown">
|
@keyup.down="onDown"
|
||||||
|
/>
|
||||||
<div class="suggestion-container" v-if="showSuggestions" @mouseleave="unfocus">
|
<div class="suggestion-container" v-if="showSuggestions" @mouseleave="unfocus">
|
||||||
<div class="suggestion-padding"></div>
|
<div class="suggestion-padding"></div>
|
||||||
<ul class="suggestions" :class="{ 'align-right': alignRight }">
|
<ul class="suggestions" :class="{ 'align-right': alignRight }">
|
||||||
<li class="suggestion" v-for="(s, i) in suggestions"
|
<li
|
||||||
|
class="suggestion"
|
||||||
|
v-for="(s, i) in suggestions"
|
||||||
:class="{ focused: i === focusIndex }"
|
:class="{ focused: i === focusIndex }"
|
||||||
@mousedown="go(i)"
|
@mousedown="go(i)"
|
||||||
@mouseenter="focus(i)">
|
@mouseenter="focus(i)"
|
||||||
|
>
|
||||||
<a :href="s.path" @click.prevent>
|
<a :href="s.path" @click.prevent>
|
||||||
<span class="page-title">{{ s.title || s.path }}</span>
|
<span class="page-title">{{ s.title || s.path }}</span>
|
||||||
<span v-if="s.header" class="header">> {{ s.header.title }}</span>
|
<span v-if="s.header" class="header">> {{ s.header.title }}</span>
|
||||||
@ -33,18 +37,14 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
query: '',
|
query: "",
|
||||||
focused: false,
|
focused: false,
|
||||||
focusIndex: 0
|
focusIndex: 0
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showSuggestions() {
|
showSuggestions() {
|
||||||
return (
|
return this.focused && this.suggestions && this.suggestions.length;
|
||||||
this.focused &&
|
|
||||||
this.suggestions &&
|
|
||||||
this.suggestions.length
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
suggestions() {
|
suggestions() {
|
||||||
const query = this.query.trim().toLowerCase();
|
const query = this.query.trim().toLowerCase();
|
||||||
@ -55,10 +55,8 @@
|
|||||||
const { pages, themeConfig } = this.$site;
|
const { pages, themeConfig } = this.$site;
|
||||||
const max = themeConfig.searchMaxSuggestions || 5;
|
const max = themeConfig.searchMaxSuggestions || 5;
|
||||||
const localePath = this.$localePath;
|
const localePath = this.$localePath;
|
||||||
const matches = item => (
|
const matches = item =>
|
||||||
item.title &&
|
item.title && item.title.toLowerCase().indexOf(query) > -1;
|
||||||
item.title.toLowerCase().indexOf(query) > - 1
|
|
||||||
);
|
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i = 0; i < pages.length; i++) {
|
for (let i = 0; i < pages.length; i++) {
|
||||||
if (res.length >= max) break;
|
if (res.length >= max) break;
|
||||||
@ -74,10 +72,12 @@
|
|||||||
if (res.length >= max) break;
|
if (res.length >= max) break;
|
||||||
const h = p.headers[j];
|
const h = p.headers[j];
|
||||||
if (matches(h)) {
|
if (matches(h)) {
|
||||||
res.push(Object.assign({}, p, {
|
res.push(
|
||||||
path: p.path + '#' + h.slug,
|
Object.assign({}, p, {
|
||||||
|
path: p.path + "#" + h.slug,
|
||||||
header: h
|
header: h
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,11 +94,11 @@
|
|||||||
methods: {
|
methods: {
|
||||||
getPageLocalePath(page) {
|
getPageLocalePath(page) {
|
||||||
for (const localePath in this.$site.locales || {}) {
|
for (const localePath in this.$site.locales || {}) {
|
||||||
if (localePath !== '/' && page.path.indexOf(localePath) === 0) {
|
if (localePath !== "/" && page.path.indexOf(localePath) === 0) {
|
||||||
return localePath;
|
return localePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '/';
|
return "/";
|
||||||
},
|
},
|
||||||
onUp() {
|
onUp() {
|
||||||
if (this.showSuggestions) {
|
if (this.showSuggestions) {
|
||||||
@ -123,7 +123,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push(this.suggestions[i].path);
|
this.$router.push(this.suggestions[i].path);
|
||||||
this.query = '';
|
this.query = "";
|
||||||
this.focusIndex = 0;
|
this.focusIndex = 0;
|
||||||
},
|
},
|
||||||
focus(i) {
|
focus(i) {
|
||||||
|
|||||||
@ -3,13 +3,15 @@
|
|||||||
<NavLinks class="block md:hidden" />
|
<NavLinks class="block md:hidden" />
|
||||||
<slot name="top" />
|
<slot name="top" />
|
||||||
<ul class="sidebar-links" v-if="items.length">
|
<ul class="sidebar-links" v-if="items.length">
|
||||||
<li v-for="(item, i) in items" :key="i">
|
<li v-for="(item, i) in items" :key="item.path">
|
||||||
<SidebarGroup v-if="item.type === 'group'"
|
<SidebarGroup
|
||||||
|
v-if="item.type === 'group'"
|
||||||
:item="item"
|
:item="item"
|
||||||
:first="i === 0"
|
:first="i === 0"
|
||||||
:open="i === openGroupIndex"
|
:open="i === openGroupIndex"
|
||||||
:collapsable="item.collapsable"
|
:collapsable="item.collapsable"
|
||||||
@toggle="toggleGroup(i)"/>
|
@toggle="toggleGroup(i)"
|
||||||
|
/>
|
||||||
<SidebarLink v-else :item="item" />
|
<SidebarLink v-else :item="item" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -18,14 +20,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SidebarGroup from './SidebarGroup.vue';
|
import SidebarGroup from "./SidebarGroup.vue";
|
||||||
import SidebarLink from './SidebarLink.vue';
|
import SidebarLink from "./SidebarLink.vue";
|
||||||
import NavLinks from './NavLinks.vue';
|
import NavLinks from "./NavLinks.vue";
|
||||||
import { isActive } from './util';
|
import { isActive } from "./util";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SidebarGroup, SidebarLink, NavLinks },
|
components: { SidebarGroup, SidebarLink, NavLinks },
|
||||||
props: ['items'],
|
props: ["items"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
openGroupIndex: 0
|
openGroupIndex: 0
|
||||||
@ -35,16 +37,13 @@
|
|||||||
this.refreshIndex();
|
this.refreshIndex();
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route'() {
|
$route() {
|
||||||
this.refreshIndex();
|
this.refreshIndex();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refreshIndex() {
|
refreshIndex() {
|
||||||
const index = resolveOpenGroupIndex(
|
const index = resolveOpenGroupIndex(this.$route, this.items);
|
||||||
this.$route,
|
|
||||||
this.items
|
|
||||||
);
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.openGroupIndex = index;
|
this.openGroupIndex = index;
|
||||||
}
|
}
|
||||||
@ -61,7 +60,10 @@
|
|||||||
function resolveOpenGroupIndex(route, items) {
|
function resolveOpenGroupIndex(route, items) {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
|
if (
|
||||||
|
item.type === "group" &&
|
||||||
|
item.children.some(c => isActive(route, c.path))
|
||||||
|
) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,13 +2,17 @@
|
|||||||
<div class="sidebar-group" :class="{ first, collapsable }">
|
<div class="sidebar-group" :class="{ first, collapsable }">
|
||||||
<p class="sidebar-heading" :class="{ open }" @click="$emit('toggle')">
|
<p class="sidebar-heading" :class="{ open }" @click="$emit('toggle')">
|
||||||
<span>{{ item.title }}</span>
|
<span>{{ item.title }}</span>
|
||||||
<span class="arrow"
|
<span class="arrow" v-if="collapsable" :class="open ? 'down' : 'right'"></span>
|
||||||
v-if="collapsable"
|
<VersionSelect
|
||||||
:class="open ? 'down' : 'right'"></span>
|
class="float-right"
|
||||||
|
v-if="isVersioned"
|
||||||
|
:versions="item.versions"
|
||||||
|
v-model="versionSelect"
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
<DropdownTransition>
|
<DropdownTransition>
|
||||||
<ul class="sidebar-group-items" ref="items" v-if="open || !collapsable">
|
<ul class="sidebar-group-items" ref="items" v-if="open || !collapsable">
|
||||||
<li v-for="child in item.children">
|
<li v-for="child in children">
|
||||||
<SidebarLink :item="child" />
|
<SidebarLink :item="child" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -17,12 +21,70 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SidebarLink from './SidebarLink.vue';
|
import SidebarLink from "./SidebarLink.vue";
|
||||||
import DropdownTransition from './DropdownTransition.vue';
|
import DropdownTransition from "./DropdownTransition.vue";
|
||||||
|
import VersionSelect from "./VersionSelect.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SidebarGroup',
|
name: "SidebarGroup",
|
||||||
props: ['item', 'first', 'open', 'collapsable'],
|
props: ["item", "first", "open", "collapsable"],
|
||||||
components: { SidebarLink, DropdownTransition }
|
components: { SidebarLink, DropdownTransition, VersionSelect },
|
||||||
|
data: function() {
|
||||||
|
let isVersioned = this.item.versions.length > 0;
|
||||||
|
|
||||||
|
let versionSelect = "";
|
||||||
|
if (isVersioned) {
|
||||||
|
versionSelect = this.item.currentVersion || this.item.versions[0].name;
|
||||||
|
if (this.$router.currentRoute.path.startsWith(this.item.path)) {
|
||||||
|
const pathVersion = this.$router.currentRoute.path.split("/")[2];
|
||||||
|
versionSelect = ~this.item.versions
|
||||||
|
.map(v => v.name)
|
||||||
|
.indexOf(pathVersion)
|
||||||
|
? pathVersion
|
||||||
|
: this.item.currentVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
isVersioned,
|
||||||
|
versionSelect
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
versionSelect(newVersion, oldVersion) {
|
||||||
|
if (
|
||||||
|
oldVersion !== newVersion &&
|
||||||
|
this.$router.currentRoute.path.startsWith(this.item.path) &&
|
||||||
|
this.selectedVersion.children.length > 0
|
||||||
|
) {
|
||||||
|
// Try to navigate to the same page in the new version, or default to the first one
|
||||||
|
let path = this.$router.currentRoute.path;
|
||||||
|
path = path.substr(path.indexOf(oldVersion) + oldVersion.length);
|
||||||
|
this.$router.push(
|
||||||
|
this.selectedVersion.children.find(c => {
|
||||||
|
return c.path.endsWith(path);
|
||||||
|
}) || this.selectedVersion.children[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$route(to, from) {
|
||||||
|
if (this.isVersioned && to.path.startsWith(this.item.path)) {
|
||||||
|
const pathVersion = to.path.split("/")[2];
|
||||||
|
if (~this.item.versions.map(v => v.name).indexOf(pathVersion)) {
|
||||||
|
this.versionSelect = pathVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
selectedVersion: function() {
|
||||||
|
return this.item.versions.find(v => v.name === this.versionSelect);
|
||||||
|
},
|
||||||
|
children: function() {
|
||||||
|
return this.isVersioned
|
||||||
|
? this.selectedVersion.children
|
||||||
|
: this.item.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
63
.vuepress/theme/VersionSelect.vue
Normal file
63
.vuepress/theme/VersionSelect.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div class="version-select custom-select" :tabindex="tabindex" @blur="open = false">
|
||||||
|
<div class="selected" :class="{open: open}" @click="open = !open">
|
||||||
|
<VersionSelectItem :version="selected" />
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
<div class="items" :class="{hidden: !open}">
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
v-for="version in versions"
|
||||||
|
:key="version.name"
|
||||||
|
@click="selected=version; open=false; $emit('input', version.name)"
|
||||||
|
>
|
||||||
|
<VersionSelectItem :version="version" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import VersionSelectItem from "./VersionSelectItem.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "VersionSelect",
|
||||||
|
components: { VersionSelectItem },
|
||||||
|
props: {
|
||||||
|
versions: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
tabindex: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
selected:
|
||||||
|
this.versions.find(v => v.name === this.value) ||
|
||||||
|
(this.versions.length > 0 ? this.versions[0] : null),
|
||||||
|
open: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(newValue, oldValue) {
|
||||||
|
if (newValue !== oldValue) {
|
||||||
|
let version = this.versions.find(v => v.name === this.value);
|
||||||
|
if (version) {
|
||||||
|
this.selected = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$emit("input", this.selected.name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
32
.vuepress/theme/VersionSelectItem.vue
Normal file
32
.vuepress/theme/VersionSelectItem.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<div class="inline-block">
|
||||||
|
{{ version.name }}
|
||||||
|
<span class="rounded-full ml-2" :class="classes">{{version.status}}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import VersionSelectItem from "./VersionSelectItem.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "VersionSelectItem",
|
||||||
|
props: {
|
||||||
|
version: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
classes() {
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
deprecated: ["text-orange"],
|
||||||
|
current: ["text-green-dark"],
|
||||||
|
stable: ["text-green-dark"],
|
||||||
|
beta: ["text-blue"]
|
||||||
|
}[this.version.status] || ["text-grey"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
.content {
|
.content {
|
||||||
code {
|
code {
|
||||||
@apply .m-0 .text-sm .bg-grey-lighter .rounded .border;
|
@apply .m-0 .text-sm .border .border-grey-light .bg-grey-lighter .rounded;
|
||||||
padding: .15rem .4rem;
|
padding: .15rem .4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ div[class*="language-"] {
|
|||||||
@apply .relative .bg-grey-darkest .rounded .border .border-black .text-sm .my-4;
|
@apply .relative .bg-grey-darkest .rounded .border .border-black .text-sm .my-4;
|
||||||
|
|
||||||
.highlight-lines {
|
.highlight-lines {
|
||||||
@apply .absolute .pin-l .w-full .leading-normal .select-none;
|
@apply .absolute .left-0 .w-full .leading-normal .select-none;
|
||||||
top: .9rem;
|
top: .9rem;
|
||||||
|
|
||||||
.highlighted {
|
.highlighted {
|
||||||
@ -57,7 +57,7 @@ div[class*="language-"] {
|
|||||||
@apply .relative;
|
@apply .relative;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
@apply .absolute .pin-l .pin-t .block .h-full .w-4;
|
@apply .absolute .left-0 .top-0 .block .h-full .w-4;
|
||||||
content: ' ';
|
content: ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ div[class*="language-"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers-wrapper {
|
.line-numbers-wrapper {
|
||||||
@apply .absolute .pin-t .text-center .w-4;
|
@apply .absolute .top-0 .text-center .w-4;
|
||||||
|
|
||||||
br {
|
br {
|
||||||
@apply .select-none;
|
@apply .select-none;
|
||||||
@ -78,7 +78,7 @@ div[class*="language-"] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&::after {
|
&::after {
|
||||||
@apply .absolute .pin-t .pin-l .h-full .w-4;
|
@apply .absolute .top-0 .left-0 .h-full .w-4;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'et-line';
|
font-family: 'et-line';
|
||||||
src:url('../fonts/et-line/et-line.eot');
|
src:url('./fonts/et-line/et-line.eot');
|
||||||
src:url('../fonts/et-line/et-line.eot?#iefix') format('embedded-opentype'),
|
src:url('./fonts/et-line/et-line.eot?#iefix') format('embedded-opentype'),
|
||||||
url('../fonts/et-line/et-line.woff') format('woff'),
|
url('./fonts/et-line/et-line.woff') format('woff'),
|
||||||
url('../fonts/et-line/et-line.ttf') format('truetype'),
|
url('./fonts/et-line/et-line.ttf') format('truetype'),
|
||||||
url('../fonts/et-line/et-line.svg#et-line') format('svg');
|
url('./fonts/et-line/et-line.svg#et-line') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "tailwindcss/preflight";
|
@import "tailwindcss/base";
|
||||||
@import "tailwindcss/components";
|
@import "tailwindcss/components";
|
||||||
|
|
||||||
@import "./layout.css";
|
@import "./layout.css";
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
@apply .px-6;
|
@apply .px-6;
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
@apply .flex-no-shrink;
|
@apply .flex-shrink-0;
|
||||||
width: 18.5rem; /* sidebar is 20rem + 1.5rem padding on each side for nav */
|
width: 18.5rem; /* sidebar is 20rem + 1.5rem padding on each side for nav */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
input {
|
input {
|
||||||
transition: all 200ms ease-in;
|
transition: all 200ms ease-in;
|
||||||
@apply .text-grey-lighter .w-1/2 .outline-none .px-4 .py-2 .rounded;
|
@apply .text-grey-lighter .w-1/2 .outline-none .px-4 .py-2 .rounded .leading-tight;
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
|||||||
@ -5,13 +5,13 @@ $arrow-bg: #000;
|
|||||||
@apply .hidden;
|
@apply .hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@apply .fixed .pin-l .pin-b .bg-white .overflow-auto .border-r .border-grey-lighter .py-8;
|
@apply .fixed .left-0 .bottom-0 .bg-white .overflow-auto .border-r .border-grey-lighter .py-8;
|
||||||
top: 56px;
|
top: 56px;
|
||||||
width: 20rem;
|
width: 20rem;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@apply .list-reset .m-0;
|
@apply .m-0 .p-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -90,6 +90,56 @@ $arrow-bg: #000;
|
|||||||
&.open .arrow {
|
&.open .arrow {
|
||||||
top: -0.18em;
|
top: -0.18em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.version-select {
|
||||||
|
@apply .relative .inline-block .text-sm;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
@apply .outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
@apply .select-none .border .border-grey-lighter .cursor-pointer .px-4;
|
||||||
|
border-radius: 1rem;
|
||||||
|
|
||||||
|
&:hover, &.open {
|
||||||
|
@apply .bg-grey-lighter .border-grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
@apply .inline-block .relative;
|
||||||
|
top: -0.16em;
|
||||||
|
left: .5em;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-top: 6px solid #b8c2cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.items {
|
||||||
|
@apply .absolute .right-0 .bg-white .shadow .p-1 .mt-1;
|
||||||
|
border-radius: 1rem;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
@apply .select-none .rounded-full .cursor-pointer .px-2 .border .border-white;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-top: .125rem;
|
||||||
|
margin-bottom: .125rem;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
@apply .bg-grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@apply .mb-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-group-items {
|
.sidebar-group-items {
|
||||||
@ -125,7 +175,7 @@ $arrow-bg: #000;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-mask {
|
.sidebar-mask {
|
||||||
@apply .fixed .pin-t .pin-l .h-screen .w-screen .hidden;
|
@apply .fixed .top-0 .left-0 .h-screen .w-screen .hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-open > .sidebar {
|
.sidebar-open > .sidebar {
|
||||||
|
|||||||
@ -118,7 +118,7 @@
|
|||||||
@charset 'UTF-8';
|
@charset 'UTF-8';
|
||||||
/* Slider */
|
/* Slider */
|
||||||
.slick-loading .slick-list {
|
.slick-loading .slick-list {
|
||||||
background: #fff url('../../public/frontpage/loading.svg') center center no-repeat;
|
background: #fff url('../public/frontpage/loading.svg') center center no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icons */
|
/* Icons */
|
||||||
@ -127,8 +127,8 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|
||||||
src: url('../fonts/slick/slick.eot');
|
src: url('./fonts/slick/slick.eot');
|
||||||
src: url('../fonts/slick/slick.eot?#iefix') format('embedded-opentype'), url('../fonts/slick/slick.woff') format('woff'), url('../fonts/slick/slick.ttf') format('truetype'), url('../fonts/slick/slick.svg#slick') format('svg');
|
src: url('./fonts/slick/slick.eot?#iefix') format('embedded-opentype'), url('./fonts/slick/slick.woff') format('woff'), url('./fonts/slick/slick.ttf') format('truetype'), url('./fonts/slick/slick.svg#slick') format('svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arrows */
|
/* Arrows */
|
||||||
|
|||||||
@ -14,12 +14,20 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd {
|
.content {
|
||||||
@apply .border .border-grey-lighter .bg-grey-lightest;
|
ul, ol {
|
||||||
|
@apply .ml-6 .pl-8 .my-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, ol {
|
ul {
|
||||||
@apply .pl-8 .my-2;
|
list-style-type: disc;
|
||||||
|
padding-left: theme('padding.4');
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
padding-left: theme('padding.4');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
@ -65,15 +73,12 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@apply .pb-2 .border-b;
|
@apply .text-2xl .pb-2 .border-b .border-grey-light;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@apply .my-4;
|
@apply .my-4;
|
||||||
}
|
line-height: 1.7;
|
||||||
|
|
||||||
code, kbd, .line-number {
|
|
||||||
@apply font-mono;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p, ul, ol {
|
p, ul, ol {
|
||||||
@ -97,7 +102,7 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th, td {
|
th, td {
|
||||||
@apply .border .py-2 .px-4;
|
@apply .border .py-2 .px-4 .border-grey-light;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
|||||||
@ -206,11 +206,17 @@ function resolveItem (item, pages, base, isNested) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const children = item.children || []
|
const children = item.children || []
|
||||||
|
const versions = item.versions || []
|
||||||
return {
|
return {
|
||||||
type: 'group',
|
type: 'group',
|
||||||
title: item.title,
|
...item,
|
||||||
children: children.map(child => resolveItem(child, pages, base, true)),
|
children: children.map(child => resolveItem(child, pages, base, true)),
|
||||||
collapsable: item.collapsable !== false
|
collapsable: item.collapsable !== false,
|
||||||
|
versions: versions.map(version => ({
|
||||||
|
...version,
|
||||||
|
status: version.name === item.currentVersion ? "current" : version.status,
|
||||||
|
children: version.children.map(child => resolveItem(item.path + version.name + child, pages, base, true))
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Give theme name:
|
|||||||
> (Press Enter)
|
> (Press Enter)
|
||||||
|
|
||||||
Where will assets be located? []:
|
Where will assets be located? []:
|
||||||
> /themes/(MyThemeNameHere) (Example: /themes/MyThemeNameHere)
|
> themes/(MyThemeNameHere) (Example: themes/MyThemeNameHere)
|
||||||
|
|
||||||
Extends an other theme? (yes/no) [no]:
|
Extends an other theme? (yes/no) [no]:
|
||||||
> (Press Enter)
|
> (Press Enter)
|
||||||
|
|||||||
@ -148,3 +148,9 @@ Starting with `v0.6` of the Daemon, the following previously _dropped_ capabilit
|
|||||||
'setfcap',
|
'setfcap',
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Enabling Cloudflare
|
||||||
|
|
||||||
|
Enabling Cloudflare on the daemon isn't particularly useful since users do not connect directly to the daemon port, and users need an unproxied hostname to access any servers on the node. As a result it's not possible to conceal the IP address of your node machine, but some people want to enable it regardless.
|
||||||
|
|
||||||
|
Cloudflare only proxies the default daemon port (8080) when using HTTP. In order to get the daemon to work with Cloudflare when HTTPS is enabled you must change the daemon port to one that Cloudflare will proxy such as 8443. Since Cloudflare only proxies HTTP/HTTPS traffic for non-enterprise plans you cannot proxy the SFTP port.
|
||||||
@ -5,17 +5,12 @@
|
|||||||
## Supported Systems
|
## Supported Systems
|
||||||
| Operating System | Version | Supported | Notes |
|
| Operating System | Version | Supported | Notes |
|
||||||
| ---------------- | ------- | :-------: | ----- |
|
| ---------------- | ------- | :-------: | ----- |
|
||||||
| **Ubuntu** | 14.04 | :warning: | Approaching EOL, not recommended for new installations. |
|
| **Ubuntu** | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
||||||
| | 16.04 | :white_check_mark: | |
|
| | 20.04 | :white_check_mark: |
|
||||||
| | 18.04 | :white_check_mark: | |
|
| **CentOS** | 7 | :warning: | Extra repos are required |
|
||||||
| **CentOS** | 6 | :no_entry_sign: | Does not support all of the required packages. |
|
| | 8 | :white_check_mark: | |
|
||||||
| | 7 | :white_check_mark: | |
|
| **Debian** | 9 | :white_check_mark: | |
|
||||||
| **Debian** | 8 | :warning: | Requires [kernel modifications](debian_8_docker.md) to run Docker. |
|
| | 10 | :white_check_mark: | |
|
||||||
| | 9 | :white_check_mark: | |
|
|
||||||
| **Alpine Linux** | 3.4+ | :warning: | Not officially supported, but reportedly works. |
|
|
||||||
| **RHEL** | 7 | :warning: | Not officially supported, should work. |
|
|
||||||
| **Fedora** | 28 | :warning: | Not officially supported, should work. |
|
|
||||||
| | 29 | :warning: | Not officially supported, should work. |
|
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
In order to run the Daemon you will need a system capable of running Docker containers. Most VPS and almost all
|
In order to run the Daemon you will need a system capable of running Docker containers. Most VPS and almost all
|
||||||
@ -148,7 +143,7 @@ Once you have done that there will be a tab called Configuration when you view t
|
|||||||
Simply copy and paste the code block and paste it into a file called `core.json` in `/srv/daemon/config` and save it.
|
Simply copy and paste the code block and paste it into a file called `core.json` in `/srv/daemon/config` and save it.
|
||||||
You may also use the Auto-Deployment feature rather than manually creating the files.
|
You may also use the Auto-Deployment feature rather than manually creating the files.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Starting the Daemon
|
## Starting the Daemon
|
||||||
To start your daemon simply move into the daemon directory and run the command below which will start the daemon in
|
To start your daemon simply move into the daemon directory and run the command below which will start the daemon in
|
||||||
@ -192,18 +187,3 @@ Then, run the commands below to reload systemd and start the daemon.
|
|||||||
``` bash
|
``` bash
|
||||||
systemctl enable --now wings
|
systemctl enable --now wings
|
||||||
```
|
```
|
||||||
|
|
||||||
### Daemonizing (using Forever)
|
|
||||||
Forever allows us to run the daemon as a pseudo-daemonized application. We can exit our terminal session without
|
|
||||||
killing the process, and we don't have to run it in a screen. Inside the daemon directory, run the commands below which
|
|
||||||
will install forever and then start the process in the background.
|
|
||||||
|
|
||||||
You should use this only if your system does not support systemd.
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
npm install -g forever
|
|
||||||
forever start src/index.js
|
|
||||||
|
|
||||||
# To stop the daemon use:
|
|
||||||
forever stop src/index.js
|
|
||||||
```
|
|
||||||
14
package.json
14
package.json
@ -1,19 +1,21 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@vuepress/plugin-google-analytics": "^1.0.0-rc.1",
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.3.1",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"vuepress": "^0.14.8"
|
"vuepress": "^1.4.0",
|
||||||
|
"vuepress-plugin-container": "^2.1.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "./node_modules/vuepress/bin/vuepress.js build",
|
"build": "vuepress build",
|
||||||
"watch": "./node_modules/vuepress/bin/vuepress.js dev"
|
"watch": "vuepress dev"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^9.0.1",
|
"autoprefixer": "^9.0.1",
|
||||||
"cssnano": "^4.0.3",
|
"cssnano": "^4.0.3",
|
||||||
"lodash": "^4.17.13",
|
"lodash": "^4.17.13",
|
||||||
"postcss-import": "^11.1.0",
|
"postcss-import": "^12.0.0",
|
||||||
"precss": "^3.1.2",
|
"precss": "^4.0.0",
|
||||||
"tailwindcss": "^0.6.4"
|
"tailwindcss": "^1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,14 +20,11 @@ this software on an OpenVZ based system you will — most likely — not
|
|||||||
|
|
||||||
| Operating System | Version | Supported | Notes |
|
| Operating System | Version | Supported | Notes |
|
||||||
| ---------------- | ------- | :-------: | ----- |
|
| ---------------- | ------- | :-------: | ----- |
|
||||||
| **Ubuntu** | 14.04 | :warning: | Documentation assumes changes to `systemd` introduced in `16.04` |
|
| **Ubuntu** | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
||||||
| | 16.04 | :warning: | Ubuntu 16.04 is nearing end of life. |
|
| | 20.04 | :white_check_mark: | |
|
||||||
| | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
| **CentOS** | 7 | :white_check_mark: | Extra repos are required. |
|
||||||
| **CentOS** | 6 | :no_entry_sign: | Does not support all of the required packages. |
|
|
||||||
| | 7 | :white_check_mark: | Extra repos are required. |
|
|
||||||
| | 8 | :white_check_mark: | All required packages are part of the base repos. |
|
| | 8 | :white_check_mark: | All required packages are part of the base repos. |
|
||||||
| **Debian** | 8 | :warning: | Debian 8 may need modifications to work with the latest docker and other requirements for the panel/daemon |
|
| **Debian** | 9 | :white_check_mark: | Extra repos are required. |
|
||||||
| | 9 | :white_check_mark: | Extra repos are required. |
|
|
||||||
| | 10 | :white_check_mark: | All required packages are part of the base repos. |
|
| | 10 | :white_check_mark: | All required packages are part of the base repos. |
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
[[toc]]
|
[[toc]]
|
||||||
|
|
||||||
|
::: danger Not for Production Use
|
||||||
|
**This is a beta version that should not be used in a production environment.**
|
||||||
|
Features haven't been fully tested and might be incomplete or broken. There is no supported way to upgrade. You should test this version with a separate installation.
|
||||||
|
:::
|
||||||
|
|
||||||
Pterodactyl Panel is designed to run on your own web server. You will need to have root access to your server in order to run and use this panel.
|
Pterodactyl Panel is designed to run on your own web server. You will need to have root access to your server in order to run and use this panel.
|
||||||
|
|
||||||
You are expected to understand how to read documentation to use this Panel. We have spent many hours detailing how to install or upgrade our
|
You are expected to understand how to read documentation to use this Panel. We have spent many hours detailing how to install or upgrade our
|
||||||
@ -20,13 +25,11 @@ this software on an OpenVZ based system you will — most likely — not
|
|||||||
|
|
||||||
| Operating System | Version | Supported | Notes |
|
| Operating System | Version | Supported | Notes |
|
||||||
| ---------------- | ------- | :-------: | ----- |
|
| ---------------- | ------- | :-------: | ----- |
|
||||||
| **Ubuntu** | 16.04 | :warning: | Ubuntu 16.04 is nearing end of life. |
|
| **Ubuntu** | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
||||||
| | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
| | 20.04 | :white_check_mark: | |
|
||||||
| **CentOS** | 6 | :no_entry_sign: | Does not support all of the required packages. |
|
| **CentOS** | 7 | :white_check_mark: | Extra repos are required. |
|
||||||
| | 7 | :white_check_mark: | Extra repos are required. |
|
|
||||||
| | 8 | :white_check_mark: | All required packages are part of the base repos. |
|
| | 8 | :white_check_mark: | All required packages are part of the base repos. |
|
||||||
| **Debian** | 8 | :warning: | Debian 8 may need modifications to work with the latest docker and other requirements for the panel/daemon |
|
| **Debian** | 9 | :white_check_mark: | Extra repos are required. |
|
||||||
| | 9 | :white_check_mark: | Extra repos are required. |
|
|
||||||
| | 10 | :white_check_mark: | All required packages are part of the base repos. |
|
| | 10 | :white_check_mark: | All required packages are part of the base repos. |
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|||||||
@ -17,7 +17,7 @@ members can be found in our Discord channel and are distinguished with a yellow
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
``` text
|
``` text
|
||||||
Copyright (c) 2015 - 2019 Dane Everitt <dane@daneeveritt.com>.
|
Copyright (c) 2015 - 2020 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
|
# Community Standards
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Sorry, but this file is off limits to additions or deletions that are not the result of fixing
|
Sorry, but this file is off limits to additions or deletions that are not the result of fixing
|
||||||
grammar or spelling mistakes.
|
grammar or spelling mistakes.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# Community Standards
|
|
||||||
Pterodactyl prides itself on providing a warm and welcoming community for all of our members. However, due to the
|
Pterodactyl prides itself on providing a warm and welcoming community for all of our members. However, due to the
|
||||||
sheer size of our community, we have a few rules that we expect all individuals to follow at all times.
|
sheer size of our community, we have a few rules that we expect all individuals to follow at all times.
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ In addition to our standard nest of supported games, our community is constantly
|
|||||||
and there are plenty more games available provided by the community. Some of these games include:
|
and there are plenty more games available provided by the community. Some of these games include:
|
||||||
|
|
||||||
* Factorio
|
* Factorio
|
||||||
* Terraria
|
|
||||||
* San Andreas: MP
|
* San Andreas: MP
|
||||||
* Pocketmine MP
|
* Pocketmine MP
|
||||||
* Squad
|
* Squad
|
||||||
|
|||||||
30
tailwind.js
30
tailwind.js
@ -123,6 +123,36 @@ let colors = {
|
|||||||
'pink-lightest': '#ffebef',
|
'pink-lightest': '#ffebef',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
prefix: '',
|
||||||
|
important: false,
|
||||||
|
separator: ':',
|
||||||
|
theme: {
|
||||||
|
colors,
|
||||||
|
screens: {
|
||||||
|
'sm': '576px',
|
||||||
|
'md': '768px',
|
||||||
|
'lg': '992px',
|
||||||
|
'xl': '1200px',
|
||||||
|
|
||||||
|
'xsx': { 'max': '575px' },
|
||||||
|
'smx': { 'max': '767px' },
|
||||||
|
'mdx': { 'max': '991px' },
|
||||||
|
'lgx': { 'max': '1999px' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
appearance: ['responsive'],
|
||||||
|
// ...
|
||||||
|
zIndex: ['responsive'],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -14,18 +14,12 @@ This software _requires Pterodactyl 1.0_ in order to run.
|
|||||||
## Supported Systems
|
## Supported Systems
|
||||||
| Operating System | Version | Supported | Notes |
|
| Operating System | Version | Supported | Notes |
|
||||||
| ---------------- | ------- | :-------: | ----- |
|
| ---------------- | ------- | :-------: | ----- |
|
||||||
| **Ubuntu** | 14.04 | :no_entry_sign: | Does not support `systemd`. |
|
| **Ubuntu** | 18.04 | :white_check_mark: | Documentation written assuming Ubuntu 18.04 as the base OS. |
|
||||||
| | 16.04 | :white_check_mark: | |
|
| | 20.04 | :white_check_mark: | |
|
||||||
| | 18.04 | :white_check_mark: | |
|
| **CentOS** | 7 | :white_check_mark: | |
|
||||||
| **CentOS** | 6 | :no_entry_sign: | Does not support all of the required packages. |
|
| | 8 | :white_check_mark: | |
|
||||||
| | 7 | :white_check_mark: | |
|
| **Debian** | 9 | :white_check_mark: | |
|
||||||
| **Debian** | 8 | :warning: | Requires [kernel modifications](/daemon/debian_8_docker.md) to run Docker. |
|
|
||||||
| | 9 | :white_check_mark: | |
|
|
||||||
| | 10 | :white_check_mark: | |
|
| | 10 | :white_check_mark: | |
|
||||||
| **Alpine Linux** | 3.4+ | :warning: | Not officially supported, but reportedly works. |
|
|
||||||
| **RHEL** | 7 | :warning: | Not officially supported, should work. |
|
|
||||||
| **Fedora** | 28 | :warning: | Not officially supported, should work. |
|
|
||||||
| | 29 | :warning: | Not officially supported, should work. |
|
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
In order to run the Daemon you will need a system capable of running Docker containers. Most VPS and almost all
|
In order to run the Daemon you will need a system capable of running Docker containers. Most VPS and almost all
|
||||||
@ -124,7 +118,7 @@ Once you have done that there will be a tab called Configuration when you view t
|
|||||||
|
|
||||||
Simply copy and paste the code block and paste it into a file called `config.yml` in `/srv/wings` and save it.
|
Simply copy and paste the code block and paste it into a file called `config.yml` in `/srv/wings` and save it.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Starting Wings
|
### Starting Wings
|
||||||
To start your daemon simply move into the daemon directory and run the command below which will start the daemon in
|
To start your daemon simply move into the daemon directory and run the command below which will start the daemon in
|
||||||
Loading…
x
Reference in New Issue
Block a user