@@ -23,6 +23,7 @@ | |||
"vue-cookies": "^1.7.4", | |||
"vue-router": "^3.2.0", | |||
"vuetify": "^2.4.0", | |||
"vuetify-image-input": "^19.2.2", | |||
"vuex": "^3.4.0" | |||
}, | |||
"devDependencies": { | |||
@@ -14976,6 +14977,14 @@ | |||
"vue": "^2.6.4" | |||
} | |||
}, | |||
"node_modules/vuetify-image-input": { | |||
"version": "19.2.2", | |||
"resolved": "https://registry.npmjs.org/vuetify-image-input/-/vuetify-image-input-19.2.2.tgz", | |||
"integrity": "sha512-U3qKkMXBiYSXV3IaRyTxNCw9rpgr52lqck0zWM7geOMdUu9IXKDGN1kfIbFGzT6FU6QntFoduHwwEOcug62bxw==", | |||
"peerDependencies": { | |||
"vuetify": "^2" | |||
} | |||
}, | |||
"node_modules/vuetify-loader": { | |||
"version": "1.7.2", | |||
"resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.7.2.tgz", | |||
@@ -28389,6 +28398,12 @@ | |||
"integrity": "sha512-Lpnwm64xYVEXb5BXdadSRaH0QHjXLFhPPjuVU9VuqWp3Nzr+WP5vA9nMPkJAfUj8vKIJGTRXqyGTGVa4VwrO3A==", | |||
"requires": {} | |||
}, | |||
"vuetify-image-input": { | |||
"version": "19.2.2", | |||
"resolved": "https://registry.npmjs.org/vuetify-image-input/-/vuetify-image-input-19.2.2.tgz", | |||
"integrity": "sha512-U3qKkMXBiYSXV3IaRyTxNCw9rpgr52lqck0zWM7geOMdUu9IXKDGN1kfIbFGzT6FU6QntFoduHwwEOcug62bxw==", | |||
"requires": {} | |||
}, | |||
"vuetify-loader": { | |||
"version": "1.7.2", | |||
"resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.7.2.tgz", |
@@ -24,6 +24,7 @@ | |||
"vue-cookies": "^1.7.4", | |||
"vue-router": "^3.2.0", | |||
"vuetify": "^2.4.0", | |||
"vuetify-image-input": "^19.2.2", | |||
"vuex": "^3.4.0" | |||
}, | |||
"devDependencies": { |
@@ -4,7 +4,10 @@ import de from 'vuetify/lib/locale/de' | |||
import '@/sass/overrides.sass' | |||
import VImageInput from 'vuetify-image-input/a-la-carte' | |||
Vue.use(Vuetify) | |||
Vue.component('VImageInput', VImageInput) | |||
const theme = { | |||
primary: '#FF041D', |
@@ -36,25 +36,40 @@ | |||
mobile-breakpoint="0" | |||
:search="filter" | |||
@click:row="open" | |||
/> | |||
> | |||
<template #item.logo="{item}"> | |||
<img | |||
v-if="item.logo" | |||
height="64" | |||
:src="item.logo" | |||
> | |||
<v-avatar | |||
v-else | |||
color="grey lighten-2" | |||
size="32" | |||
> | |||
{{ item.name.substr(0,2) }} | |||
</v-avatar> | |||
</template> | |||
</v-data-table> | |||
</v-card> | |||
<!--edit-people | |||
<edit-apparatus | |||
:id="dialog.id" | |||
v-model="dialog.open" | |||
/--> | |||
/> | |||
</v-container> | |||
</template> | |||
<script> | |||
import { useAuth } from '@/plugins/auth' | |||
import gql from 'graphql-tag' | |||
// import { updateQuery, deleteQuery } from '@/graphql' | |||
import { updateQuery, deleteQuery } from '@/plugins/graphql' | |||
export default { | |||
name: 'People', | |||
components: { | |||
// EditPeople: () => import('./dialogs/EditPeople'), | |||
EditApparatus: () => import('./dialogs/EditApparatus') | |||
}, | |||
setup (props, context) { | |||
@@ -69,7 +84,8 @@ export default { | |||
{ | |||
text: '', | |||
value: 'logo', | |||
sortable: false | |||
sortable: false, | |||
width: 100 | |||
}, | |||
{ | |||
text: 'Name', | |||
@@ -86,20 +102,20 @@ export default { | |||
apollo: { | |||
ApparatusFind: { | |||
query: gql`query { ApparatusFind { _id name logo } }` | |||
/* subscribeToMore: { | |||
document: gql`subscription { PersonUpdated { _id vorname nachname geburtstag dtbid gymnet { id } email { email typ } tel { nummer typ } adresse { strasse hausnummer plz ort land typ } turnportal { typ gueltigvon gueltigbis lastcheck sperre festgeturnt verein vermerk } } }`, | |||
updateQuery: updateQuery('PersonList', 'PersonUpdated') | |||
} */ | |||
} | |||
/* $subscribe: { | |||
query: gql`query { ApparatusFind { _id name logo } }`, | |||
subscribeToMore: { | |||
document: gql`subscription { ApparatusUpdated { _id name logo } }`, | |||
updateQuery: updateQuery('ApparatusFind', 'ApparatusUpdated') | |||
} | |||
}, | |||
$subscribe: { | |||
PersonDeleted: { | |||
query: gql`subscription { PersonDeleted }`, | |||
query: gql`subscription { ApparatusDeleted }`, | |||
result (id) { | |||
deleteQuery('PersonList', 'PersonUpdated', this.PersonList, id) | |||
}, | |||
}, | |||
}, */ | |||
deleteQuery('ApparatusFind', 'ApparatusDeleted', this.ApparatusFind, id) | |||
} | |||
} | |||
} | |||
}, | |||
methods: { |
@@ -0,0 +1,104 @@ | |||
<template> | |||
<base-material-dialog | |||
:value="value" | |||
icon="mdi-home" | |||
title="Gerät bearbeiten" | |||
:sub-title="id ? id : 'NEU'" | |||
color="rgb(255, 4, 29)" | |||
:actions="[doc && isMaster ? 'del' : '', isMaster ? 'save' : '', 'cancel']" | |||
@del="del" | |||
@save="save" | |||
@close="close" | |||
@esc="close" | |||
> | |||
<v-row v-if="!isMaster"> | |||
Kein Zugriff! {{ isMaster }} | |||
</v-row> | |||
<v-row v-else> | |||
<v-col | |||
cols="12" | |||
sm="6" | |||
md="9" | |||
> | |||
<v-text-field | |||
v-model="data.name" | |||
label="Gerätename" | |||
/> | |||
</v-col> | |||
<v-col | |||
cols="12" | |||
sm="6" | |||
md="3" | |||
> | |||
<v-image-input | |||
ref="logo" | |||
v-model="data.logo" | |||
:image-quality="0.60" | |||
:image-height="128" | |||
:image-width="128" | |||
overlay-padding="10px" | |||
overlay-border-width="2px" | |||
overlay-border-color="#f00" | |||
upload-icon="fa-cloud-upload" | |||
flip-horizontally-icon="fa-arrows-h" | |||
flip-vertically-icon="fa-arrows-v" | |||
rotate-clockwise-icon="fa-redo" | |||
rotate-counter-clockwise-icon="fa-undo" | |||
image-min-scaling="contain" | |||
clearable | |||
/> | |||
</v-col> | |||
</v-row> | |||
</base-material-dialog> | |||
</template> | |||
<script> | |||
import { useAuth } from '@/plugins/auth' | |||
import { useEditDialog } from '@/plugins/editdialog' | |||
export default { | |||
name: 'EditApparatus', | |||
props: { | |||
value: { | |||
type: Boolean, | |||
required: true | |||
}, | |||
id: { | |||
type: String, | |||
default: null | |||
} | |||
}, | |||
setup (props, context) { | |||
return { | |||
...useAuth(context), | |||
...useEditDialog(props, context, 'Apparatus(id: $id) { _id name logo }', ['name', 'logo']) | |||
} | |||
}, | |||
methods: { | |||
update () { | |||
return { | |||
mutation: `mutation($id: UUID!, $name: String, $logo: String) { | |||
ApparatusUpdate(id: $id, name: $name, logo: $logo) { | |||
_id name logo | |||
} | |||
}` | |||
} | |||
}, | |||
create () { | |||
return { | |||
mutation: `mutation($name: String!, $logo: String) { | |||
ApparatusCreate(name: $name, logo: $logo) { | |||
_id name logo | |||
} | |||
}` | |||
} | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="sass"> | |||
$dialog-elevation: 0 | |||
</style> |
@@ -82,6 +82,9 @@ type Mutation { | |||
PersonUpdate(master: Boolean, email: EmailAddress, familyName: String, givenName: String, id: UUID!): Person! | |||
PersonCreate(master: Boolean, email: EmailAddress!, familyName: String!, givenName: String!): Person! | |||
PersonDelete(id: UUID!): UUID! | |||
ApparatusUpdate(logo: String, name: String, id: UUID!): Apparatus! | |||
ApparatusCreate(logo: String, name: String!): Apparatus! | |||
ApparatusDelete(id: UUID!): UUID! | |||
OrganizerRegister(ort: String, plz: Int, name: String!): Organizer! | |||
EventCreate(name: String, date: Date!, organizer: UUID!): Event! | |||
} | |||
@@ -89,4 +92,6 @@ type Mutation { | |||
type Subscription { | |||
PersonUpdated: Person | |||
PersonDeleted: UUID! | |||
ApparatusUpdated: Apparatus | |||
ApparatusDeleted: UUID! | |||
} |
@@ -3,10 +3,11 @@ import { ApparatusResolverQ } from './resolver/apparatus.query'; | |||
import { ApparatusResolverM } from './resolver/apparatus.mutation'; | |||
import { ApparatusService } from './apparatus.service'; | |||
import { ApparatusResolver } from './resolver/apparatus'; | |||
import {ApparatusResolverS} from './resolver/apparatus.subscription' | |||
@Module({ | |||
providers: [ | |||
ApparatusResolverQ, ApparatusResolverM, | |||
ApparatusResolverQ, ApparatusResolverM, ApparatusResolverS, | |||
ApparatusService, | |||
ApparatusResolver, | |||
], |
@@ -3,10 +3,67 @@ import { Apparatus } from '../models/Apparatus'; | |||
import { Client } from '../../client'; | |||
import { ApparatusService } from '../apparatus.service'; | |||
import { HttpException } from '@nestjs/common'; | |||
import {UUID} from '../../global/scalars/UUID' | |||
import {pubsub} from '../../main' | |||
@Resolver(() => Apparatus) | |||
export class ApparatusResolverM { | |||
constructor( | |||
private readonly service: ApparatusService, | |||
) {} | |||
@Mutation(() => Apparatus, { nullable: false }) | |||
async ApparatusUpdate( | |||
@Context('client') client: Client, | |||
@Args('id', { type: () => UUID, nullable: false }) id: UUID, | |||
@Args('name', { nullable: true }) name?: string, | |||
@Args('logo', { nullable: true }) logo?: string, | |||
): Promise<Apparatus> { | |||
if (!client.isMaster()) throw new HttpException('Access denied', 403); | |||
const tmp = await this.service.findOneById(id); | |||
const set: { | |||
name?: string | |||
logo?: string | |||
} = {}; | |||
if (name !== undefined && name !== tmp.name) set.name = name | |||
if (logo !== undefined && logo !== tmp.logo) set.logo = logo | |||
if (Object.values(set).length === 0) return tmp; | |||
const neu = await this.service.update(client, tmp._id, {$set: set}); | |||
pubsub.publish('ApparatusUpdated', { ApparatusUpdated: neu }); | |||
return neu; | |||
} | |||
@Mutation(() => Apparatus, { nullable: false }) | |||
async ApparatusCreate( | |||
@Context('client') client: Client, | |||
@Args('name', { nullable: false }) name: string, | |||
@Args('logo', { nullable: true }) logo?: string, | |||
): Promise<Apparatus> { | |||
if (!client.isMaster()) throw new HttpException('Access denied', 403); | |||
const neu = await this.service.insert(client, { name, logo }); | |||
pubsub.publish('ApparatusUpdated', { ApparatusUpdated: neu }); | |||
return neu; | |||
} | |||
@Mutation(() => UUID, { nullable: false }) | |||
async ApparatusDelete( | |||
@Context('client') client: Client, | |||
@Args('id', { type: () => UUID, nullable: false }) id: UUID | |||
): Promise<UUID> { | |||
if (!client.isMaster()) throw new HttpException('Access denied', 403); | |||
this.service.delete(client, id); | |||
pubsub.publish('ApparatusDeleted', { ApparatusDeleted: id }); | |||
return id; | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
import {Resolver, Subscription} from '@nestjs/graphql' | |||
import {ApparatusService} from '../apparatus.service' | |||
import {Apparatus} from '../models/Apparatus' | |||
import { pubsub } from '../../main' | |||
import { UUID } from '../../global/scalars/UUID' | |||
@Resolver(() => Apparatus) | |||
export class ApparatusResolverS { | |||
constructor( | |||
private readonly service: ApparatusService, | |||
) {} | |||
@Subscription(() => Apparatus,{ nullable: true }) | |||
async ApparatusUpdated() { | |||
return pubsub.asyncIterator('ApparatusUpdated'); | |||
} | |||
@Subscription(() => UUID, { nullable: false }) | |||
async ApparatusDeleted() { | |||
return pubsub.asyncIterator('ApparatusDeleted') | |||
} | |||
} |