266 lines
7.2 KiB
Vue
266 lines
7.2 KiB
Vue
<template>
|
|
<div class="tabletop-form">
|
|
<v-row dense>
|
|
<v-col
|
|
cols="12"
|
|
md="6"
|
|
>
|
|
<text-field
|
|
label="Name"
|
|
:value="model.name"
|
|
:error-messages="errors.name"
|
|
:disabled="!editPermission"
|
|
@change="(value, ack) => change('name', value, ack)"
|
|
/>
|
|
</v-col>
|
|
<v-col
|
|
cols="12"
|
|
md="6"
|
|
>
|
|
<text-field
|
|
label="Picture URL"
|
|
hint="A link to a cover image for this tabletop"
|
|
:disabled="!editPermission"
|
|
:value="model.imageUrl"
|
|
:error-messages="errors.imageUrl"
|
|
@change="(value, ack) => change('imageUrl', value, ack)"
|
|
/>
|
|
</v-col>
|
|
<v-col
|
|
cols="12"
|
|
>
|
|
<text-area
|
|
label="Description"
|
|
:value="model.description"
|
|
:disabled="!editPermission"
|
|
@change="(value, ack) => change('description', value, ack)"
|
|
/>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<form-sections type="tabletop">
|
|
<form-section name="Sharing">
|
|
<v-row>
|
|
<v-col
|
|
cols="12"
|
|
md="6"
|
|
>
|
|
<smart-select
|
|
label="Who can view"
|
|
:items="[
|
|
{text: 'Only people I share with', value: 'false'},
|
|
{text: 'Anyone with link', value: 'true'}
|
|
]"
|
|
:value="!!model.public + ''"
|
|
@change="(value, ack) => change('public', value === 'true', ack)"
|
|
/>
|
|
</v-col>
|
|
<v-col
|
|
v-if="model.public"
|
|
cols="12"
|
|
md="6"
|
|
>
|
|
<text-field
|
|
readonly
|
|
label="Link"
|
|
:value="link"
|
|
/>
|
|
</v-col>
|
|
|
|
<v-col
|
|
cols="12"
|
|
class="mb-4 px-4"
|
|
>
|
|
<h3 class="mb-4">
|
|
Add user
|
|
</h3>
|
|
<text-field
|
|
label="Username or email"
|
|
:value="userSearched"
|
|
:debounce-time="300"
|
|
:disabled="!editPermission"
|
|
@change="(value, ack) => getUser({value, ack})"
|
|
/>
|
|
<smart-select
|
|
label="Permission"
|
|
:items="[
|
|
{text: 'Game Master', value: 'gameMaster'},
|
|
{text: 'Player', value: 'player'},
|
|
{text: 'Spectator', value: 'spectator'},
|
|
]"
|
|
:value="newSharePermission"
|
|
:disabled="!editPermission"
|
|
@change="(value, ack) => { newSharePermission = value; ack();}"
|
|
/>
|
|
<smart-btn
|
|
class="ml-2 mt-2"
|
|
single-click
|
|
:disabled="userFoundState !== 'found' || !editPermission"
|
|
@click="ack => updateSharing(userId, newSharePermission, ack)"
|
|
>
|
|
Share
|
|
</smart-btn>
|
|
</v-col>
|
|
|
|
<property-field
|
|
name="Owner"
|
|
:cols="{cols: 12, md: 6}"
|
|
>
|
|
{{ users.owner.username || users.owner._id || '' }}
|
|
</property-field>
|
|
<v-col
|
|
v-if="users.gameMasters.length"
|
|
key="gameMasters"
|
|
cols="12"
|
|
md="6"
|
|
class="mb-4"
|
|
>
|
|
<outlined-input name="Game Masters">
|
|
<tabletop-user-list
|
|
:users="users.gameMasters"
|
|
:edit-permission="editPermission"
|
|
:owner="model.owner"
|
|
role="gameMaster"
|
|
@set-role="e => $emit('update-sharing', e)"
|
|
/>
|
|
</outlined-input>
|
|
</v-col>
|
|
|
|
<v-col
|
|
v-if="users.players.length"
|
|
key="players"
|
|
cols="12"
|
|
md="6"
|
|
class="mb-4"
|
|
>
|
|
<outlined-input name="Players">
|
|
<tabletop-user-list
|
|
:users="users.players"
|
|
:edit-permission="editPermission"
|
|
:owner="model.owner"
|
|
role="player"
|
|
@set-role="e => $emit('update-sharing', e)"
|
|
/>
|
|
</outlined-input>
|
|
</v-col>
|
|
|
|
<v-col
|
|
v-if="users.spectators.length"
|
|
key="spectators"
|
|
cols="12"
|
|
md="6"
|
|
class="mb-4"
|
|
>
|
|
<outlined-input name="Spectators">
|
|
<tabletop-user-list
|
|
:users="users.spectators"
|
|
:edit-permission="editPermission"
|
|
:owner="model.owner"
|
|
role="spectator"
|
|
@set-role="e => $emit('update-sharing', e)"
|
|
/>
|
|
</outlined-input>
|
|
</v-col>
|
|
</v-row>
|
|
</form-section>
|
|
</form-sections>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="js">
|
|
import OutlinedInput from '/imports/client/ui/properties/viewers/shared/OutlinedInput.vue';
|
|
import TabletopUserList from '/imports/client/ui/tabletop/TabletopUserList.vue';
|
|
import PropertyField from '/imports/client/ui/properties/viewers/shared/PropertyField.vue';
|
|
import FormSection, { FormSections } from '/imports/client/ui/properties/forms/shared/FormSection.vue';
|
|
|
|
export default {
|
|
name: 'TabletopViewer',
|
|
components: {
|
|
OutlinedInput,
|
|
TabletopUserList,
|
|
PropertyField,
|
|
FormSection,
|
|
FormSections,
|
|
},
|
|
props: {
|
|
model: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
errors: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
editPermission: {
|
|
type: Boolean,
|
|
required: true,
|
|
},
|
|
users: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
newSharePermission: 'player',
|
|
userSearched: undefined,
|
|
userFoundState: 'idle',
|
|
userId: undefined,
|
|
};
|
|
},
|
|
computed: {
|
|
link() {
|
|
return window.location.origin + this.$router.resolve({
|
|
name: 'tabletop',
|
|
params: { id: this.model._id },
|
|
}).href
|
|
}
|
|
},
|
|
methods: {
|
|
change(path, value, ack) {
|
|
this.$emit('change', { path, value, ack });
|
|
},
|
|
updateSharing(userId, role, ack) {
|
|
this.$emit('update-sharing', { userId, role, ack});
|
|
},
|
|
getUser({ value, ack }) {
|
|
this.userSearched = value;
|
|
if (!value) {
|
|
this.userFoundState = 'idle';
|
|
ack();
|
|
return;
|
|
}
|
|
Meteor.users.findUserByUsernameOrEmail.call({
|
|
usernameOrEmail: value
|
|
}, (error, result) => {
|
|
if (error) {
|
|
ack(error && error.reason || error);
|
|
this.userFoundState = 'failed';
|
|
} else {
|
|
this.userId = result;
|
|
if (result) {
|
|
if (this.users.gameMasters.includes(result)) {
|
|
this.userFoundState = 'failed';
|
|
ack('User is already a game master');
|
|
} else if (this.users.players.includes(result)) {
|
|
this.userFoundState = 'failed';
|
|
ack('User is already a player');
|
|
} else if (this.users.spectators.includes(result)) {
|
|
this.userFoundState = 'failed';
|
|
ack('User is already a spectator');
|
|
} else {
|
|
this.userFoundState = 'found';
|
|
ack();
|
|
}
|
|
} else {
|
|
this.userFoundState = 'notFound';
|
|
ack('User not found');
|
|
}
|
|
}
|
|
});
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|