mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
First pass at /callbacks
dashboard
This commit is contained in:
parent
59ec044d04
commit
50943f01de
10 changed files with 365 additions and 104 deletions
|
@ -4,10 +4,15 @@ Default mutations
|
|||
|
||||
*/
|
||||
|
||||
import { newMutation, editMutation, removeMutation, Utils } from 'meteor/vulcan:lib';
|
||||
import { registerCallback, newMutation, editMutation, removeMutation, Utils } from 'meteor/vulcan:lib';
|
||||
import Users from 'meteor/vulcan:users';
|
||||
|
||||
export const getDefaultMutations = (collectionName, options = {}) => ({
|
||||
export const getDefaultMutations = (collectionName, options = {}) => {
|
||||
|
||||
// register callbacks for documentation purposes
|
||||
registerCollectionCallbacks(collectionName);
|
||||
|
||||
return {
|
||||
|
||||
// mutation for inserting a new document
|
||||
|
||||
|
@ -120,5 +125,92 @@ export const getDefaultMutations = (collectionName, options = {}) => ({
|
|||
},
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
const registerCollectionCallbacks = collectionName => {
|
||||
|
||||
collectionName = collectionName.toLowerCase();
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.validate`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Validate a document before insertion (can be skipped when inserting directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.before`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a new document before it's inserted in the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.after`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a new document after it's inserted in the database but *before* the mutation returns it.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.async`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
description: `Perform operations on a new document after it's inserted in the database asynchronously.`
|
||||
});
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.validate`,
|
||||
arguments: [{modifier: 'The MongoDB modifier'}, {document: 'The document being inserted'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'modifier',
|
||||
description: `Validate a document before update (can be skipped when updating directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.before`,
|
||||
arguments: [{modifier: 'The MongoDB modifier'}, {document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'modifier',
|
||||
description: `Perform operations on a document before it's updated in the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.after`,
|
||||
arguments: [{document: 'The document being inserted'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Perform operations on a document after it's updated in the database but *before* the mutation returns it.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.edit.async`,
|
||||
arguments: [{document: 'The document being updated'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
description: `Perform operations on a document after it's updated in the database asynchronously.`
|
||||
});
|
||||
|
||||
registerCallback({
|
||||
name: `${collectionName}.remove.validate`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}, {validationErrors: 'An object that can be used to accumulate validation errors'}],
|
||||
runs: 'sync',
|
||||
returns: 'document',
|
||||
description: `Validate a document before removal (can be skipped when removing directly on server).`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.remove.before`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}],
|
||||
runs: 'sync',
|
||||
returns: null,
|
||||
description: `Perform operations on a document before it's removed from the database.`
|
||||
});
|
||||
registerCallback({
|
||||
name: `${collectionName}.new.async`,
|
||||
arguments: [{document: 'The document being removed'}, {currentUser: 'The current user'}, {collection: 'The collection the document belongs to'}],
|
||||
runs: 'async',
|
||||
returns: null,
|
||||
description: `Perform operations on a document after it's removed from the database asynchronously.`
|
||||
});
|
||||
}
|
31
packages/vulcan-debug/lib/components/Callbacks.jsx
Normal file
31
packages/vulcan-debug/lib/components/Callbacks.jsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import React from 'react';
|
||||
import { FormattedMessage } from 'meteor/vulcan:i18n';
|
||||
import { registerComponent, Components } from 'meteor/vulcan:lib';
|
||||
import Callbacks from '../modules/callbacks/collection.js';
|
||||
|
||||
const CallbacksName = ({ document }) =>
|
||||
<strong>{document.name}</strong>
|
||||
|
||||
const CallbacksDashboard = props =>
|
||||
<div className="settings">
|
||||
<Components.Datatable
|
||||
showSearch={false}
|
||||
showEdit={false}
|
||||
collection={Callbacks}
|
||||
options={{
|
||||
fragmentName: 'CallbacksFragment'
|
||||
}}
|
||||
columns={[
|
||||
{ name: 'name', component: CallbacksName },
|
||||
'arguments',
|
||||
'returns',
|
||||
'runs',
|
||||
'description',
|
||||
'hooks',
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
registerComponent('Callbacks', CallbacksDashboard);
|
||||
|
||||
export default Callbacks;
|
19
packages/vulcan-debug/lib/modules/callbacks/collection.js
Normal file
19
packages/vulcan-debug/lib/modules/callbacks/collection.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { createCollection } from 'meteor/vulcan:lib';
|
||||
import schema from './schema.js';
|
||||
import resolvers from './resolvers.js';
|
||||
import './fragments.js';
|
||||
|
||||
const Callbacks = createCollection({
|
||||
|
||||
collectionName: 'Callbacks',
|
||||
|
||||
typeName: 'Callback',
|
||||
|
||||
schema,
|
||||
|
||||
resolvers,
|
||||
|
||||
});
|
||||
|
||||
|
||||
export default Callbacks;
|
12
packages/vulcan-debug/lib/modules/callbacks/fragments.js
Normal file
12
packages/vulcan-debug/lib/modules/callbacks/fragments.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { registerFragment } from 'meteor/vulcan:lib';
|
||||
|
||||
registerFragment(`
|
||||
fragment CallbacksFragment on Callback {
|
||||
name
|
||||
arguments
|
||||
runs
|
||||
returns
|
||||
description
|
||||
hooks
|
||||
}
|
||||
`);
|
26
packages/vulcan-debug/lib/modules/callbacks/resolvers.js
Normal file
26
packages/vulcan-debug/lib/modules/callbacks/resolvers.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { CallbackHooks } from 'meteor/vulcan:lib';
|
||||
|
||||
const resolvers = {
|
||||
|
||||
list: {
|
||||
|
||||
name: 'CallbacksList',
|
||||
|
||||
resolver(root, {terms = {}}, context, info) {
|
||||
return CallbackHooks;
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
total: {
|
||||
|
||||
name: 'CallbacksTotal',
|
||||
|
||||
resolver(root, {terms = {}}, context) {
|
||||
return CallbackHooks.length;
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
export default resolvers;
|
63
packages/vulcan-debug/lib/modules/callbacks/schema.js
Normal file
63
packages/vulcan-debug/lib/modules/callbacks/schema.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { Callbacks } from 'meteor/vulcan:lib';
|
||||
|
||||
const schema = {
|
||||
|
||||
name: {
|
||||
label: 'Name',
|
||||
type: String,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
arguments: {
|
||||
label: 'Arguments',
|
||||
type: Array,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
'arguments.$': {
|
||||
type: Object,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
runs: {
|
||||
label: 'Runs',
|
||||
type: String,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
returns: {
|
||||
label: 'Should Return',
|
||||
type: String,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
description: {
|
||||
label: 'Description',
|
||||
type: String,
|
||||
viewableBy: ['admins'],
|
||||
},
|
||||
|
||||
hooks: {
|
||||
label: 'Hooks',
|
||||
type: Array,
|
||||
viewableBy: ['admins'],
|
||||
resolveAs: {
|
||||
type: '[String]',
|
||||
resolver: (callback) => {
|
||||
console.log('// callback')
|
||||
console.log(callback)
|
||||
console.log(Callbacks[callback.name])
|
||||
if (Callbacks[callback.name]) {
|
||||
const callbacks = Callbacks[callback.name].map(f => f.name);
|
||||
console.log(callbacks)
|
||||
return callbacks;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default schema;
|
|
@ -2,3 +2,4 @@
|
|||
import '../components/Emails.jsx';
|
||||
import '../components/Groups.jsx';
|
||||
import '../components/Settings.jsx';
|
||||
import '../components/Callbacks.jsx';
|
||||
|
|
|
@ -4,6 +4,7 @@ addRoute([
|
|||
// {name: 'cheatsheet', path: '/cheatsheet', component: import('./components/Cheatsheet.jsx')},
|
||||
{name: 'groups', path: '/groups', component: () => getDynamicComponent(import('../components/Groups.jsx'))},
|
||||
{name: 'settings', path: '/settings', componentName: 'Settings'},
|
||||
{name: 'settings', path: '/callbacks', componentName: 'Callbacks'},
|
||||
// {name: 'emails', path: '/emails', component: () => getDynamicComponent(import('./components/Emails.jsx'))},
|
||||
{name: 'emails', path: '/emails', componentName: 'Emails'},
|
||||
]);
|
|
@ -1,11 +1,26 @@
|
|||
import { debug } from './debug.js';
|
||||
|
||||
/**
|
||||
* @summary A list of all registered callback hooks
|
||||
*/
|
||||
export const CallbackHooks = [];
|
||||
|
||||
/**
|
||||
* @summary Callback hooks provide an easy way to add extra steps to common operations.
|
||||
* @namespace Callbacks
|
||||
*/
|
||||
export const Callbacks = {};
|
||||
|
||||
|
||||
/**
|
||||
* @summary Register a callback
|
||||
* @param {String} hook - The name of the hook
|
||||
* @param {Function} callback - The callback function
|
||||
*/
|
||||
export const registerCallback = function (callback) {
|
||||
CallbackHooks.push(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Add a callback function to a hook
|
||||
* @param {String} hook - The name of the hook
|
||||
|
|
|
@ -220,6 +220,7 @@ export const removeMutation = async ({ collection, documentId, currentUser, vali
|
|||
}
|
||||
}
|
||||
|
||||
await runCallbacks(`${collectionName}.remove.before`, document, currentUser);
|
||||
await runCallbacks(`${collectionName}.remove.sync`, document, currentUser);
|
||||
|
||||
collection.remove(documentId);
|
||||
|
|
Loading…
Add table
Reference in a new issue