3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

Auto-generate plugin docs (WIP)

This commit is contained in:
Dragory 2019-08-22 01:22:26 +03:00
parent 6bdb05e678
commit ee6d622941
44 changed files with 599 additions and 150 deletions

View file

@ -0,0 +1,64 @@
<template>
<div>
<h1 class="z-title is-1 mb-1">Argument Types</h1>
<p class="mb-1">
This page details the different argument types available for commands.
</p>
<h2 id="delay" class="z-title is-2 mt-2 mb-1">Delay</h2>
<p class="mb-1">
A delay is used to specify an amount of time. It uses simple letters to specify time durations.<br>
For example, <code>2d15h27m3s</code> would be 2 days, 15 hours, 27 minutes and 3 seconds.
</p>
<p class="mb-1">
Note that the delay should always be written as 1 word, without spaces!
</p>
<b-collapse :open="false" class="card mb-1">
<div slot="trigger" slot-scope="props" class="card-header" role="button">
<p class="card-header-title">Additional Information</p>
<a class="card-header-icon">
<b-icon :icon="props.open ? 'menu-down' : 'menu-up'"></b-icon>
</a>
</div>
<div class="card-content">
<div class="content">
Durations:
<ul>
<li>
<code>d</code> Day
</li>
<li>
<code>h</code> Hour
</li>
<li>
<code>m</code> Minute
</li>
<li>
<code>s</code> Seconds
</li>
</ul>
</div>
</div>
</b-collapse>
<h2 id="string" class="z-title is-2 mb-1">String</h2>
<h2 id="user" class="z-title is-2 mt-2 mb-1">User</h2>
<p class="mb-1">
Anything that uniquely identifies a user. This includes:
</p>
<ul class="z-list z-ul mb-1">
<li>User ID <code>108552944961454080</code></li>
<li>User Mention <code>@Dark#1010</code></li>
<li>Loose user mention <code>Dark#1010</code></li>
</ul>
</div>
</template>
<script>
import CodeBlock from "./CodeBlock";
export default {
components: { CodeBlock },
};
</script>

View file

@ -1,10 +1,10 @@
<template>
<div>
<h1>Configuration format</h1>
<p>
<h1 class="z-title is-1 mb-1">Configuration format</h1>
<p class="mb-1">
This is the basic format of the bot configuration for a guild. The basic breakdown is:
</p>
<ol>
<ol class="z-list mb-1">
<li>Prefix (i.e. what character is preceding each command)</li>
<li>Permission levels (see <router-link to="/docs/permissions">Permissions</router-link> for more info)</li>
<li>Plugin-specific configuration (see <router-link to="/docs/plugin-configuration">Plugin configuration</router-link> for more info)</li>

View file

@ -1,29 +1,29 @@
<template>
<div>
<h1>Introduction</h1>
<p>
<h1 class="z-title is-1 mb-1">Introduction</h1>
<p class="mb-1">
Zeppelin is a private moderation bot for Discord, designed with large servers and reliability in mind.
</p>
<h2>Getting the bot</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Getting the bot</h2>
<p class="mb-1">
Since the bot is currently private, access to the bot is granted on a case by case basis.<br>
There are plans to streamline this process in the future.
</p>
<h2>Configuration</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Configuration</h2>
<p class="mb-1">
All Zeppelin configuration is done through the dashboard by editing a YAML config file. By default, only the server
owner has access to this, but they can give other users access as they see fit. See <router-link to="/docs/configuration-format">Configuration format</router-link> for more details.
</p>
<h2>Plugins</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Plugins</h2>
<p class="mb-1">
Zeppelin is divided into plugins: grouped functionality that can be enabled/disabled as needed, and that have their own configurations.
</p>
<h2>Commands</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Commands</h2>
<p class="mb-1">
The commands for each plugin are listed on the plugin's page (see "Plugins" on the menu). On these pages, the command prefix is assumed to be <code>!</code> but this can be changed on a per-server basis.
</p>
</div>

View file

@ -41,14 +41,15 @@
<p class="menu-label">Plugins</p>
<ul class="menu-list">
<li><router-link to="/docs/plugins/locate-user">Locate user</router-link></li>
<li><router-link to="/docs/plugins/mod-actions">Mod actions</router-link></li>
<li v-for="plugin in plugins">
<router-link :to="'/docs/plugins/' + plugin.name">{{ plugin.info.prettyName || plugin.name }}</router-link>
</li>
</ul>
</aside>
</div>
</div>
<div class="docs-main content">
<router-view></router-view>
<div class="docs-main">
<router-view :key="$route.fullPath"></router-view>
</div>
</div>
</div>
@ -132,9 +133,22 @@
<script>
import Vue from "vue";
import VueHighlightJS from "vue-highlightjs";
import {mapState} from "vuex";
import "../../directives/trim-code";
import "highlight.js/styles/ocean.css";
import "../../style/docs.scss";
Vue.use(VueHighlightJS);
export default {
async mounted() {
await this.$store.dispatch("docs/loadAllPlugins");
},
computed: {
...mapState('docs', {
plugins: 'allPlugins',
}),
},
};
</script>

View file

@ -1,23 +1,23 @@
<template>
<div>
<h1>Permissions</h1>
<p>
<h1 class="z-title is-1 mb-1">Permissions</h1>
<p class="mb-1">
Permissions in Zeppelin are simply values in plugin configuration that are checked when the command is used.
These values can be changed with overrides (see <router-link to="/docs/plugin-configuration">Plugin configuration</router-link> for more info)
and can depend on e.g. user id, role id, channel id, category id, or <strong>permission level</strong>.
</p>
<h2>Permission levels</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Permission levels</h2>
<p class="mb-1">
The simplest way to control access to bot commands and features is via permission levels.
These levels are simply a number (usually between 0 and 100), based on the user's roles or user id, that can then
be used in permission overrides. By default, several commands are "moderator only" (level 50 and up) or "admin only" (level 100 and up).
</p>
<p>
<p class="mb-1">
Additionally, having a higher permission level means that certain commands (such as !ban) can't be used against
you by users with a lower or equal permission level (so e.g. moderators can't ban each other or admins above them).
</p>
<p>
<p class="mb-1">
Permission levels are defined in the config in the <strong>levels</strong> section. For example:
</p>
@ -28,14 +28,14 @@
"172950000412655616": 50 # Example mod
</CodeBlock>
<h2>Examples</h2>
<h2 class="z-title is-2 mt-2 mb-1">Examples</h2>
<h3>Basic overrides</h3>
<p>
<h3 class="z-title is-3 mb-1">Basic overrides</h3>
<p class="mb-1">
For this example, let's assume we have a plugin called <code>cats</code> which has a command <code>!cat</code> locked behind the permission <code>can_cat</code>.
Let's say that by default, the plugin allows anyone to use <code>!cat</code>, but we want to restrict it to moderators only.
</p>
<p>
<p class="mb-1">
Here's what the configuration for this would look like:
</p>
@ -51,15 +51,15 @@
can_cat: true
</CodeBlock>
<h3>Replacing defaults</h3>
<p>
<h3 class="z-title is-3 mt-2 mb-1">Replacing defaults</h3>
<p class="mb-1">
In this example, let's assume you don't want to use the default permission levels of 50 and 100 for mods and admins respectively.
Let's say you're using various incremental levels instead: 10, 20, 30, 40, 50...<br>
We want to make it so moderator commands are available starting at level 70.
Additionally, we'd like to reserve banning for levels 90+ only.
To do this, we need to <strong>replace</strong> the default overrides that enable moderator commands at level 50.
</p>
<p>
<p class="mb-1">
Here's what the configuration for this would look like:
</p>

View file

@ -0,0 +1,77 @@
<template>
<div v-if="loading">
Loading...
</div>
<div v-else>
<h1 class="z-title is-1 mb-1">{{ data.info.prettyName || data.name }}</h1>
<p class="mb-1">
Name in config: <code>{{ data.name }}</code>
</p>
<div v-if="data.info.description">
<h2 class="z-title is-2 mt-2 mb-1">Description</h2>
<div class="content" v-html="renderMarkdown(data.info.description)"></div>
</div>
<h2 class="z-title is-2 mt-2 mb-1">Default configuration</h2>
<CodeBlock lang="yaml">{{ renderConfiguration(data.options) }}</CodeBlock>
<div v-if="data.commands.length">
<h2 class="z-title is-2 mt-2 mb-1">Commands</h2>
<div v-for="command in data.commands">
<h3 class="z-title is-3 mt-2 mb-1">!{{ command.trigger }}</h3>
<div v-if="command.config.requiredPermission">
Permission: <code>{{ command.config.requiredPermission }}</code>
</div>
<div v-if="command.config.info && command.config.info.basicUsage">
Basic usage: <code>{{ command.config.info.basicUsage }}</code>
</div>
<div v-if="command.config.aliases && command.config.aliases.length">
Shortcut:
<code style="margin-right: 4px" v-for="alias in command.config.aliases">!{{ alias }}</code>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from "vue";
import {mapState} from "vuex";
import marked from "marked";
import yaml from "js-yaml";
import CodeBlock from "./CodeBlock";
export default {
components: { CodeBlock },
async mounted() {
this.loading = true;
await this.$store.dispatch("docs/loadPluginData", this.pluginName);
this.loading = false;
},
methods: {
renderMarkdown(str) {
return marked(str);
},
renderConfiguration(options) {
return yaml.safeDump({
[this.pluginName]: options,
});
},
},
data() {
return {
loading: true,
pluginName: this.$route.params.pluginName,
};
},
computed: {
...mapState("docs", {
data(state) {
return state.plugins[this.pluginName];
},
}),
},
}
</script>

View file

@ -1,20 +1,20 @@
<template>
<div>
<h1>Plugin configuration</h1>
<p>
<h1 class="z-title is-1 mb-1">Plugin configuration</h1>
<p class="mb-1">
Each plugin in Zeppelin has its own configuration options. In the config editor, you can both set the default config
and overrides based on specific conditions. Permissions are also just values in the plugin's config, and thus follow
the same rules with overrides etc. as other options (see <router-link to="/docs/permissions">Permissions</router-link> for more info).
</p>
<p>
<p class="mb-1">
Information about each plugin's options can be found on the plugin's page on the sidebar. See <router-link to="/docs/configuration-format">Configuration format</router-link> for an example of a full config.
</p>
<h2>Overrides</h2>
<p>
<h2 class="z-title is-2 mt-2 mb-1">Overrides</h2>
<p class="mb-1">
Overrides are the primary mechanism of changing options and permissions based on permission levels, roles, channels, user ids, etc.
</p>
<p>
<p class="mb-1">
Here's an example demonstrating different types of overrides:
</p>

View file

@ -36,28 +36,12 @@ export const router = new VueRouter({
component: () => import("./components/docs/PluginConfiguration.vue"),
},
{
path: "descriptions",
component: () => import("./components/docs/descriptions/Layout.vue"),
children: [
{
path: "argument-types",
component: () => import("./components/docs/descriptions/ArgumentTypes.vue"),
},
],
path: "descriptions/argument-types",
component: () => import("./components/docs/ArgumentTypes.vue"),
},
{
path: "plugins",
component: () => import("./components/docs/plugins/Layout.vue"),
children: [
{
path: "mod-actions",
component: () => import("./components/docs/plugins/ModActions.vue"),
},
{
path: "locate-user",
component: () => import("./components/docs/plugins/LocateUser.vue"),
},
],
path: "plugins/:pluginName",
component: () => import("./components/docs/Plugin.vue"),
},
],
},
@ -80,11 +64,15 @@ export const router = new VueRouter({
},
],
scrollBehavior(to) {
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash,
};
} else if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
},
});

View file

@ -0,0 +1,54 @@
import { get } from "../api";
import { Module } from "vuex";
import { DocsState, RootState } from "./types";
export const DocsStore: Module<DocsState, RootState> = {
namespaced: true,
state: {
allPlugins: [],
loadingAllPlugins: false,
plugins: {},
},
actions: {
async loadAllPlugins({ state, commit }) {
if (state.loadingAllPlugins) return;
commit("setAllPluginLoadStatus", true);
const plugins = await get("docs/plugins");
plugins.sort((a, b) => {
const aName = (a.info.prettyName || a.name).toLowerCase();
const bName = (b.info.prettyName || b.name).toLowerCase();
if (aName > bName) return 1;
if (aName < bName) return -1;
return 0;
});
commit("setAllPlugins", plugins);
commit("setAllPluginLoadStatus", false);
},
async loadPluginData({ state, commit }, name) {
if (state.plugins[name]) return;
const data = await get(`docs/plugins/${name}`);
commit("setPluginData", { name, data });
},
},
mutations: {
setAllPluginLoadStatus(state: DocsState, status: boolean) {
state.loadingAllPlugins = status;
},
setAllPlugins(state: DocsState, plugins) {
state.allPlugins = plugins;
},
setPluginData(state: DocsState, { name, data }) {
state.plugins[name] = data;
},
},
};

View file

@ -6,23 +6,27 @@ Vue.use(Vuex);
import { RootState } from "./types";
import { AuthStore } from "./auth";
import { GuildStore } from "./guilds";
import { DocsStore } from "./docs";
export const RootStore = new Vuex.Store<RootState>({
modules: {
auth: AuthStore,
guilds: GuildStore,
docs: DocsStore,
},
});
// Set up typings so Vue/our components know about the state's types
declare module "vue/types/options" {
interface ComponentOptions<V extends Vue> {
// @ts-ignore
store?: Store<RootState>;
}
}
declare module "vue/types/vue" {
interface Vue {
// @ts-ignore
$store: Store<RootState>;
}
}

View file

@ -21,7 +21,29 @@ export interface GuildState {
};
}
export interface ThinDocsPlugin {
name: string;
info: {
name: string;
description?: string;
};
}
export interface DocsPlugin extends ThinDocsPlugin {
commands: any[];
}
export interface DocsState {
allPlugins: ThinDocsPlugin[];
loadingAllPlugins: boolean;
plugins: {
[key: string]: DocsPlugin;
};
}
export type RootState = {
auth: AuthState;
guilds: GuildState;
docs: DocsState;
};

View file

@ -1,6 +1,12 @@
@import url('https://cdn.materialdesignicons.com/2.5.94/css/materialdesignicons.min.css');
$family-primary: 'Open Sans', sans-serif;
$list-background-color: transparent;
$size-1: 2.5rem;
$size-2: 2rem;
$size-3: 1.5rem;
$size-4: 1.25rem;
@import "~bulmaswatch/superhero/_variables";
@import "~bulma/bulma";
@ -9,3 +15,30 @@ $family-primary: 'Open Sans', sans-serif;
.docs-cloak {
visibility: visible !important;
}
.z-title {
line-height: 1.125;
&.is-1 { font-size: $size-1; }
&.is-2 { font-size: $size-2; }
&.is-3 { font-size: $size-3; }
&.is-4 { font-size: $size-4; }
&.is-5 { font-size: $size-5; }
&.is-6 { font-size: $size-6; }
}
.z-list {
margin-left: 1.5rem;
}
.z-ul {
list-style: disc;
}
.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 1.5rem; }
.mt-3 { margin-top: 2rem; }
.mb-1 { margin-bottom: 1rem; }
.mb-2 { margin-bottom: 1.5rem; }
.mb-3 { margin-bottom: 2rem; }