Improved sharing dialog, setting a sheet as public now working
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import '/imports/api/sharing/sharing.js';
|
||||
|
||||
let SharingSchema = new SimpleSchema({
|
||||
owner: {
|
||||
@@ -28,7 +29,7 @@ let SharingSchema = new SimpleSchema({
|
||||
},
|
||||
public: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
defaultValue: false,
|
||||
index: 1,
|
||||
},
|
||||
});
|
||||
|
||||
20
app/imports/api/sharing/sharing.js
Normal file
20
app/imports/api/sharing/sharing.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { assertOwnership } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
|
||||
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
|
||||
import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
|
||||
|
||||
const setPublic = new ValidatedMethod({
|
||||
name: 'sharing.methods.setPublic',
|
||||
validate: new SimpleSchema({
|
||||
docRef: RefSchema,
|
||||
public: { type: Boolean },
|
||||
}).validator(),
|
||||
run({docRef, public}){
|
||||
let doc = fetchDocByRef(docRef);
|
||||
assertOwnership(doc, this.userId);
|
||||
getCollectionByName(docRef.collection).update(docRef.id, {$set: {public}});
|
||||
},
|
||||
});
|
||||
|
||||
export { setPublic };
|
||||
@@ -134,8 +134,9 @@ Meteor.users.findUserByUsernameOrEmail = new ValidatedMethod({
|
||||
},
|
||||
}).validator(),
|
||||
run({usernameOrEmail}){
|
||||
let user = Accounts.findUserByUsername(username) ||
|
||||
Accounts.findUserByEmail(email);
|
||||
if (Meteor.isClient) return;
|
||||
let user = Accounts.findUserByUsername(usernameOrEmail) ||
|
||||
Accounts.findUserByEmail(usernameOrEmail);
|
||||
return user && user._id;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -71,7 +71,14 @@ export default {
|
||||
this.loading = false;
|
||||
this.dirty = false;
|
||||
this.error = !!error;
|
||||
this.ackErrors = error || null;
|
||||
if (!error){
|
||||
this.ackErrors = null;
|
||||
} else if (typeof error === 'string'){
|
||||
this.ackErrors = error;
|
||||
} else {
|
||||
this.ackErrors = 'Something went wrong'
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
change(val){
|
||||
this.dirty = true;
|
||||
|
||||
@@ -9,9 +9,30 @@
|
||||
</v-btn>
|
||||
<span>{{character.name}}</span>
|
||||
<v-spacer/>
|
||||
<v-btn flat icon @click="showCharacterForm" data-id="character-form-button">
|
||||
<v-icon>more</v-icon>
|
||||
</v-btn>
|
||||
<v-menu bottom left transition="slide-y-transition" data-id="creature-menu">
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn icon v-on="on">
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-tile @click="deleteCharacter">
|
||||
<v-list-tile-title>
|
||||
<v-icon>delete</v-icon> Delete
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showCharacterForm">
|
||||
<v-list-tile-title>
|
||||
<v-icon>create</v-icon> Edit details
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showShareDialog">
|
||||
<v-list-tile-title>
|
||||
<v-icon>share</v-icon> Sharing
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-tabs
|
||||
slot="extension"
|
||||
v-model="tab"
|
||||
@@ -81,12 +102,27 @@
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'character-form-button',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
showShareDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'share-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
docRef: {
|
||||
id: this.creatureId,
|
||||
collection: 'creatures',
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
deleteCharacter(){
|
||||
console.log('todo');
|
||||
},
|
||||
isDarkColor,
|
||||
},
|
||||
meteor: {
|
||||
|
||||
@@ -10,6 +10,7 @@ import FeatureDialogContainer from '/imports/ui/properties/features/FeatureDialo
|
||||
import LibraryCreationDialog from '/imports/ui/library/LibraryCreationDialog.vue';
|
||||
import LibraryNodeCreationDialog from '/imports/ui/library/LibraryNodeCreationDialog.vue';
|
||||
import LibraryNodeEditDialog from '/imports/ui/library/LibraryNodeEditDialog.vue';
|
||||
import ShareDialog from '/imports/ui/sharing/ShareDialog.vue';
|
||||
import SkillDialogContainer from '/imports/ui/properties/skills/SkillDialogContainer.vue';
|
||||
|
||||
export default {
|
||||
@@ -25,5 +26,6 @@ export default {
|
||||
LibraryCreationDialog,
|
||||
LibraryNodeCreationDialog,
|
||||
LibraryNodeEditDialog,
|
||||
ShareDialog,
|
||||
SkillDialogContainer,
|
||||
};
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
<template lang="html">
|
||||
<dialog-base>
|
||||
<div slot="toolbar">
|
||||
Sharing {{name}}
|
||||
Sharing
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="model">
|
||||
<smart-select
|
||||
label="Who can view"
|
||||
:items="[
|
||||
{text: 'Only people I share with', value: false},
|
||||
{text: 'Anyone with link', value: true}
|
||||
{text: 'Only people I share with', value: 'false'},
|
||||
{text: 'Anyone with link', value: 'true'}
|
||||
]"
|
||||
:value="model.public"
|
||||
:error-messages="errors.public"
|
||||
:value="!!model.public + ''"
|
||||
@change="(value, ack) => setSheetPublic({value, ack})"
|
||||
/>
|
||||
<div class="layout row">
|
||||
<text-field
|
||||
label="Username or email"
|
||||
:value="userSearched"
|
||||
@change="(value, ack) => getUser({value, ack})"
|
||||
:debounceTime="300"
|
||||
/>
|
||||
<v-btn :disabled="userFoundState !== found">
|
||||
<v-btn :disabled="userFoundState !== 'found'">
|
||||
Share
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="sharedWith">
|
||||
<h3>Can Edit</h3>
|
||||
<div v-for="userId in model.writers">
|
||||
{{username(userId)}}
|
||||
<h3 v-if="writers.length">Can Edit</h3>
|
||||
<div v-for="user in writers">
|
||||
{{user}}
|
||||
<v-btn flat icon>
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<h3>Can View</h3>
|
||||
<div v-for="userId in model.readers">
|
||||
{{username(userId)}}
|
||||
<h3 v-if="readers.length">Can View</h3>
|
||||
<div v-for="user in readers">
|
||||
{{user}}
|
||||
<v-btn flat icon>
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
@@ -45,21 +45,38 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setPublic } from '/imports/api/sharing/sharing.js';
|
||||
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DialogBase,
|
||||
},
|
||||
data(){ return {
|
||||
userSearched: undefined,
|
||||
userFoundState: 'idle',
|
||||
userId: undefined,
|
||||
}},
|
||||
props: {
|
||||
ref: Object,
|
||||
docRef: Object,
|
||||
},
|
||||
methods: {
|
||||
setSheetPublic({value, ack}){
|
||||
setPublic.call({
|
||||
docRef: this.docRef,
|
||||
public: value === 'true',
|
||||
}, (error, value) => {
|
||||
ack(error && error.reason || error);
|
||||
});
|
||||
},
|
||||
getUser({value, ack}){
|
||||
this.userSearched = value;
|
||||
if (!value){
|
||||
this.userFoundState = 'idle';
|
||||
ack();
|
||||
return;
|
||||
}
|
||||
Meteor.users.findUserByUsernameOrEmail.call({
|
||||
usernameOrEmail: value
|
||||
}, (error, result) => {
|
||||
@@ -69,8 +86,13 @@ export default {
|
||||
} else {
|
||||
this.userId = result;
|
||||
if (result){
|
||||
this.userFoundState = 'found';
|
||||
ack();
|
||||
if (result === this.model.owner){
|
||||
this.userFoundState = 'failed';
|
||||
ack('User is already the owner')
|
||||
} else {
|
||||
this.userFoundState = 'found';
|
||||
ack();
|
||||
}
|
||||
} else {
|
||||
this.userFoundState = 'notFound';
|
||||
ack('User not found');
|
||||
@@ -81,15 +103,26 @@ export default {
|
||||
},
|
||||
meteor: {
|
||||
model(){
|
||||
return fetchDocByRef(this.ref);
|
||||
if (!this.docRef || !this.docRef.id) return;
|
||||
let model = fetchDocByRef(this.docRef);
|
||||
console.log({model})
|
||||
return model;
|
||||
},
|
||||
username(userId){
|
||||
let user = Meteor.users.findOne(userId);
|
||||
return user && user.username;
|
||||
readers(){
|
||||
if (this.model){
|
||||
return Meteor.users.find({_id: {$in: this.model.readers}})
|
||||
}
|
||||
},
|
||||
writers(){
|
||||
if (this.model){
|
||||
return Meteor.users.find({_id: {$in: this.model.writers}})
|
||||
}
|
||||
},
|
||||
$subscribe: {
|
||||
'userPublicProfiles'(){
|
||||
return [...this.model.writers, ...this.model.readers];
|
||||
let model = this.model;
|
||||
if (!model) return false;
|
||||
return [model.owner, ...model.writers, ...model.readers];
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user