mirror of
https://github.com/quepasaevents/qpa-client.git
synced 2023-12-14 05:33:02 +01:00
Add more stuff
This commit is contained in:
parent
ee3be1f3be
commit
4774b3a8b1
|
@ -1,4 +1,5 @@
|
|||
import * as React from 'react'
|
||||
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
|
||||
|
||||
const App = () => (
|
||||
<h1>Hello from app</h1>
|
||||
|
|
10
client/Calendar/Calendar.tsx
Normal file
10
client/Calendar/Calendar.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import * as React from 'react'
|
||||
|
||||
interface Props {
|
||||
from: Date
|
||||
type: 'list' | 'board'
|
||||
}
|
||||
|
||||
const Calendar = (props: Props) => (
|
||||
|
||||
)
|
25
client/Calendar/EventsQuery.ts
Normal file
25
client/Calendar/EventsQuery.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { Query } from 'react-apollo'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
const query = gql`
|
||||
query EventsQuery($filter: EventsQueryFilter!) {
|
||||
events(filter: $filter) {
|
||||
id
|
||||
status
|
||||
info {
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
interface Variables {
|
||||
filter: {
|
||||
limit?: number
|
||||
owner?: number
|
||||
from?: string
|
||||
to?: string
|
||||
categories?: string[]
|
||||
}
|
||||
}
|
7
client/Calendar/List/List.tsx
Normal file
7
client/Calendar/List/List.tsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
import * as React from 'react'
|
||||
|
||||
interface Props {
|
||||
from: Date
|
||||
}
|
||||
|
||||
const List = () => ()
|
2
client/Calendar/List/index.ts
Normal file
2
client/Calendar/List/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
import List from './List'
|
||||
export default List
|
|
@ -20,7 +20,9 @@
|
|||
"keycode": "^2.2.0",
|
||||
"react": "^16.8.6",
|
||||
"react-apollo": "^2.2.4",
|
||||
"react-dom": "^16.8.6"
|
||||
"react-dom": "^16.8.6",
|
||||
"react-router": "^5.0.0",
|
||||
"react-router-dom": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.2.3",
|
||||
|
@ -45,8 +47,6 @@
|
|||
"babel-plugin-styled-components": "^1.10.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"react-hot-loader": "^4.8.2",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"ts-jest": "^24.0.0",
|
||||
"ts-node": "^8.0.2",
|
||||
"tslint": "^5.12.1",
|
||||
|
|
|
@ -3587,7 +3587,7 @@ he@1.2.x:
|
|||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
history@^4.7.2:
|
||||
history@^4.9.0:
|
||||
version "4.9.0"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca"
|
||||
integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==
|
||||
|
@ -3608,12 +3608,12 @@ hmac-drbg@^1.0.0:
|
|||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^2.5.0, hoist-non-react-statics@^2.5.5:
|
||||
hoist-non-react-statics@^2.5.5:
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
|
||||
integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
|
||||
|
||||
hoist-non-react-statics@^3.3.0:
|
||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
|
||||
integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==
|
||||
|
@ -6041,7 +6041,7 @@ react-hot-loader@^4.8.2:
|
|||
shallowequal "^1.0.2"
|
||||
source-map "^0.7.3"
|
||||
|
||||
react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||
version "16.8.6"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
|
||||
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
|
||||
|
@ -6051,30 +6051,34 @@ react-lifecycles-compat@^3.0.4:
|
|||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-router-dom@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6"
|
||||
integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==
|
||||
react-router-dom@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.0.0.tgz#542a9b86af269a37f0b87218c4c25ea8dcf0c073"
|
||||
integrity sha512-wSpja5g9kh5dIteZT3tUoggjnsa+TPFHSMrpHXMpFsaHhQkm/JNVGh2jiF9Dkh4+duj4MKCkwO6H08u6inZYgQ==
|
||||
dependencies:
|
||||
history "^4.7.2"
|
||||
invariant "^2.2.4"
|
||||
"@babel/runtime" "^7.1.2"
|
||||
history "^4.9.0"
|
||||
loose-envify "^1.3.1"
|
||||
prop-types "^15.6.1"
|
||||
react-router "^4.3.1"
|
||||
warning "^4.0.1"
|
||||
prop-types "^15.6.2"
|
||||
react-router "5.0.0"
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-router@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e"
|
||||
integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==
|
||||
react-router@5.0.0, react-router@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.0.0.tgz#349863f769ffc2fa10ee7331a4296e86bc12879d"
|
||||
integrity sha512-6EQDakGdLG/it2x9EaCt9ZpEEPxnd0OCLBHQ1AcITAAx7nCnyvnzf76jKWG1s2/oJ7SSviUgfWHofdYljFexsA==
|
||||
dependencies:
|
||||
history "^4.7.2"
|
||||
hoist-non-react-statics "^2.5.0"
|
||||
invariant "^2.2.4"
|
||||
"@babel/runtime" "^7.1.2"
|
||||
create-react-context "^0.2.2"
|
||||
history "^4.9.0"
|
||||
hoist-non-react-statics "^3.1.0"
|
||||
loose-envify "^1.3.1"
|
||||
path-to-regexp "^1.7.0"
|
||||
prop-types "^15.6.1"
|
||||
warning "^4.0.1"
|
||||
prop-types "^15.6.2"
|
||||
react-is "^16.6.0"
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
@ -7490,13 +7494,6 @@ walker@^1.0.7, walker@~1.0.5:
|
|||
dependencies:
|
||||
makeerror "1.0.x"
|
||||
|
||||
warning@^4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
watchpack@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>hello</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -8,7 +8,7 @@ const config: ConnectionOptions = {
|
|||
database: process.env.POSTGRES_DB || 'qpa-dev',
|
||||
entities: ["src/**/*.entity.ts"],
|
||||
synchronize: true,
|
||||
logging: false
|
||||
logging: true
|
||||
}
|
||||
|
||||
export const testConfig: ConnectionOptions = {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"codegen": "gql2ts ./src/schema.graphql -o ./src/@types/index.d.ts",
|
||||
"lint": "tslint --project tsconfig.json",
|
||||
"build": "tsc --version && tsc",
|
||||
"start": "nodemon --exec ts-node src/index.ts",
|
||||
"start": "nodemon --exec ts-node --files src/index.ts",
|
||||
"test": "jest --runInBand"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
|
|
43
server/src/@types/index.d.ts
vendored
43
server/src/@types/index.d.ts
vendored
|
@ -1,7 +1,7 @@
|
|||
// tslint:disable
|
||||
// graphql typescript definitions
|
||||
|
||||
export namespace GQL {
|
||||
declare namespace GQL {
|
||||
interface IGraphQLResponseRoot {
|
||||
data?: IQuery | IMutation;
|
||||
errors?: Array<IGraphQLResponseError>;
|
||||
|
@ -24,12 +24,17 @@ export namespace GQL {
|
|||
__typename: 'Query';
|
||||
me: IUser | null;
|
||||
events: Array<ICalendarEvent | null> | null;
|
||||
occurrences: Array<IEventOccurrence | null> | null;
|
||||
}
|
||||
|
||||
interface IEventsOnQueryArguments {
|
||||
filter: IEventsQueryFilter;
|
||||
}
|
||||
|
||||
interface IOccurrencesOnQueryArguments {
|
||||
filter: IOccurrencesQueryFilter;
|
||||
}
|
||||
|
||||
interface IUser {
|
||||
__typename: 'User';
|
||||
name: string;
|
||||
|
@ -39,8 +44,11 @@ export namespace GQL {
|
|||
}
|
||||
|
||||
interface IEventsQueryFilter {
|
||||
limit?: number | null;
|
||||
owner?: string | null;
|
||||
limit?: number | null;
|
||||
from?: any | null;
|
||||
to?: any | null;
|
||||
categories?: Array<any | null> | null;
|
||||
}
|
||||
|
||||
interface ICalendarEvent {
|
||||
|
@ -52,6 +60,7 @@ export namespace GQL {
|
|||
status: any;
|
||||
contact: Array<IEventContactPerson>;
|
||||
location: ILocation;
|
||||
occurrences: Array<IEventOccurrence | null> | null;
|
||||
}
|
||||
|
||||
interface IEventInformation {
|
||||
|
@ -95,6 +104,25 @@ export namespace GQL {
|
|||
lng: number | null;
|
||||
}
|
||||
|
||||
interface IEventOccurrence {
|
||||
__typename: 'EventOccurrence';
|
||||
id: string;
|
||||
event: ICalendarEvent;
|
||||
start: string;
|
||||
utcStart: string;
|
||||
end: string;
|
||||
utcEnd: string;
|
||||
timeZone: string;
|
||||
}
|
||||
|
||||
interface IOccurrencesQueryFilter {
|
||||
from?: any | null;
|
||||
to?: any | null;
|
||||
timeZone?: any | null;
|
||||
categories?: Array<any | null> | null;
|
||||
limit?: number | null;
|
||||
}
|
||||
|
||||
interface IMutation {
|
||||
__typename: 'Mutation';
|
||||
signup: Array<IError | null> | null;
|
||||
|
@ -116,8 +144,7 @@ export namespace GQL {
|
|||
}
|
||||
|
||||
interface ICreateEventOnMutationArguments {
|
||||
input?: ICreateEventInput | null;
|
||||
foo?: string | null;
|
||||
input: ICreateEventInput;
|
||||
}
|
||||
|
||||
interface ISignupInput {
|
||||
|
@ -159,10 +186,10 @@ export namespace GQL {
|
|||
}
|
||||
|
||||
interface IEventTimeInput {
|
||||
timeZone?: any | null;
|
||||
status?: any | null;
|
||||
start?: any | null;
|
||||
end?: any | null;
|
||||
timeZone: any;
|
||||
start: any;
|
||||
end: any;
|
||||
recurrence?: string | null;
|
||||
}
|
||||
|
||||
interface IEventInformationInput {
|
||||
|
|
|
@ -7,7 +7,7 @@ export class Session extends BaseEntity {
|
|||
@PrimaryGeneratedColumn()
|
||||
id: string
|
||||
|
||||
@ManyToOne(type => User, (user: User) => user.sessions)
|
||||
@ManyToOne(type => User, (user: User) => user.sessions, { eager: true})
|
||||
user: User
|
||||
|
||||
@Column()
|
||||
|
|
|
@ -26,7 +26,7 @@ export class User extends BaseEntity {
|
|||
events: Event[]
|
||||
|
||||
@OneToMany(type => Session, session => session.user)
|
||||
sessions: Session[]
|
||||
sessions: Promise<Session[]>
|
||||
|
||||
@OneToMany(type => SessionInvite, invite => invite.user)
|
||||
sessionInvites: SessionInvite[]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import SessionManager, { SessionAlreadyValidatedError } from "./SessionManager"
|
||||
import { User } from "./User.entity"
|
||||
import { GQL } from "../@types"
|
||||
import { PostOffice } from "../post_office"
|
||||
|
||||
interface Dependencies {
|
||||
|
|
|
@ -4,23 +4,15 @@ import {
|
|||
Column,
|
||||
BaseEntity,
|
||||
OneToMany,
|
||||
OneToOne,
|
||||
ManyToOne,
|
||||
CreateDateColumn,
|
||||
JoinColumn,
|
||||
AfterUpdate,
|
||||
AfterInsert,
|
||||
BeforeInsert,
|
||||
BeforeUpdate,
|
||||
TransactionManager,
|
||||
EntityManager,
|
||||
Transaction
|
||||
PrimaryColumn
|
||||
} from "typeorm"
|
||||
import { User } from "../Auth/User.entity"
|
||||
import { DateTime } from "luxon"
|
||||
import { rrulestr } from "rrule"
|
||||
|
||||
const toUTC = (isoTime: string, ianaTZ: string) => {
|
||||
export const toUTC = (isoTime: string, ianaTZ: string): string => {
|
||||
const parsed = DateTime.fromISO(isoTime, { zone: ianaTZ })
|
||||
if (parsed.invalidReason) {
|
||||
throw new Error(
|
||||
|
@ -71,13 +63,6 @@ export class EventTime {
|
|||
exceptions?: string
|
||||
}
|
||||
|
||||
export class EventInformation {
|
||||
@Column()
|
||||
title: string
|
||||
@Column()
|
||||
description: string
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class Event extends BaseEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
|
@ -91,8 +76,8 @@ export class Event extends BaseEntity {
|
|||
})
|
||||
occurrences: EventOccurrence[]
|
||||
|
||||
@Column(type => EventInformation)
|
||||
info: EventInformation
|
||||
@OneToMany(type => EventInformation, eventInfo => eventInfo.event)
|
||||
info: EventInformation[]
|
||||
|
||||
@Column(type => EventTime)
|
||||
time: EventTime
|
||||
|
@ -121,7 +106,9 @@ export class Event extends BaseEntity {
|
|||
this.occurrences = [singleOccurrence]
|
||||
} else {
|
||||
const ruleSet = rrulestr(this.time.recurrence)
|
||||
const allDates = ruleSet.all()
|
||||
const allDates = ruleSet.all(
|
||||
(occurenceDate, i) => i < 30
|
||||
)
|
||||
|
||||
this.occurrences = allDates
|
||||
.map(occurenceDate => {
|
||||
|
@ -140,6 +127,26 @@ export class Event extends BaseEntity {
|
|||
}
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class EventInformation {
|
||||
@PrimaryColumn()
|
||||
eventIdAndLang: string
|
||||
@Column()
|
||||
language: string
|
||||
@Column()
|
||||
title: string
|
||||
@Column()
|
||||
description: string
|
||||
@ManyToOne(type => Event, event => event.info)
|
||||
event: Event
|
||||
|
||||
@BeforeInsert()
|
||||
updatePrimaryColumn() {
|
||||
this.eventIdAndLang = `${this.event.id}_${this.language}`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Entity()
|
||||
export class EventOccurrence extends BaseEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
|
@ -148,18 +155,25 @@ export class EventOccurrence extends BaseEntity {
|
|||
@ManyToOne(type => Event, event => event.occurrences)
|
||||
event: Event
|
||||
|
||||
@Column({ type: "timestamp without time zone" })
|
||||
start: string
|
||||
|
||||
@Column({ type: "timestamptz" })
|
||||
utcStart: string
|
||||
|
||||
@Column({ type: "timestamp without time zone" })
|
||||
end: string
|
||||
|
||||
@Column({ type: "timestamptz" })
|
||||
utcEnd: string
|
||||
|
||||
// Time zone of the event as entered by the user
|
||||
// or implicitly by calendar's time-zone
|
||||
@Column()
|
||||
timeZone: string
|
||||
@Column({ type: "timestamp" })
|
||||
// Start date as entered by the user local to the
|
||||
// event's time zone
|
||||
start: string
|
||||
// End date as entered by the user local to the
|
||||
// event's time zone
|
||||
@Column({ type: "timestamp" })
|
||||
end: string
|
||||
|
||||
// Absolute start date in UTC used to find
|
||||
// and order occurrences chronologically
|
||||
@Column({ type: "timestamptz" })
|
||||
utcStart: string
|
||||
// Absolute end date in UTC used to find
|
||||
// and order occurrences chronologically
|
||||
@Column({ type: "timestamptz" })
|
||||
utcEnd: string
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ describe("Events resolver", () => {
|
|||
return (connection = await createConnection({
|
||||
...testConfig
|
||||
}))
|
||||
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
|
@ -150,7 +149,4 @@ describe("Events resolver", () => {
|
|||
done()
|
||||
})
|
||||
|
||||
it('Get events by user', async done => {
|
||||
|
||||
})
|
||||
})
|
||||
|
|
55
server/src/Events/__tests__/occurrences.spec.ts
Normal file
55
server/src/Events/__tests__/occurrences.spec.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import {User} from "../../Auth/User.entity"
|
||||
import {Session} from "../../Auth/Session.entity"
|
||||
import {Event, toUTC} from "../../Calendar/Event.entity"
|
||||
import {Frequency, RRule} from 'rrule'
|
||||
import {testConfig} from "../../../ormconfig"
|
||||
import {Connection, createConnection} from "typeorm"
|
||||
|
||||
let connection: Connection = null
|
||||
|
||||
describe('Occurrences', async () => {
|
||||
beforeAll(async () => {
|
||||
return (connection = await createConnection({
|
||||
...testConfig,
|
||||
}))
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await connection.close()
|
||||
})
|
||||
|
||||
it('Test occurrences resolver', async () => {
|
||||
const owner = new User()
|
||||
owner.name = "All the time"
|
||||
owner.username = "allthetime"
|
||||
owner.email = "allthetime@example.com"
|
||||
await owner.save()
|
||||
|
||||
const session = new Session()
|
||||
session.user = owner
|
||||
session.hash = "allthetime_owners_auth_hash"
|
||||
session.isValid = true
|
||||
await session.save()
|
||||
|
||||
const event = new Event()
|
||||
event.owner = owner
|
||||
event.info = {
|
||||
title: "Recurring event once a week",
|
||||
description: "Event happening every monday at 13:00"
|
||||
}
|
||||
event.time = {
|
||||
timeZone: "Europe/Madrid",
|
||||
start: "2019-03-01T13:00",
|
||||
end: "2019-03-01T14:00",
|
||||
recurrence: new RRule({
|
||||
freq: Frequency.WEEKLY,
|
||||
interval: 1,
|
||||
dtstart: new Date(toUTC("2019-03-01T13:00", "Europe/Madrid"))
|
||||
}).toString()
|
||||
}
|
||||
event.status = "Scheduled"
|
||||
|
||||
event.updateOccurrences()
|
||||
await event.save()
|
||||
})
|
||||
})
|
|
@ -1,15 +1,34 @@
|
|||
import {Event} from "../Calendar/Event.entity"
|
||||
import {Context, ResolverMap} from "../@types/graphql-utils"
|
||||
import {GQL} from "../@types"
|
||||
import {
|
||||
Event,
|
||||
EventInformation,
|
||||
EventOccurrence
|
||||
} from "../Calendar/Event.entity"
|
||||
import { Context, ResolverMap } from "../@types/graphql-utils"
|
||||
|
||||
const resolvers: ResolverMap = {
|
||||
Query: {
|
||||
events: async (_, req: GQL.IEventsOnQueryArguments, context, info) => {
|
||||
return Event.find({
|
||||
take: req.filter.limit,
|
||||
where: (req.filter && req.filter.owner) ? `"ownerId"='${req.filter.owner}'` : null
|
||||
where:
|
||||
req.filter && req.filter.owner
|
||||
? `"ownerId"='${req.filter.owner}'`
|
||||
: null
|
||||
})
|
||||
},
|
||||
occurrences: async (
|
||||
_,
|
||||
req: GQL.IOccurrencesOnQueryArguments,
|
||||
context,
|
||||
info
|
||||
) => {
|
||||
return EventOccurrence.createQueryBuilder("occurrence")
|
||||
.where("occurrence.utcStart BETWEEN :from AND :to", {
|
||||
from: req.filter.from,
|
||||
to: req.filter.to
|
||||
})
|
||||
.limit(req.filter.limit)
|
||||
}
|
||||
},
|
||||
|
||||
Event: {
|
||||
|
@ -19,15 +38,34 @@ const resolvers: ResolverMap = {
|
|||
},
|
||||
|
||||
Mutation: {
|
||||
createEvent: async (_, { input }: GQL.ICreateEventOnMutationArguments, context: Context, info) => {
|
||||
createEvent: async (
|
||||
_,
|
||||
{ input }: GQL.ICreateEventOnMutationArguments,
|
||||
context: Context,
|
||||
info
|
||||
) => {
|
||||
if (!context.user) {
|
||||
throw Error('not authenticated')
|
||||
throw Error("not authenticated")
|
||||
}
|
||||
const event = new Event()
|
||||
event.owner = context.user
|
||||
event.info = input.info.map(infoInput => {
|
||||
const eventInformation = new EventInformation()
|
||||
eventInformation.language = infoInput.language
|
||||
eventInformation.title = infoInput.title
|
||||
eventInformation.description = infoInput.description
|
||||
eventInformation.event = event
|
||||
return eventInformation
|
||||
})
|
||||
event.time = {
|
||||
recurrence: input.time.recurrence,
|
||||
timeZone: input.time.timeZone,
|
||||
start: input.time.start,
|
||||
end: input.time.end
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default resolvers
|
||||
|
|
|
@ -62,6 +62,7 @@ export const createServer = async (dependencies: Dependencies) => {
|
|||
ctx.user = session.user
|
||||
}
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
})
|
||||
|
|
|
@ -5,6 +5,7 @@ import { sendEmail} from "./post_office"
|
|||
import * as config from './config'
|
||||
|
||||
async function start() {
|
||||
console.log(`Starting with db: ${typeormConfig.database}`)
|
||||
const server = await createServer({
|
||||
typeormConnection: await createConnection(typeormConfig),
|
||||
sendEmail,
|
||||
|
|
|
@ -41,6 +41,17 @@ type CalendarEvent {
|
|||
status: EventStatus!
|
||||
contact: [EventContactPerson!]!
|
||||
location: Location!
|
||||
occurrences: [EventOccurrence]
|
||||
}
|
||||
|
||||
type EventOccurrence {
|
||||
id: ID!
|
||||
event: CalendarEvent!
|
||||
start: String!
|
||||
utcStart: String!
|
||||
end: String!
|
||||
utcEnd: String!
|
||||
timeZone: String!
|
||||
}
|
||||
|
||||
type Location {
|
||||
|
@ -91,16 +102,29 @@ type Contact {
|
|||
phone: String
|
||||
}
|
||||
|
||||
scalar Category
|
||||
|
||||
input EventsQueryFilter {
|
||||
limit: Int
|
||||
owner: ID
|
||||
limit: Int
|
||||
from: Timestamp
|
||||
to: Timestamp
|
||||
categories: [Category]
|
||||
}
|
||||
|
||||
input OccurrencesQueryFilter {
|
||||
from: Timestamp
|
||||
to: Timestamp
|
||||
timeZone: TimeZone
|
||||
categories: [Category]
|
||||
limit: Int
|
||||
}
|
||||
|
||||
input EventTimeInput {
|
||||
timeZone: TimeZone
|
||||
status: EventStatus
|
||||
start: Timestamp
|
||||
end: Timestamp
|
||||
timeZone: TimeZone!
|
||||
start: Timestamp!
|
||||
end: Timestamp!
|
||||
recurrence: String
|
||||
}
|
||||
|
||||
input EventContactInput {
|
||||
|
@ -157,7 +181,7 @@ type Mutation {
|
|||
requestInvite(input: RequestInviteInput): Boolean!
|
||||
|
||||
# Event
|
||||
createEvent(input: CreateEventInput, foo: String): CalendarEvent
|
||||
createEvent(input: CreateEventInput!): CalendarEvent
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,4 +192,5 @@ type Query {
|
|||
|
||||
# Event
|
||||
events(filter: EventsQueryFilter!): [CalendarEvent]
|
||||
occurrences(filter: OccurrencesQueryFilter!): [EventOccurrence]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue