mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Initial port to vue 3
This commit is contained in:
parent
e1966534d5
commit
454981fa1f
14 changed files with 1906 additions and 1804 deletions
|
@ -27,7 +27,7 @@
|
|||
"source-map-loader": "^4.0.1",
|
||||
"tailwindcss": "^1.9.6",
|
||||
"ts-loader": "^9.4.3",
|
||||
"vue-loader": "^15.10.1",
|
||||
"vue-loader": "^17.4.2",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vue-template-compiler": "^2.7.14",
|
||||
"webpack": "^5.88.0",
|
||||
|
@ -37,7 +37,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fastify/static": "^7.0.1",
|
||||
"@highlightjs/vue-plugin": "^1.0.2",
|
||||
"fastify": "^4.26.2",
|
||||
"highlight.js": "^11.8.0",
|
||||
"humanize-duration": "^3.27.0",
|
||||
|
@ -45,11 +44,12 @@
|
|||
"marked": "^5.1.0",
|
||||
"modern-css-reset": "^1.4.0",
|
||||
"moment": "^2.29.4",
|
||||
"vue": "^2.7.14",
|
||||
"vue-material-design-icons": "^4.1.0",
|
||||
"vue-router": "^3.6.5",
|
||||
"vue2-ace-editor": "^0.0.15",
|
||||
"vuex": "^3.6.2"
|
||||
"vue": "^3.5.13",
|
||||
"vue-material-design-icons": "^5.3.1",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-ace-editor": "^2.2.4",
|
||||
"vue3-highlightjs": "^1.0.5",
|
||||
"vuex": "^4.1.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 2 Chrome versions"
|
||||
|
|
|
@ -21,9 +21,11 @@ export const loginCallbackGuard: NavigationGuard = async (to, from, next) => {
|
|||
} else {
|
||||
window.location.href = `/?error=noAccess`;
|
||||
}
|
||||
return next();
|
||||
};
|
||||
|
||||
export const authRedirectGuard: NavigationGuard = async (to, form, next) => {
|
||||
if (await isAuthenticated()) return next("/dashboard");
|
||||
window.location.href = `${process.env.API_URL}/auth/login`;
|
||||
return next();
|
||||
};
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
.inline-code,
|
||||
code:not([class]),
|
||||
>>> code:not([class]) {
|
||||
:deep(code:not([class])) {
|
||||
@apply bg-gray-900;
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ export default {
|
|||
expiresAt: null,
|
||||
});
|
||||
|
||||
this.$set(perm, "permissions", new Set(perm.permissions));
|
||||
perm.permissions = new Set(perm.permissions);
|
||||
},
|
||||
|
||||
onTreeUpdate(targetPermissions) {
|
||||
|
|
|
@ -19,13 +19,20 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<AceEditor class="rounded shadow-lg border border-gray-700 mt-4"
|
||||
v-model="editableConfig"
|
||||
<v-ace-editor class="rounded shadow-lg border border-gray-700 mt-4"
|
||||
v-model:value="editableConfig"
|
||||
@init="editorInit"
|
||||
lang="yaml"
|
||||
theme="tomorrow_night"
|
||||
:height="editorHeight"
|
||||
ref="aceEditor" />
|
||||
ref="aceEditor"
|
||||
v-options="{
|
||||
useSoftTabs: true,
|
||||
tabSize: 2
|
||||
}"
|
||||
:style="{
|
||||
width: editorWidth + 'px',
|
||||
height: editorHeight + 'px',
|
||||
}" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -34,14 +41,19 @@
|
|||
import {ApiError} from "../../api";
|
||||
import { GuildState } from "../../store/types";
|
||||
|
||||
import AceEditor from "vue2-ace-editor";
|
||||
import { VAceEditor } from "vue3-ace-editor";
|
||||
|
||||
import "ace-builds/src-noconflict/ext-language_tools";
|
||||
import 'ace-builds/src-noconflict/ext-searchbox';
|
||||
import "ace-builds/src-noconflict/mode-yaml";
|
||||
import "ace-builds/src-noconflict/theme-tomorrow_night";
|
||||
|
||||
let editorKeybindListener;
|
||||
let windowResizeListener;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AceEditor,
|
||||
VAceEditor,
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
|
@ -101,16 +113,6 @@
|
|||
},
|
||||
methods: {
|
||||
editorInit() {
|
||||
require("brace/ext/language_tools");
|
||||
require('brace/ext/searchbox');
|
||||
require("brace/mode/yaml");
|
||||
require("brace/theme/tomorrow_night");
|
||||
|
||||
this.$refs.aceEditor.editor.setOptions({
|
||||
useSoftTabs: true,
|
||||
tabSize: 2
|
||||
});
|
||||
|
||||
// Add Ctrl+S/Cmd+S save shortcut
|
||||
const isMac = /mac/i.test(navigator.platform);
|
||||
const modKeyPressed = (ev: KeyboardEvent) => (isMac ? ev.metaKey : ev.ctrlKey);
|
||||
|
@ -131,7 +133,7 @@
|
|||
|
||||
if (shortcutModifierPressed(ev) && ev.key === "f") {
|
||||
ev.preventDefault();
|
||||
this.$refs.aceEditor.editor.execCommand("find");
|
||||
this.$refs.aceEditor.getAceInstance().execCommand("find");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -171,7 +173,7 @@
|
|||
this.editorHeight = newHeight;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.aceEditor.editor.resize();
|
||||
this.$refs.aceEditor.getAceInstance().resize();
|
||||
});
|
||||
},
|
||||
async save() {
|
||||
|
|
|
@ -174,7 +174,6 @@
|
|||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import {mapState} from "vuex";
|
||||
import yaml from "js-yaml";
|
||||
import CodeBlock from "./CodeBlock.vue";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Vue from "vue";
|
||||
import { Directive } from "vue";
|
||||
|
||||
Vue.directive("trim-indents", {
|
||||
bind(el, binding) {
|
||||
export const trimIndents: Directive = {
|
||||
beforeMount(el, binding) {
|
||||
const withoutStartEndWhitespace = el.innerHTML.replace(/(^\n+|\n+$)/g, "");
|
||||
|
||||
const mode = binding.value != null ? binding.value : "start";
|
||||
|
@ -22,4 +22,4 @@ Vue.directive("trim-indents", {
|
|||
.map((line) => line.slice(spacesToTrim))
|
||||
.join("\n");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import "./style/app.pcss";
|
||||
|
||||
import Vue from "vue";
|
||||
import { createApp } from "vue";
|
||||
|
||||
import VueHighlightJS from "@highlightjs/vue-plugin";
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import hljsYaml from "highlight.js/lib/languages/yaml.js";
|
||||
import VueHighlightJS from "vue3-highlightjs";
|
||||
import "highlight.js/styles/base16/ocean.css";
|
||||
|
||||
import { router } from "./routes";
|
||||
|
@ -13,9 +11,15 @@ import { RootStore } from "./store";
|
|||
import "./directives/trim-indents";
|
||||
|
||||
import App from "./components/App.vue";
|
||||
import { trimIndents } from "./directives/trim-indents";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(router);
|
||||
app.use(RootStore);
|
||||
|
||||
// Set up a read-only global variable to access specific env vars
|
||||
Vue.mixin({
|
||||
app.mixin({
|
||||
data() {
|
||||
return {
|
||||
get env() {
|
||||
|
@ -27,14 +31,8 @@ Vue.mixin({
|
|||
},
|
||||
});
|
||||
|
||||
hljs.registerLanguage("yaml", hljsYaml);
|
||||
Vue.use(VueHighlightJS, { hljs });
|
||||
app.use(VueHighlightJS);
|
||||
|
||||
const app = new Vue({
|
||||
router,
|
||||
store: RootStore,
|
||||
el: "#app",
|
||||
render(h) {
|
||||
return h(App);
|
||||
},
|
||||
});
|
||||
app.directive("trim-indents", trimIndents);
|
||||
|
||||
app.mount("#app");
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { authGuard, authRedirectGuard, loginCallbackGuard } from "./auth";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
export const router = new VueRouter({
|
||||
mode: "history",
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{ path: "/login", beforeEnter: authRedirectGuard },
|
||||
{ path: "/login-callback", beforeEnter: loginCallbackGuard },
|
||||
{ path: "/login", components: {}, beforeEnter: authRedirectGuard },
|
||||
{ path: "/login-callback", component: {}, beforeEnter: loginCallbackGuard },
|
||||
|
||||
// Privacy policy
|
||||
{
|
||||
|
@ -97,12 +94,12 @@ export const router = new VueRouter({
|
|||
scrollBehavior(to, from, savedPosition) {
|
||||
if (to.hash) {
|
||||
return {
|
||||
selector: to.hash,
|
||||
el: to.hash,
|
||||
};
|
||||
} else if (savedPosition) {
|
||||
return savedPosition;
|
||||
} else {
|
||||
return { x: 0, y: 0 };
|
||||
return { left: 0, top: 0 };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import Vue from "vue";
|
||||
import { Module } from "vuex";
|
||||
import { get, post } from "../api";
|
||||
import { GuildState, LoadStatus, RootState } from "./types";
|
||||
|
@ -89,22 +88,18 @@ export const GuildStore: Module<GuildState, RootState> = {
|
|||
},
|
||||
|
||||
setConfig(state: GuildState, { guildId, config }) {
|
||||
Vue.set(state.configs, guildId, config);
|
||||
state.configs[guildId] = config;
|
||||
},
|
||||
|
||||
setGuildPermissionAssignments(state: GuildState, { guildId, permissionAssignments }) {
|
||||
if (!state.guildPermissionAssignments) {
|
||||
Vue.set(state, "guildPermissionAssignments", {});
|
||||
state.guildPermissionAssignments = {};
|
||||
}
|
||||
|
||||
Vue.set(
|
||||
state.guildPermissionAssignments,
|
||||
guildId,
|
||||
permissionAssignments.map((p) => ({
|
||||
...p,
|
||||
permissions: new Set(p.permissions),
|
||||
})),
|
||||
);
|
||||
state.guildPermissionAssignments[guildId] = permissionAssignments.map((p) => ({
|
||||
...p,
|
||||
permissions: new Set(p.permissions),
|
||||
}));
|
||||
},
|
||||
|
||||
setTargetPermissions(state: GuildState, { guildId, targetId, type, permissions, expiresAt }) {
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
import Vue from "vue";
|
||||
import Vuex, { Store } from "vuex";
|
||||
|
||||
Vue.use(Vuex);
|
||||
import { createStore, Store } from "vuex";
|
||||
|
||||
import { AuthStore } from "./auth";
|
||||
import { DocsStore } from "./docs";
|
||||
import { GuildStore } from "./guilds";
|
||||
import { RootState } from "./types";
|
||||
|
||||
export const RootStore = new Vuex.Store<RootState>({
|
||||
export const RootStore = createStore({
|
||||
modules: {
|
||||
auth: AuthStore,
|
||||
guilds: GuildStore,
|
||||
|
@ -17,16 +14,8 @@ export const RootStore = new Vuex.Store<RootState>({
|
|||
});
|
||||
|
||||
// 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
|
||||
declare module "vue" {
|
||||
interface ComponentCustomProperties {
|
||||
$store: Store<RootState>;
|
||||
}
|
||||
}
|
||||
|
|
5
dashboard/ts-vue-shim.d.ts
vendored
5
dashboard/ts-vue-shim.d.ts
vendored
|
@ -1,6 +1,7 @@
|
|||
declare module "*.vue" {
|
||||
import Vue from "vue";
|
||||
export default Vue;
|
||||
import { DefineComponent } from "vue";
|
||||
const component: DefineComponent;
|
||||
export default component;
|
||||
}
|
||||
|
||||
declare module "*.png" {
|
||||
|
|
|
@ -65,7 +65,12 @@ let config = {
|
|||
// Vue / Babel / Typescript
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: ["vue-loader"],
|
||||
loader: "vue-loader",
|
||||
options: {
|
||||
compilerOptions: {
|
||||
whitespace: 'preserve', // not the default despite the docs saying so
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
|
|
3550
package-lock.json
generated
3550
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue