Midsd
This commit is contained in:
parent
ede69a2a7a
commit
8581fb9314
@ -1,5 +1,6 @@
|
||||
const Campaign = require("../models/Campaign");
|
||||
const CampaignUser = require("../models/CampaignUser");
|
||||
const User = require("../models/User");
|
||||
|
||||
function hasCampaign(req, res, next){
|
||||
Campaign.findById(req.query.campaign).lean().then((campaign) => {
|
||||
@ -16,11 +17,17 @@ function hasCampaign(req, res, next){
|
||||
}).catch((err) => res.json({status: "error", err}));
|
||||
}
|
||||
|
||||
function hasUser(req, res, next){
|
||||
|
||||
function isAdmin(req, res, next){
|
||||
User.findOne(req.user).lean().then((user) => {
|
||||
if(user.admin){
|
||||
next();
|
||||
return;
|
||||
}
|
||||
res.json({status: "error", msg: "unauthorized"});
|
||||
}).catch((err) => res.json({status: "error", err}));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hasCampaign,
|
||||
hasUser
|
||||
isAdmin
|
||||
}
|
17
backend/routes/admin.js
Normal file
17
backend/routes/admin.js
Normal file
@ -0,0 +1,17 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const { isAdmin } = require('../config/middleware');
|
||||
const User = require("../models/User");
|
||||
|
||||
router.get('/users', isAdmin, (req, res) => {
|
||||
console.log("HJDSHAKJDHKH")
|
||||
User.find({}).then((users) => {
|
||||
console.log("HJDSHAKJDHKH2")
|
||||
res.json({
|
||||
users
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
module.exports = router;
|
@ -1,10 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const passport = require('passport');
|
||||
|
||||
const Campaign = require("../models/Campaign");
|
||||
const CampaignUser = require("../models/CampaignUser");
|
||||
const Concept = require('../models/Concept');
|
||||
const { hasCampaign } = require('../config/middleware');
|
||||
const { getIo } = require('../io/socket');
|
||||
|
@ -73,6 +73,7 @@ app.use(checkAuth);
|
||||
app.use('/campaign', require('./routes/campaign'));
|
||||
app.use('/maps', require('./routes/map'))
|
||||
app.use('/concept', require('./routes/concept'))
|
||||
app.use('/admin', require('./routes/admin'))
|
||||
// GET localhost:8081/concept/list
|
||||
|
||||
// SETUP IO
|
||||
|
@ -221,6 +221,11 @@ button:active {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.document.centered {
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.document.item {
|
||||
text-align: center;
|
||||
width: 220px;
|
||||
|
@ -23,11 +23,14 @@ async function FetchPlugins(){
|
||||
name: pluginData.name,
|
||||
_id: pluginName,
|
||||
info: {
|
||||
|
||||
name: pluginData.name,
|
||||
description: pluginData.description,
|
||||
authors: pluginData.authors,
|
||||
version: pluginData.version,
|
||||
}
|
||||
});
|
||||
|
||||
import(/* @vite-ignore */ `../../plugins/${pluginName}/${pluginData.entrypoint}`).then(module => {
|
||||
import(/* @vite-ignore */ `../../plugins/${pluginName}/${pluginData.client.entrypoint}`).then(module => {
|
||||
module.Main({
|
||||
Dragonroll,
|
||||
Chat,
|
||||
|
@ -29,6 +29,7 @@ import IconSelectorWindow from '@/views/windows/selectors/IconSelectorWindow.vue
|
||||
import DatabaseWindow from '@/views/windows/game/DatabaseWindow.vue'
|
||||
import AccountManagementWindow from '@/views/windows/settings/AccountManagementWindow.vue'
|
||||
import PluginManagementWindow from '@/views/windows/settings/PluginManagementWindow.vue'
|
||||
import PluginWindow from '../views/windows/settings/PluginWindow.vue';
|
||||
|
||||
let windowMap = {
|
||||
test: ExampleWindow,
|
||||
@ -56,7 +57,8 @@ let windowMap = {
|
||||
icon_selector: IconSelectorWindow,
|
||||
database: DatabaseWindow,
|
||||
plugin_management: PluginManagementWindow,
|
||||
account_management: AccountManagementWindow
|
||||
account_management: AccountManagementWindow,
|
||||
plugin_window: PluginWindow
|
||||
};
|
||||
|
||||
async function InjectWindow(plugin, window_type, window_component){
|
||||
|
22
client/src/views/partials/BigIconTemplate.vue
Normal file
22
client/src/views/partials/BigIconTemplate.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
const props = defineProps(['title', 'img']);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="document centered">
|
||||
<h1>{{props.title}}</h1>
|
||||
<img :src="props.img" class="big-icon">
|
||||
<br>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.big-icon {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 16px;
|
||||
margin:auto;
|
||||
}
|
||||
</style>
|
@ -11,15 +11,15 @@ const elementDiv = ref(null);
|
||||
const tooltipContainer = ref(null);
|
||||
const icon = ref("icons/game-icons/ffffff/lorc/crossed-swords.svg")
|
||||
|
||||
function updateElement(){
|
||||
async function updateElement(){
|
||||
element.value = props.element;
|
||||
// Do whatever
|
||||
let desc = element.value.info.description;
|
||||
desc = desc ? marked.parse(desc) : '';
|
||||
|
||||
if(props.icon) icon.value = props.icon(element.value);
|
||||
if(props.icon) icon.value = await props.icon(element.value);
|
||||
|
||||
let tooltip = props.tooltip(element.value);
|
||||
let tooltip = await props.tooltip(element.value);
|
||||
if(tooltip) AddTooltip(tooltipContainer.value, tooltip);
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,9 @@ function onLeave(el, done) {
|
||||
<ConceptEntry class="list-element" v-for="(element, index) in elements"
|
||||
:key="element._id"
|
||||
:element="element"
|
||||
:context="() => ContextElement(element)"
|
||||
:tooltip="(el) => TooltipElement(el)"
|
||||
:icon="(el) => IconElement(el)"
|
||||
:context="async () => await ContextElement(element)"
|
||||
:tooltip="async (el) => await TooltipElement(el)"
|
||||
:icon="async (el) => await IconElement(el)"
|
||||
v-on:click.prevent="OpenElement(element)"
|
||||
:data-index="index"></ConceptEntry>
|
||||
</TransitionGroup>
|
||||
|
@ -39,7 +39,6 @@ function OpenCreateItemPrompt(){
|
||||
|
||||
|
||||
function OpenConcept(element){
|
||||
console.log(`${GetCampaignModuleName()}/item_sheet`);
|
||||
CreateWindow(`${GetCampaignModuleName()}/item_sheet`, {
|
||||
id: 'item_sheet_' + element._id,
|
||||
title: 'Edit Item',
|
||||
@ -49,7 +48,6 @@ function OpenConcept(element){
|
||||
}
|
||||
|
||||
function ElementContext(element){
|
||||
console.log(element);
|
||||
return [
|
||||
{name: "Open"},
|
||||
{name: "Delete"}
|
||||
|
@ -1,8 +1,13 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, shallowRef } from 'vue';
|
||||
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
import Api from '@/services/Api'
|
||||
|
||||
import IconButton from '@/views/partials/game/IconButton.vue'
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
import ConceptList from '../../partials/ConceptList.vue';
|
||||
import { backendUrl } from '../../../services/BackendURL';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
@ -11,13 +16,32 @@ const data = props.data;
|
||||
|
||||
let id = data.id;
|
||||
|
||||
const test = ref(null)
|
||||
const elements = shallowRef([]);
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {width: 500, height: 380});
|
||||
ResetPosition(id, "center");
|
||||
|
||||
Api().get('/admin/users').then(response => {
|
||||
let users = response.data.users;
|
||||
elements.value = [];
|
||||
users.forEach(user => {
|
||||
elements.value.push({
|
||||
name: user.username,
|
||||
_id: user._id,
|
||||
info: {
|
||||
name: user.username
|
||||
}
|
||||
})
|
||||
});
|
||||
}).catch((err) => console.log(err));
|
||||
});
|
||||
|
||||
async function ElementIcon(element){
|
||||
let response = await Api().get('/user/retrieve-avatar?username=' + element.name);
|
||||
if(response.data.image) return backendUrl + "public/" + response.data.image;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -26,8 +50,14 @@ onMounted(() => {
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<!-- Body -->
|
||||
<div ref="test"></div>
|
||||
<ConceptList
|
||||
:elements="elements"
|
||||
:icon="ElementIcon"
|
||||
></ConceptList>
|
||||
|
||||
<div class="fixed-bottom-buttons">
|
||||
<IconButton icon="/icons/iconoir/regular/plus.svg" :action="OpenCreateItemPrompt"></IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -37,6 +67,14 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fixed-bottom-buttons {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
import ConceptList from '../../partials/ConceptList.vue';
|
||||
import { _GetPlugins } from '../../../services/Plugins';
|
||||
import { SetMinSize, SetResizable } from '../../../services/Windows';
|
||||
import { ClearWindow, CreateChildWindow, SetMinSize, SetResizable } from '../../../services/Windows';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
@ -32,6 +32,16 @@ onMounted(() => {
|
||||
function GetPluginIcon(plugin){
|
||||
return `/plugins/${plugin._id}/icon.png`;
|
||||
}
|
||||
|
||||
function OpenPlugin(plugin){
|
||||
CreateChildWindow(id, '', {
|
||||
type: 'plugin_window',
|
||||
id: 'plugin-window-' + plugin._id,
|
||||
title: plugin.name,
|
||||
plugin,
|
||||
close: () => ClearWindow('plugin-window-' + plugin._id)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -43,6 +53,7 @@ function GetPluginIcon(plugin){
|
||||
<ConceptList
|
||||
:elements="elements"
|
||||
:icon="GetPluginIcon"
|
||||
:open="OpenPlugin"
|
||||
></ConceptList>
|
||||
</div>
|
||||
</template>
|
||||
|
42
client/src/views/windows/settings/PluginWindow.vue
Normal file
42
client/src/views/windows/settings/PluginWindow.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
import BigIconTemplate from '../../partials/BigIconTemplate.vue';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
let id = data.id;
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {width: 500, height: 380});
|
||||
ResetPosition(id, "center");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="window-wrapper" :id="'window-wrapper-' + id">
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<!-- Body -->
|
||||
<BigIconTemplate :title="data.plugin.name" :img="`plugins/${data.plugin._id}/icon.png`">
|
||||
|
||||
</BigIconTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.window-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -14,7 +14,7 @@ function Main(Api){
|
||||
"name": "Aran Roig"
|
||||
}
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"version": "0.1",
|
||||
"color": "#e92026"
|
||||
});
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "Dnd 5e System",
|
||||
"entrypoint": "main.js"
|
||||
}
|
@ -4,6 +4,7 @@ import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
import { ClearWindow, CreateWindow } from '@/services/Windows';
|
||||
import { GetCampaignModuleName } from '../../../../client/src/services/Campaign';
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
@ -23,7 +24,7 @@ function ConfirmSelection(){
|
||||
if(!selected) return;
|
||||
let value = selected.value;
|
||||
|
||||
CreateWindow('item_sheet', {
|
||||
CreateWindow(`${GetCampaignModuleName()}/item_sheet`, {
|
||||
id: 'item_sheet',
|
||||
title: 'Edit Item',
|
||||
item_type: value,
|
||||
|
13
plugins/dnd-5e/plugin.json
Normal file
13
plugins/dnd-5e/plugin.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Dnd 5e System",
|
||||
"description": "This plugin provides the Dnd 5e module",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aran Roig"
|
||||
}
|
||||
],
|
||||
"version": "0.1",
|
||||
"client": {
|
||||
"entrypoint": "main.js"
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "Dragonroll example plugin",
|
||||
"entrypoint": "main.js"
|
||||
}
|
13
plugins/example/plugin.json
Normal file
13
plugins/example/plugin.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Dragonroll example plugin",
|
||||
"description": "This is an example plugin to help you getting started with the Dragonroll API",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aran Roig"
|
||||
}
|
||||
],
|
||||
"version": "0.1",
|
||||
"client": {
|
||||
"entrypoint": "main.js"
|
||||
}
|
||||
}
|
@ -94,6 +94,7 @@ console.log("Updated Locales")
|
||||
for(let j = 0; j < plugins.length; j++){
|
||||
if(fs.existsSync(`./plugins/${plugins[j]}/client/`)){
|
||||
fs.cpSync(`./plugins/${plugins[j]}/client/`, `./client/plugins/${plugins[j]}`, {recursive: true});
|
||||
fs.copyFileSync(`./plugins/${plugins[j]}/plugin.json`, `./client/plugins/${plugins[j]}/plugin.json`);
|
||||
}
|
||||
|
||||
if(fs.existsSync(`./plugins/${plugins[j]}/public/`)){
|
||||
|
Loading…
Reference in New Issue
Block a user