Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GraphQL Operations for Event #66

Closed
64 changes: 64 additions & 0 deletions server/schema/event/event.mutation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* @module app.schema.EventMutation
* @description Event Mutation
*
* @requires module:app.schema.scalars
*
* @version v1
* @since 0.1.0
*/

const {
GraphQLObjectType,
GraphQLString,
// GraphQLSchema,
GraphQLID,
//GraphQLList,
// GraphQLBoolean,
GraphQLInt,
GraphQLNonNull,
// GraphQLDate,
// GraphQLTime,
GraphQLDateTime,
//GraphQLJSON,
//GraphQLJSONObject,
} = require('../scalars');
const { createEvent, updateEvent } = require('./event.resolver');
const EventType = require('./event.type');

module.exports = new GraphQLObjectType({
rutajdash marked this conversation as resolved.
Show resolved Hide resolved
name: 'EventMutation',
fields: {
createEvent: {
description: 'Creates an event',
type: EventType,
args: {
name: { type: GraphQLNonNull(GraphQLString) },
startTS: { type: GraphQLNonNull(GraphQLDateTime) },
endTS: { type: GraphQLNonNull(GraphQLDateTime) },
poster: { type: GraphQLID },
type: { type: GraphQLInt, description: '0- Club, 1- Institute, 2- Fest, 3- Holiday' },
host: { type: GraphQLID },
url: { type: GraphQLString },
venue: { type: GraphQLNonNull(GraphQLString) },
},
resolve: createEvent,
},
updateEvent: {
description: 'Updates a pre-existing event',
type: EventType,
args: {
id:{type: GraphQLID},
name: { type: GraphQLString },
startTS: { type: GraphQLDateTime },
endTS: { type: GraphQLDateTime },
poster: { type: GraphQLID },
type: { type: GraphQLInt },
host: { type: GraphQLID },
url: { type: GraphQLString },
venue: { type: GraphQLString },
},
resolve: updateEvent,
},
},
});
59 changes: 59 additions & 0 deletions server/schema/event/event.query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @module app.schema.EventQuery
* @description Event Query
*
* @requires module:app.schema.scalars
*
* @version v1
* @since 0.1.0
*/

const {
GraphQLObjectType,
GraphQLString,
// GraphQLSchema,
GraphQLID,
GraphQLList,
// GraphQLBoolean,
// GraphQLInt,
GraphQLNonNull,
// GraphQLDate,
// GraphQLTime,
// GraphQLDateTime,
// GraphQLJSON,
// GraphQLJSONObject,
} = require('../scalars');
const EventType = require('./event.type');
const { getEvent, listEvents, searchEvents } = require('./event.resolver');
rutajdash marked this conversation as resolved.
Show resolved Hide resolved

module.exports = new GraphQLObjectType({
name: 'EventQuery',
fields: {
getEvent: {
description: 'Retrieves a single event',
type: EventType,
args: {
id: {
type: GraphQLNonNull(GraphQLID),
description: "The event's mongo ID.",
},
},
resolve: getEvent,
rutajdash marked this conversation as resolved.
Show resolved Hide resolved
},
listEvents: {
type: GraphQLList(EventType),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add description

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

resolve: listEvents,
},
searchEvents: {
description: 'Searches a event for keywords',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: 'Searches a event for keywords',
description: 'Searches a event by keywords',

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

type: GraphQLList(EventType),
args: {
keywords: {
description: 'The search keywords',
type: new GraphQLNonNull(GraphQLString),
},
},
resolve: searchEvents,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this resolver not yet done?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seach events isn't being done rn as @rutajdash told the approach we though of following was very expensive. After we decide on how to do it, it'll be done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a TODO or create an issue

},
},
});
132 changes: 132 additions & 0 deletions server/schema/event/event.resolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* @module app.schema.EventResolver
* @description Event Resolver
*
* @requires module:app.schema.EventType
* @requires module:app.schema.EventModel
* @requires module:app.authorization
* @version v1
* @since 0.1.0
*/

const { GraphQLError, APIError } = require('../../helpers/errorHandler');
const { Model } = require('mongoose');

/**
* @type {Model}
*/
//const { HasPermission } = require('../../helpers/authorization');
const EventModel = require('./event.model');

const DEF_LIMIT = 10;
const DEF_OFFSET = 0;
module.exports = {
getEvent: async (parent, { id }, context, info, _EventModel = EventModel) => {
try {
if (!id) {
return APIError('BAD_REQUEST');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rutajdash do we need checks like these. The GraphQL query has these fields as non-nullable so these checks in my opinion across the project are worthless

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I had this in mind and hence I stopped using it for other resolvers. Forgot to remove this.

const _event = await _EventModel.findById(id);
if (!_event) {
return APIError('NOT_FOUND');
}
return _event;
} catch (e) {
if (e instanceof GraphQLError) {
return e;
}
return APIError(null, e);
}
},

createEvent: async (
parent,
{ name, startTS, endTS, poster, type, host, url, venue },
context,
info,
_EventModel = EventModel
) => {
try {
/**
* stores current DateTime
*/
let date = new Date();
/**
* Checks if the start time of the event is before the end time of the
* event and if the event is scheduled after the current time.
*/
if (startTS >= endTS || startTS < date.toISOString()) {
return APIError('BAD_REQUEST');
}
const _event = await _EventModel.create({
name: name,
startTS: startTS,
endTS: endTS,
poster: poster,
type: type,
host: host,
url: url,
venue: venue,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't this part give an ESLint warning?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add schemaVersion, CAt, UAt, CBy, UBy

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't this part give an ESLint warning?

What warning exactly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format
{url:url}
can be reduced to
{url}

When key and value have same name

});
return _event;
} catch (e) {
if (e instanceof GraphQLError) {
return e;
}
return APIError(null, e);
}
},

updateEvent: async (
parent,
{ id, name, startTS, endTS, poster, type, host, url, venue },
context,
info,
_EventModel = EventModel
) => {
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a check to see if an event of that ID exists
Only Future events should be updated

/**
* The getUpdateObject function returns an object that contains the
* key-value pairs of the event fields that are needed to be updated.
*/
const getUpdateObject = (propertiesObject) => {
/**
* Initialises an empty object that stores the updated fields.
*/
const updateObject = {};
/**
* The propertiesObject(an object which contains the event fields that
* can be updated) is looped through and only the fields that are
* required to be updated are added to updateObject.
*/
for (key in propertiesObject) {
if (propertiesObject[key]) {
updateObject[key] = propertiesObject[key];
}
}

return updateObject;
};

const updateEvent = getUpdateObject({ name, startTS, endTS, poster, type, host, url, venue });
const _event = await _EventModel.findByIdAndUpdate(id, updateEvent);
return _event;
} catch (e) {
if (e instanceof GraphQLError) {
return e;
}
return APIError(null, e);
}
},
listEvents: async (parent, { limit = DEF_LIMIT, offset = DEF_OFFSET }, context, info, _EventModel = EventModel) => {
try {
const _events = await _EventModel.find().skip(offset).limit(limit);
return _events;
} catch (e) {
if (e instanceof GraphQLError) {
return e;
}
return APIError(null, e);
}
},
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only future events should be listed, or there should be a flag to show past events
The UI needs a list of events in time/date ordered, where is that handled?

34 changes: 34 additions & 0 deletions server/schema/event/event.schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @module app.schema.Event
* @description Event Schema
*
* @requires module:app.schema.scalars
* @requires module:app.schema.Event Query
* @requires module:app.schema.Event Mutation
*
* @version v1
* @since 0.1.0
*/

const {
// GraphQLObjectType,
// GraphQLString,
GraphQLSchema,
// GraphQLID,
// GraphQLList,
// GraphQLBoolean,
// GraphQLInt,
// GraphQLNonNull,
// GraphQLDate,
// GraphQLTime,
// GraphQLDateTime,
// GraphQLJSON,
// GraphQLJSONObject,
} = require('../scalars');
const EventMutation = require('./event.mutation');
const EventQuery = require('./event.query');

module.exports = new GraphQLSchema({
query: EventQuery,
mutation: EventMutation,
});
48 changes: 48 additions & 0 deletions server/schema/event/event.type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @module app.schema.EventType
* @description User Type
*
* @requires module:app.schema.scalars
*
* @version v1
* @since 0.1.0
*/

const {
GraphQLObjectType,
GraphQLString,
//GraphQLSchema,
GraphQLID,
//GraphQLList,
// GraphQLBoolean,
GraphQLInt,
// GraphQLNonNull,
// GraphQLDate,
// GraphQLTime,
GraphQLDateTime,
// GraphQLJSON,
// GraphQLJSONObject,
} = require('../scalars');

const EventType = new GraphQLObjectType({
name: 'Event',
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
startTS: { type: GraphQLDateTime },
endTS: { type: GraphQLDateTime },
poster: { type: GraphQLID },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poster of type GraphQLID?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to what we've planned, we'll be having a media collection, and we would just refer to the id of that media where ever required.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'll be a an ID in database but should resolve to poster and its blurhash here, isn't it?

type: { type: GraphQLInt },
host: { type: GraphQLID },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we resolving the host from its ID?

url: { type: GraphQLString },
venue: { type: GraphQLString },
hits: { type: GraphQLInt },
createdAt: { type: GraphQLID },
createdBy: { type: GraphQLID },
updatedAt: { type: GraphQLDateTime },
updatedBy: { type: GraphQLID },
schemaVersion: { type: GraphQLInt },
Comment on lines +40 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these five needed in GraphQL?

}),
});

module.exports = EventType;
3 changes: 2 additions & 1 deletion server/schema/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

const { mergeSchemas } = require('graphql-tools');
const UserSchema = require('./user/user.schema');
const EventSchema = require('./event/event.schema');

module.exports = mergeSchemas({
schemas: [UserSchema],
schemas: [UserSchema, EventSchema],
});