Merge branch 'master' of github.com:fLotte-meets-HWR-DB/frontend

pull/3/head
leonnicolas 4 years ago
commit 0bfd28877d

@ -1,4 +1,4 @@
<div #booleanInputType *ngIf="inputType == 'boolean'">
<div #booleanInputType *ngIf="inputType == 'Boolean'">
<mat-checkbox
class="checkbox"
[disabled]="!editable"
@ -7,7 +7,7 @@
></mat-checkbox>
</div>
<div #enumInputType *ngIf="inputType == 'enum'">
<div #enumInputType *ngIf="inputType.startsWith('Enum//')">
<mat-form-field *ngIf="editable; else nonEditableText">
<mat-select [(ngModel)]="value" (ngModelChange)="change($event)">
<mat-option *ngFor="let option of enumValues" [value]="option">
@ -20,7 +20,7 @@
</ng-template>
</div>
<div #otherInputType *ngIf="inputType != 'enum' && inputType != 'boolean'">
<div #otherInputType *ngIf="inputType === 'number' || inputType === 'text'">
<mat-form-field *ngIf="editable; else nonEditableText">
<input
matInput

@ -1,5 +1,4 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { catchError } from 'rxjs/operators';
@Component({
selector: 'app-cell',
@ -14,8 +13,22 @@ export class CellComponent {
editable = false;
@Input()
inputType = 'text';
@Input()
enumValues: string[] = [];
enumValues = [];
ngOnChanges() {
if (this.inputType.split('//')[0] === 'Enum') {
this.enumValues = this.inputType.split('//').slice(1);
} else if (this.inputType === 'Int' || this.inputType === 'Float') {
this.inputType = 'number';
} else if (this.inputType === 'ID' || this.inputType === 'String') {
this.inputType = 'text';
} else if (this.inputType === 'Boolean') {
} else {
console.log(this.inputType);
}
}
change(newValue) {
this.value = this.inputType === 'number' ? +newValue : newValue;

@ -1,5 +1,5 @@
query GetCargoBikes {
...Introspection
...SchemaIntrospection
cargoBikes(limit: 100, offset: 0) {
...CargoBikeFields

@ -1,4 +1,4 @@
fragment Introspection on Query {
fragment GroupIntrospection on Query {
__type(name: "Group") {
name
enumValues {
@ -6,3 +6,26 @@ fragment Introspection on Query {
}
}
}
fragment SchemaIntrospection on Query {
__schema {
types {
name
kind
enumValues {
name
}
fields {
name
type {
name
kind
ofType {
name
kind
}
}
}
}
}
}

@ -19,7 +19,7 @@ function isPartOfSelectionSet(
if (variablePath.length === 1) {
return true;
}
return isPartOfSelectionSet(variablePath.slice(1).join(), nextSelectionObject);
return isPartOfSelectionSet(variablePath.slice(1).join('.'), nextSelectionObject);
} else {
return false;
}

@ -62,7 +62,6 @@
[editable]="element.isLockedByMe && !isReadonly(column)"
[(value)]="element[column]"
[inputType]="getType(column, element)"
[enumValues]="getEnumValues(column)"
></app-cell>
</td>
</ng-container>

@ -10,6 +10,7 @@ import {
CargoBikeFieldsMutableFragmentDoc,
CargoBikeUpdateInput,
} from 'src/generated/graphql';
import { SchemaService } from 'src/app/services/schema.service';
@Component({
selector: 'app-bikes',
@ -18,9 +19,9 @@ import {
})
export class BikesComponent {
columnInfo = [
{ name: 'name', header: 'Name', type: 'string', sticky: true },
{ name: 'id', header: 'ID', type: 'number', readonly: true },
{ name: 'group', header: 'Gruppe', type: 'enum', enumValues: [] },
{ name: 'name', header: 'Name', sticky: true },
{ name: 'id', header: 'ID', readonly: true },
{ name: 'group', header: 'Gruppe'},
];
//properties that wont be shown in the table
@ -47,16 +48,13 @@ export class BikesComponent {
relockingInterval = null;
relockingDuration = 1000 * 60 * 1;
constructor(private bikesService: BikesService) {
constructor(
private bikesService: BikesService,
private schemaService: SchemaService
) {
this.displayedColumns.unshift(this.additionalColumnsFront[0]);
this.displayedColumns.push(this.additionalColumnsBack[0]);
bikesService.groupEnum.subscribe((groupEnum) => {
this.columnInfo.find(
(column) => column.name === 'group'
).enumValues = groupEnum;
});
bikesService.loadingRowIds.subscribe((rowIds) => {
this.loadingRowIds = rowIds;
});
@ -75,7 +73,7 @@ export class BikesComponent {
}
for (const prop in this.data[0]) {
if (!this.blacklistedColumns.includes(prop) && !prop.includes("__")) {
if (!this.blacklistedColumns.includes(prop) && !prop.includes('__')) {
this.dataColumns.push(prop);
}
}
@ -122,17 +120,17 @@ export class BikesComponent {
}
getType(propertyName: string, row) {
//TODO: get type from introspection query
//console.log(propertyName, this.schemaService.getPropertyTypeFromSchema("CargoBike", propertyName))
return (
this.columnInfo.find((column) => column.name === propertyName)?.type ||
(typeof row[propertyName])
this.schemaService.getPropertyTypeFromSchema("CargoBike", propertyName)
);
}
isReadonly(propertyName: string) {
return (
this.columnInfo.find((column) => column.name === propertyName)
?.readonly || !isPartOfGraphQLDoc(propertyName, CargoBikeFieldsMutableFragmentDoc)
?.readonly ||
!isPartOfGraphQLDoc(propertyName, CargoBikeFieldsMutableFragmentDoc)
);
}
@ -143,13 +141,6 @@ export class BikesComponent {
);
}
getEnumValues(propertyName: string) {
return (
this.columnInfo.find((column) => column.name === propertyName)
?.enumValues || []
);
}
isLoading(id: string) {
return this.loadingRowIds.includes(id);
}

@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { SchemaService } from './schema.service';
import {
GetCargoBikesGQL,
GetCargoBikesQuery,
@ -28,6 +29,7 @@ export class BikesService {
groupEnum: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
constructor(
private schemaService: SchemaService,
private getCargoBikesGQL: GetCargoBikesGQL,
private getCargoBikeByIdGQL: GetCargoBikeByIdGQL,
private updateCargoBikeGQL: UpdateCargoBikeGQL,
@ -50,8 +52,7 @@ export class BikesService {
loadBikes() {
this.getCargoBikesGQL.fetch().subscribe((result) => {
this.bikes.next(result.data.cargoBikes);
let enumValues = result.data.__type.enumValues.map((value) => value.name);
this.groupEnum.next(enumValues);
this.schemaService.nextSchema(result.data.__schema);
});
}

@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { find } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class SchemaService {
schema: BehaviorSubject<any> = new BehaviorSubject({});
nextSchema(schema: any) {
this.schema.next(schema);
}
/** expects startingObject and variablePath and returns its type e.g. cargoBike, security.name -> returns the type of the name variable */
getPropertyTypeFromSchema(
startingObjectName: String,
variable: String
): String {
const variablePath = variable.split('.');
const types = this.schema.value.types;
const startingObject = types.find(
(type) => type.name === startingObjectName
);
const field = startingObject.fields.find(
(field) => field.name === variablePath[0]
);
const type = field.type.name || field.type.ofType.name;
if (variablePath.length === 1) {
if ((field.type.kind === "ENUM")) {
return "Enum//" + this.getEnumValuesFromSchema(field.type.name).join("//");
}
return type;
} else {
return this.getPropertyTypeFromSchema(type, variablePath.slice(1).join('.'));
}
}
getEnumValuesFromSchema(typeName: String): String[] {
const types= this.schema.value.types;
const type = types.find(type => type.name === typeName);
return type.enumValues.map((value) => value.name);
}
}

@ -1668,6 +1668,22 @@ export enum CacheControlScope {
}
/** A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations. */
export type __Schema = {
__typename?: '__Schema';
description?: Maybe<Scalars['String']>;
/** A list of all types supported by this server. */
types: Array<__Type>;
/** The type that query operations will be rooted at. */
queryType: __Type;
/** If this server supports mutation, the type that mutation operations will be rooted at. */
mutationType?: Maybe<__Type>;
/** If this server support subscription, the type that subscription operations will be rooted at. */
subscriptionType?: Maybe<__Type>;
/** A list of all directives supported by this server. */
directives: Array<__Directive>;
};
/**
* The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.
*
@ -1757,6 +1773,62 @@ export type __EnumValue = {
deprecationReason?: Maybe<Scalars['String']>;
};
/**
* A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
*
* In some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.
*/
export type __Directive = {
__typename?: '__Directive';
name: Scalars['String'];
description?: Maybe<Scalars['String']>;
isRepeatable: Scalars['Boolean'];
locations: Array<__DirectiveLocation>;
args: Array<__InputValue>;
};
/** A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies. */
export enum __DirectiveLocation {
/** Location adjacent to a query operation. */
Query = 'QUERY',
/** Location adjacent to a mutation operation. */
Mutation = 'MUTATION',
/** Location adjacent to a subscription operation. */
Subscription = 'SUBSCRIPTION',
/** Location adjacent to a field. */
Field = 'FIELD',
/** Location adjacent to a fragment definition. */
FragmentDefinition = 'FRAGMENT_DEFINITION',
/** Location adjacent to a fragment spread. */
FragmentSpread = 'FRAGMENT_SPREAD',
/** Location adjacent to an inline fragment. */
InlineFragment = 'INLINE_FRAGMENT',
/** Location adjacent to a variable definition. */
VariableDefinition = 'VARIABLE_DEFINITION',
/** Location adjacent to a schema definition. */
Schema = 'SCHEMA',
/** Location adjacent to a scalar definition. */
Scalar = 'SCALAR',
/** Location adjacent to an object type definition. */
Object = 'OBJECT',
/** Location adjacent to a field definition. */
FieldDefinition = 'FIELD_DEFINITION',
/** Location adjacent to an argument definition. */
ArgumentDefinition = 'ARGUMENT_DEFINITION',
/** Location adjacent to an interface definition. */
Interface = 'INTERFACE',
/** Location adjacent to a union definition. */
Union = 'UNION',
/** Location adjacent to an enum definition. */
Enum = 'ENUM',
/** Location adjacent to an enum value definition. */
EnumValue = 'ENUM_VALUE',
/** Location adjacent to an input object type definition. */
InputObject = 'INPUT_OBJECT',
/** Location adjacent to an input object field definition. */
InputFieldDefinition = 'INPUT_FIELD_DEFINITION'
}
export type GetCargoBikeByIdQueryVariables = Exact<{
id: Scalars['ID'];
}>;
@ -1818,7 +1890,7 @@ export type GetCargoBikesQuery = (
{ __typename?: 'CargoBike' }
& CargoBikeFieldsFragment
)>> }
& IntrospectionFragment
& SchemaIntrospectionFragment
);
export type BikeEventFieldsFragment = (
@ -1867,7 +1939,7 @@ export type CargoBikeFieldsFragment = (
& CargoBikeFieldsMutableFragment
);
export type IntrospectionFragment = (
export type GroupIntrospectionFragment = (
{ __typename?: 'Query' }
& { __type?: Maybe<(
{ __typename?: '__Type' }
@ -1879,6 +1951,32 @@ export type IntrospectionFragment = (
)> }
);
export type SchemaIntrospectionFragment = (
{ __typename?: 'Query' }
& { __schema: (
{ __typename?: '__Schema' }
& { types: Array<(
{ __typename?: '__Type' }
& Pick<__Type, 'name' | 'kind'>
& { enumValues?: Maybe<Array<(
{ __typename?: '__EnumValue' }
& Pick<__EnumValue, 'name'>
)>>, fields?: Maybe<Array<(
{ __typename?: '__Field' }
& Pick<__Field, 'name'>
& { type: (
{ __typename?: '__Type' }
& Pick<__Type, 'name' | 'kind'>
& { ofType?: Maybe<(
{ __typename?: '__Type' }
& Pick<__Type, 'name' | 'kind'>
)> }
) }
)>> }
)> }
) }
);
export type LendingStationFieldsGeneralFragment = (
{ __typename?: 'LendingStation' }
& Pick<LendingStation, 'id' | 'name'>
@ -2050,8 +2148,8 @@ export const CargoBikeFieldsFragmentDoc = gql`
${CargoBikeFieldsMutableFragmentDoc}
${ProviderFieldsGeneralFragmentDoc}
${LendingStationFieldsGeneralFragmentDoc}`;
export const IntrospectionFragmentDoc = gql`
fragment Introspection on Query {
export const GroupIntrospectionFragmentDoc = gql`
fragment GroupIntrospection on Query {
__type(name: "Group") {
name
enumValues {
@ -2060,6 +2158,30 @@ export const IntrospectionFragmentDoc = gql`
}
}
`;
export const SchemaIntrospectionFragmentDoc = gql`
fragment SchemaIntrospection on Query {
__schema {
types {
name
kind
enumValues {
name
}
fields {
name
type {
name
kind
ofType {
name
kind
}
}
}
}
}
}
`;
export const GetCargoBikeByIdDocument = gql`
query GetCargoBikeById($id: ID!) {
cargoBikeById(id: $id) {
@ -2134,12 +2256,12 @@ export const UnlockCargoBikeDocument = gql`
}
export const GetCargoBikesDocument = gql`
query GetCargoBikes {
...Introspection
...SchemaIntrospection
cargoBikes(limit: 100, offset: 0) {
...CargoBikeFields
}
}
${IntrospectionFragmentDoc}
${SchemaIntrospectionFragmentDoc}
${CargoBikeFieldsFragmentDoc}`;
@Injectable({

Loading…
Cancel
Save