Add app info dialog
This commit is contained in:
parent
3c1f07f3b0
commit
3992429236
15 changed files with 254 additions and 3 deletions
23
backend/package-lock.json
generated
23
backend/package-lock.json
generated
|
@ -1412,6 +1412,14 @@
|
|||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz",
|
||||
"integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==",
|
||||
"requires": {
|
||||
"node-fetch": "2.6.1"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
|
@ -2056,6 +2064,11 @@
|
|||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
|
||||
},
|
||||
"extract-files": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
|
||||
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
|
||||
},
|
||||
"fast-decode-uri-component": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
|
||||
|
@ -2484,6 +2497,16 @@
|
|||
"lodash.get": "^4.4.2"
|
||||
}
|
||||
},
|
||||
"graphql-request": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz",
|
||||
"integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==",
|
||||
"requires": {
|
||||
"cross-fetch": "^3.0.6",
|
||||
"extract-files": "^9.0.0",
|
||||
"form-data": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"graphql-subscriptions": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.1.0.tgz",
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
"fastify-sensible": "^3.1.0",
|
||||
"fastify-session": "^5.2.1",
|
||||
"got": "^11.8.1",
|
||||
"graphql-request": "^3.4.0",
|
||||
"graphql-tag": "^2.11.0",
|
||||
"lodash": "^4.17.20",
|
||||
"mongodb": "^3.6.3",
|
||||
"nanoid": "^3.1.20",
|
||||
|
|
|
@ -28,6 +28,12 @@ export default class Application extends BaseEntity {
|
|||
@Column()
|
||||
public redirectUris!: string[];
|
||||
|
||||
@Column()
|
||||
public ownerGitHubLogin!: string;
|
||||
|
||||
@Column()
|
||||
public homepage!: string | null;
|
||||
|
||||
public static generateClientId(): string {
|
||||
return nanoid(12);
|
||||
}
|
||||
|
|
20
backend/src/graphql/github/queries/get-user.ts
Normal file
20
backend/src/graphql/github/queries/get-user.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import gql from 'graphql-tag';
|
||||
|
||||
export const getUserQuery = gql`query GetUser($login: String!) {
|
||||
user(login: $login) {
|
||||
login
|
||||
name
|
||||
url
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export interface User {
|
||||
login: string;
|
||||
name: string | null;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface GetUserQueryResult {
|
||||
user: User
|
||||
}
|
14
backend/src/graphql/github/sdk.ts
Normal file
14
backend/src/graphql/github/sdk.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { GraphQLClient } from 'graphql-request';
|
||||
import { requireEnv } from '../../utils';
|
||||
import type { GetUserQueryResult, User } from './queries/get-user';
|
||||
import { getUserQuery } from './queries/get-user';
|
||||
|
||||
const client = new GraphQLClient('https://api.github.com/graphql');
|
||||
client.setHeader('Authorization', `bearer ${requireEnv('GITHUB_API_TOKEN')}`);
|
||||
|
||||
export async function getUser(login: string): Promise<User> {
|
||||
const { user } = await client.request<GetUserQueryResult>(getUserQuery, {
|
||||
login,
|
||||
});
|
||||
return user;
|
||||
}
|
15
backend/src/routes/website-api/models/github-user.ts
Normal file
15
backend/src/routes/website-api/models/github-user.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { Field, ObjectType } from 'type-graphql';
|
||||
|
||||
@ObjectType()
|
||||
export default class GitHubUser {
|
||||
@Field(() => String)
|
||||
public login!: string;
|
||||
|
||||
@Field(() => String, {
|
||||
nullable: true,
|
||||
})
|
||||
public name!: string | null;
|
||||
|
||||
@Field(() => String)
|
||||
public url!: string;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import { Field, ObjectType } from 'type-graphql';
|
||||
import GitHubUser from './github-user';
|
||||
|
||||
@ObjectType()
|
||||
export default class PromptInfoApplication {
|
||||
|
@ -15,4 +16,12 @@ export default class PromptInfoApplication {
|
|||
|
||||
@Field(() => Boolean)
|
||||
public verified!: boolean;
|
||||
|
||||
@Field(() => GitHubUser)
|
||||
public owner!: GitHubUser;
|
||||
|
||||
@Field(() => String, {
|
||||
nullable: true,
|
||||
})
|
||||
public homepage!: string | null;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
Arg, Ctx, FieldResolver, Query, Resolver, Root,
|
||||
} from 'type-graphql';
|
||||
import database from '../../../database/database';
|
||||
import { getUser } from '../../../graphql/github/sdk';
|
||||
import { UnknownPromptError } from '../errors';
|
||||
import PromptInfo from '../models/prompt-info';
|
||||
import type PromptInfoApplication from '../models/prompt-info-application';
|
||||
|
@ -39,6 +40,8 @@ export default class PromptInfoResolver implements ResolverInterface<PromptInfo>
|
|||
iconUrl: application.iconUrl,
|
||||
iconColor: application.iconColor,
|
||||
verified: application.verified,
|
||||
homepage: application.homepage,
|
||||
owner: await getUser(application.ownerGitHubLogin),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<template>
|
||||
<v-dialog v-model="value" max-width="450">
|
||||
<template #activator="{ on: dialogOn }">
|
||||
<v-tooltip bottom>
|
||||
<template #activator="{ on: tooltipOn }">
|
||||
<v-card
|
||||
class="d-inline-block px-1"
|
||||
color="primary--text"
|
||||
rounded
|
||||
flat
|
||||
v-on="{ ...dialogOn, ...tooltipOn }"
|
||||
link
|
||||
>
|
||||
{{ promptInfo.application.name }}
|
||||
</v-card>
|
||||
</template>
|
||||
Kliknij aby zobaczyć informacje o aplikacji
|
||||
</v-tooltip>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
Informacje o aplikacji
|
||||
</v-card-title>
|
||||
<v-list>
|
||||
<v-list-item>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-information</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="text-overline">
|
||||
Nazwa aplikacji
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-title>
|
||||
{{ promptInfo.application.name }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="promptInfo.application.homepage"
|
||||
:href="promptInfo.application.homepage"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-home</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="text-overline">
|
||||
Strona domowa
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-title>
|
||||
{{ promptInfo.application.homepage }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
:href="promptInfo.application.owner.url"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-github</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="text-overline">
|
||||
Twórca
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-title v-if="promptInfo.application.owner.name">
|
||||
{{ promptInfo.application.owner.name }}
|
||||
<span class="text--secondary">
|
||||
({{ promptInfo.application.owner.login }})
|
||||
</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-title v-else>
|
||||
{{ promptInfo.application.owner.login }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-alert
|
||||
color="green"
|
||||
icon="mdi-check"
|
||||
text
|
||||
class="mx-2"
|
||||
v-if="promptInfo.application.verified"
|
||||
>
|
||||
Aplikacja zweryfikowana
|
||||
</v-alert>
|
||||
<v-alert
|
||||
color="grey darken-2"
|
||||
icon="mdi-close"
|
||||
text
|
||||
class="mx-2"
|
||||
v-else
|
||||
>
|
||||
Aplikacja nie została zweryfikowana
|
||||
</v-alert>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="primary" text @click="value = false">Zamknij</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import { PromptInfo } from '@/types';
|
||||
|
||||
@Component({
|
||||
name: 'AppInfoDialog',
|
||||
})
|
||||
export default class AppInfoDialog extends Vue {
|
||||
@Prop({
|
||||
required: true,
|
||||
type: Object,
|
||||
})
|
||||
promptInfo!: PromptInfo;
|
||||
|
||||
value = false;
|
||||
}
|
||||
</script>
|
|
@ -3,7 +3,7 @@
|
|||
<div class="pt-16">
|
||||
<h2 class="text-subtitle-1 text--secondary mt-6 mb-2 px-4">
|
||||
Aplikacja
|
||||
<span class="text--primary">{{ promptInfo.application.name }}</span>
|
||||
<app-info-dialog :prompt-info="promptInfo" />
|
||||
chce uzyskać dostęp do twojego konta VULCAN UONET+ przez Wulkanowy Bridge
|
||||
</h2>
|
||||
<v-subheader>Uprawnienia aplikacji</v-subheader>
|
||||
|
@ -46,9 +46,11 @@
|
|||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import { PromptInfo } from '@/types';
|
||||
import AppInfoDialog from '@/compontents/authenticate-prompt-windows/app-info-dialog.vue';
|
||||
|
||||
@Component({
|
||||
name: 'OverviewWindow',
|
||||
components: { AppInfoDialog },
|
||||
})
|
||||
export default class OverviewWindow extends Vue {
|
||||
@Prop({
|
||||
|
|
|
@ -31,5 +31,9 @@ export default class DialogApp extends Vue {
|
|||
.v-card__text, .v-card__title {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.no-basis {
|
||||
flex-basis: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -45,6 +45,15 @@ export type PromptInfoApplication = {
|
|||
iconUrl: Maybe<Scalars['String']>;
|
||||
iconColor: Scalars['String'];
|
||||
verified: Scalars['Boolean'];
|
||||
owner: GitHubUser;
|
||||
homepage: Maybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type GitHubUser = {
|
||||
__typename?: 'GitHubUser';
|
||||
login: Scalars['String'];
|
||||
name: Maybe<Scalars['String']>;
|
||||
url: Scalars['String'];
|
||||
};
|
||||
|
||||
export type Mutation = {
|
||||
|
@ -101,7 +110,11 @@ export type GetPromptInfoQuery = (
|
|||
& Pick<PromptInfo, 'id' | 'scopes' | 'studentsMode'>
|
||||
& { application: (
|
||||
{ __typename?: 'PromptInfoApplication' }
|
||||
& Pick<PromptInfoApplication, 'name' | 'iconUrl' | 'iconColor' | 'verified'>
|
||||
& Pick<PromptInfoApplication, 'name' | 'iconUrl' | 'iconColor' | 'verified' | 'homepage'>
|
||||
& { owner: (
|
||||
{ __typename?: 'GitHubUser' }
|
||||
& Pick<GitHubUser, 'login' | 'name' | 'url'>
|
||||
); }
|
||||
); }
|
||||
); }
|
||||
);
|
||||
|
@ -133,6 +146,12 @@ export const GetPromptInfoDocument = gql`
|
|||
iconUrl
|
||||
iconColor
|
||||
verified
|
||||
homepage
|
||||
owner {
|
||||
login
|
||||
name
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ export default gql`query GetPromptInfo($promptId: String!) {
|
|||
iconUrl
|
||||
iconColor
|
||||
verified
|
||||
homepage
|
||||
owner {
|
||||
login
|
||||
name
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<style lang="scss">
|
||||
.authenticate-prompt-app {
|
||||
.avatar-sheet {
|
||||
border-radius: 50%;
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
|
||||
.fill-height {
|
||||
|
|
|
@ -13,6 +13,12 @@ export interface PromptInfo {
|
|||
iconUrl: string | null;
|
||||
iconColor: string;
|
||||
verified: boolean;
|
||||
homepage: string | null;
|
||||
owner: {
|
||||
login: string;
|
||||
name: string | null;
|
||||
url: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue