2024-09-12 21:55:22 +00:00
|
|
|
<script setup>
|
|
|
|
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
|
|
|
|
2024-10-21 18:05:21 +00:00
|
|
|
import { GetItem } from './../data.js';
|
2024-10-11 22:35:06 +00:00
|
|
|
|
2024-10-24 19:04:26 +00:00
|
|
|
import { onMounted, ref, shallowRef, toRaw } from 'vue';
|
2024-10-16 11:57:33 +00:00
|
|
|
import { SetupHandle, SetSize, ResetPosition, SetMinSize, SetResizable } from '@/services/Windows';
|
2024-09-21 17:08:36 +00:00
|
|
|
import IconSelector from '@/views/partials/IconSelector.vue';
|
|
|
|
import { AddContextMenu, HideContextMenu, ShowContextMenu } from '@/services/ContextMenu';
|
|
|
|
import Tabs from '@/views/partials/Tabs.vue';
|
|
|
|
import MarkdownEditor from '@/views/partials/MarkdownEditor.vue';
|
|
|
|
import Tags from '@/views/partials/Tags.vue';
|
2024-10-18 13:11:08 +00:00
|
|
|
import Input from '@/views/partials/Input.vue';
|
|
|
|
import { GetKey, SetKey } from '@/services/Utils.js';
|
2024-10-16 11:57:33 +00:00
|
|
|
|
|
|
|
import { Global } from '@/services/PluginGlobals';
|
2024-10-18 13:11:08 +00:00
|
|
|
import Dropdown from '@/views/partials/Dropdown.vue';
|
|
|
|
import FormElement from '@/views/partials/FormElement.vue';
|
|
|
|
|
2024-09-12 21:55:22 +00:00
|
|
|
const props = defineProps(['data']);
|
|
|
|
const data = props.data;
|
2024-10-16 11:57:33 +00:00
|
|
|
const api = Global('dnd-5e').Api;
|
|
|
|
const pluginData = Global('dnd-5e').Data;
|
|
|
|
const dndModule = Global('dnd-5e').DndModule;
|
2024-09-12 21:55:22 +00:00
|
|
|
|
2024-10-11 22:35:06 +00:00
|
|
|
|
2024-09-12 21:55:22 +00:00
|
|
|
const handle = ref(null);
|
|
|
|
const item_type = ref("");
|
|
|
|
const rarity = ref(null);
|
|
|
|
const weaponType = ref(null);
|
2024-09-14 00:10:05 +00:00
|
|
|
const item_name = ref(null);
|
|
|
|
const icon_selector = ref(null);
|
2024-09-15 15:25:50 +00:00
|
|
|
const description = ref(null);
|
2024-09-21 17:08:36 +00:00
|
|
|
const properties = ref(null);
|
2024-09-23 13:24:20 +00:00
|
|
|
const quantity = ref(null);
|
|
|
|
const weight = ref(null);
|
|
|
|
const price = ref(null);
|
2024-10-18 13:11:08 +00:00
|
|
|
const item_type_name = ref("");
|
2024-09-14 00:10:05 +00:00
|
|
|
|
|
|
|
function GenRarities(){
|
|
|
|
let rarities = [];
|
|
|
|
let raritiesNames = ['', 'Common', 'Uncommon', 'Rare', 'Very Rare', 'Legendary', 'Artifact'];
|
|
|
|
raritiesNames.forEach(name => {
|
|
|
|
let lowerName = name.replace(/\s+/g, '-').toLowerCase();
|
|
|
|
rarities.push({
|
|
|
|
name: `<span class='${lowerName}'>${name}</span>`,
|
|
|
|
action: () => {
|
|
|
|
rarity.value.innerHTML = `<span class='important ${lowerName}'>${name}</span>`;
|
|
|
|
HideContextMenu();
|
|
|
|
SetParam('rarity', name);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
|
|
|
return rarities;
|
|
|
|
}
|
|
|
|
|
|
|
|
function GenTypes(list){
|
|
|
|
let types = [];
|
|
|
|
list.forEach(name => {
|
|
|
|
types.push({
|
|
|
|
name,
|
|
|
|
action: () => {
|
|
|
|
weaponType.value.innerHTML = `<span class="important">${name}</span>`;
|
|
|
|
HideContextMenu();
|
|
|
|
SetParam('weapon_type', name);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return types;
|
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
|
|
|
|
let id = data.id;
|
2024-09-14 00:10:05 +00:00
|
|
|
let concept = shallowRef({});
|
|
|
|
let oldInfo;
|
|
|
|
|
|
|
|
function Upload(){
|
2024-10-16 11:57:33 +00:00
|
|
|
let params = {id: concept.value._id};
|
2024-10-18 22:42:22 +00:00
|
|
|
dndModule.router.put('/item/update', params, {data: concept.value}).then(response => {
|
2024-10-16 20:13:56 +00:00
|
|
|
// console.log(response);
|
2024-09-14 00:10:05 +00:00
|
|
|
});
|
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
|
2024-09-14 00:10:05 +00:00
|
|
|
function SetParam(param, value){
|
2024-10-21 17:36:34 +00:00
|
|
|
SetKey(concept.value, `${param}`, value);
|
2024-09-14 00:10:05 +00:00
|
|
|
Upload();
|
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
|
2024-09-14 00:10:05 +00:00
|
|
|
function IconSelected(val){
|
|
|
|
SetParam('icon', val.selected.path);
|
|
|
|
}
|
|
|
|
|
2024-09-15 15:25:50 +00:00
|
|
|
function DescriptionChanged(text){
|
|
|
|
SetParam('description', text);
|
|
|
|
}
|
|
|
|
|
|
|
|
function PropertiesChanged(properties){
|
|
|
|
SetParam('properties', properties);
|
|
|
|
}
|
|
|
|
|
2024-09-14 00:10:05 +00:00
|
|
|
function InitValues(){
|
|
|
|
let rarities = GenRarities();
|
|
|
|
let weapon_types = GenTypes(["", "Melee", "Ranged", "Martial Melee", "Martial Ranged", "Natural", "Improvised", "Siege Weapon"]);
|
|
|
|
|
2024-10-21 17:36:34 +00:00
|
|
|
icon_selector.value.icon = GetKey(concept.value, "icon");
|
|
|
|
rarity.value.innerHTML = `<span class='important ${GetKey(concept.value, "rarity") ? GetKey(concept.value, "rarity").replace(/\s+/g, '-').toLowerCase() : ""}'>${GetKey(concept.value, "rarity")}</span>`;
|
2024-10-18 13:11:08 +00:00
|
|
|
weaponType.value.innerHTML = `<span class='important'>${GetKey(concept.value, "info.weapon_type")}</span>`;
|
2024-10-21 17:36:34 +00:00
|
|
|
description.value.text = GetKey(concept.value, "description");
|
2024-10-18 13:11:08 +00:00
|
|
|
properties.value.selected = GetKey(concept.value, "info.properties");
|
2024-10-21 17:36:34 +00:00
|
|
|
quantity.value.Set(GetKey(concept.value, "quantity"));
|
|
|
|
weight.value.Set(GetKey(concept.value, "weight"));
|
|
|
|
price.value.Set(GetKey(concept.value, "price"));
|
2024-10-18 13:11:08 +00:00
|
|
|
item_type_name.value = GetKey(concept.value, "type");
|
|
|
|
item_name.value.innerHTML = GetKey(concept.value, "name");
|
2024-09-23 13:24:20 +00:00
|
|
|
|
|
|
|
quantity.value.OnUpdate((val) => SetParam('quantity', val));
|
|
|
|
weight.value.OnUpdate((val) => SetParam('weight', val));
|
|
|
|
price.value.OnUpdate((val) => SetParam('price', val));
|
|
|
|
|
2024-09-12 21:55:22 +00:00
|
|
|
rarity.value.addEventListener("click", () => {
|
|
|
|
ShowContextMenu(rarities)
|
|
|
|
});
|
2024-09-22 15:51:04 +00:00
|
|
|
AddContextMenu(rarity.value, rarities, {dropdown: true})
|
2024-09-12 21:55:22 +00:00
|
|
|
|
|
|
|
weaponType.value.addEventListener("click", () => {
|
|
|
|
ShowContextMenu(weapon_types)
|
|
|
|
});
|
2024-09-22 15:51:04 +00:00
|
|
|
AddContextMenu(weaponType.value, weapon_types, {dropdown: true});
|
2024-09-12 21:55:22 +00:00
|
|
|
|
2024-09-14 00:10:05 +00:00
|
|
|
item_name.value.addEventListener('blur', () => {
|
|
|
|
concept.value.name = item_name.value.textContent;
|
|
|
|
Upload();
|
2024-09-12 21:55:22 +00:00
|
|
|
});
|
2024-09-14 00:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
SetupHandle(id, handle);
|
2024-09-15 15:25:50 +00:00
|
|
|
SetSize(id, {width: 600, height: 700});
|
|
|
|
SetResizable(id, true);
|
|
|
|
SetMinSize(id, {width: 400, height: 300});
|
2024-09-14 00:10:05 +00:00
|
|
|
ResetPosition(id, "center");
|
2024-10-24 19:04:26 +00:00
|
|
|
|
|
|
|
if(data.staticContent){
|
|
|
|
concept.value = toRaw(data.staticContent);
|
|
|
|
console.log(concept.value);
|
|
|
|
InitValues();
|
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
});
|
|
|
|
|
2024-10-18 13:11:08 +00:00
|
|
|
item_type.value = data.item_type;
|
|
|
|
if(data.item_create){
|
|
|
|
dndModule.router.post('/item/create', {}, {
|
|
|
|
data: {
|
|
|
|
type: data.item_type,
|
|
|
|
name: "New " + data.item_type
|
|
|
|
},
|
|
|
|
}).then(response => {
|
2024-10-18 22:42:22 +00:00
|
|
|
concept.value = response.data.data;
|
2024-10-18 13:11:08 +00:00
|
|
|
InitValues();
|
|
|
|
|
|
|
|
}).catch(err => console.log(err));
|
|
|
|
} else {
|
2024-10-24 19:04:26 +00:00
|
|
|
if(!data.staticContent){
|
|
|
|
GetItem(data.item_id).then(response => {
|
|
|
|
concept.value = response.data.data;
|
|
|
|
console.log(concept.value);
|
|
|
|
InitValues();
|
|
|
|
}).catch(err => console.log(err));
|
|
|
|
}
|
2024-10-18 13:11:08 +00:00
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div class="window-wrapper" :id="'window-wrapper-' + id">
|
|
|
|
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
|
|
|
|
|
|
|
<div class="main-container">
|
|
|
|
<div class="item-header">
|
2024-09-14 00:10:05 +00:00
|
|
|
<IconSelector :window="id" ref="icon_selector" :done="IconSelected"></IconSelector>
|
2024-09-12 21:55:22 +00:00
|
|
|
<div class="header-info">
|
|
|
|
<div class="row">
|
2024-10-18 13:11:08 +00:00
|
|
|
<h1 class="grow subsection left" contenteditable="true" spellcheck="false" ref="item_name"></h1>
|
|
|
|
<h1 class="subsection right">{{ item_type_name }}</h1>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="grow subsection center border" ref="weaponType"></div>
|
|
|
|
<div class="grow subsection center border" ref="rarity"></div>
|
2024-09-12 21:55:22 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2024-09-23 09:51:39 +00:00
|
|
|
<Tabs :rows="[
|
|
|
|
{id: 'description', value: 'general.description'},
|
|
|
|
{id: 'details', value: 'general.details'}
|
|
|
|
]">
|
2024-09-15 15:25:50 +00:00
|
|
|
<template #description>
|
|
|
|
<div class="description-container">
|
|
|
|
<div class="description-sidebar">
|
2024-09-23 13:24:20 +00:00
|
|
|
<div class="form-container">
|
2024-10-18 13:11:08 +00:00
|
|
|
<FormElement>
|
2024-09-23 13:24:20 +00:00
|
|
|
<label>{{$t('general.quantity')}}</label>
|
2024-10-18 13:11:08 +00:00
|
|
|
<Input ref="quantity"></Input>
|
|
|
|
</FormElement>
|
|
|
|
<FormElement>
|
2024-09-23 13:24:20 +00:00
|
|
|
<label>{{$t('general.weight')}}</label>
|
2024-10-18 13:11:08 +00:00
|
|
|
<Input ref="weight"></Input>
|
|
|
|
</FormElement>
|
|
|
|
<FormElement>
|
2024-09-23 13:24:20 +00:00
|
|
|
<label>{{$t('general.price')}}</label>
|
2024-10-18 13:11:08 +00:00
|
|
|
<Input ref="price"></Input>
|
|
|
|
</FormElement>
|
2024-09-23 13:24:20 +00:00
|
|
|
</div>
|
2024-09-15 15:25:50 +00:00
|
|
|
</div>
|
|
|
|
<div class="description">
|
2024-09-25 23:15:53 +00:00
|
|
|
<MarkdownEditor ref="description" :done="DescriptionChanged" :editable="true"></MarkdownEditor>
|
2024-09-15 15:25:50 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<template #details>
|
|
|
|
<h2 class="section">Properties</h2>
|
2024-10-18 13:11:08 +00:00
|
|
|
<FormElement>
|
|
|
|
<label>Properties</label>
|
|
|
|
<Tags ref="properties" :items="['Amunnition','Finesse','Heavy','Light','Loading','Range','Reach','Special','Thrown','Two-Handed','Versatile']" :done="PropertiesChanged"></Tags>
|
|
|
|
</FormElement>
|
|
|
|
<h2 class="section">Usage</h2>
|
|
|
|
<FormElement>
|
|
|
|
<label>Range</label>
|
|
|
|
<Input></Input><label>/</label><Input></Input><Dropdown :options="['ft', 'm']" :selected="'ft'"></Dropdown>
|
|
|
|
</FormElement>
|
2024-09-15 15:25:50 +00:00
|
|
|
<h2 class="section">Damage</h2>
|
2024-10-18 13:11:08 +00:00
|
|
|
<FormElement>
|
|
|
|
<label>Damage</label>
|
|
|
|
<Dropdown :options="['None','Acid','Bludgeoning','Cold','Fire','Force','Lightning','Necrotic','Piercing','Poison','Psychic','Radiant','Slashing','Thunder','Healing','Healing (Temp)']"></Dropdown>
|
|
|
|
<Input></Input>
|
|
|
|
</FormElement>
|
2024-09-15 15:25:50 +00:00
|
|
|
</template>
|
|
|
|
</Tabs>
|
2024-09-12 21:55:22 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
@mixin shadow {
|
|
|
|
-moz-box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
|
|
|
|
box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
|
|
|
|
}
|
|
|
|
|
|
|
|
@mixin panel {
|
|
|
|
@include shadow();
|
|
|
|
background-color: #1B1B1B;
|
|
|
|
border: 1px solid var(--color-border);
|
|
|
|
}
|
|
|
|
|
2024-09-15 15:25:50 +00:00
|
|
|
h2.section {
|
|
|
|
margin-left: 12px;
|
|
|
|
font-family: NodestoCapsCondensed;
|
|
|
|
font-size: 32px;
|
|
|
|
line-height: 48px;
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
|
|
|
|
.description-container {
|
|
|
|
display: flex;
|
|
|
|
height: 100%;
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
.description-sidebar {
|
2024-10-18 13:11:08 +00:00
|
|
|
max-width: 200px;
|
2024-09-15 15:25:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.description {
|
|
|
|
flex-grow: 1;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
}
|
2024-09-12 21:55:22 +00:00
|
|
|
|
|
|
|
.item-header {
|
|
|
|
display: flex;
|
|
|
|
width: 100%;
|
|
|
|
height: 88px;
|
|
|
|
padding: 10px;
|
|
|
|
background-color: #1d1d1d;
|
|
|
|
|
|
|
|
.book-info {
|
|
|
|
margin-left: 20px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.header-info {
|
|
|
|
display: flex;
|
|
|
|
flex-grow: 1;
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
margin-left: 12px;
|
|
|
|
font-family: NodestoCapsCondensed;
|
|
|
|
font-weight: lighter;
|
|
|
|
font-size: 32px;
|
|
|
|
line-height: 32px;
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.row {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.window-wrapper {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
user-select: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|