Using GraphQL SDL to generate the TypeScript Types
This commit is contained in:
parent
3d2cf6d594
commit
702dc74ab6
|
@ -1,11 +1,8 @@
|
|||
import { ChronologyItemEntity, Maybe } from "graphql/operations-types";
|
||||
import styles from "styles/Chronology/ChronologyItemComponent.module.css";
|
||||
import {
|
||||
ChronologyItem,
|
||||
ChronologyItemsEvent,
|
||||
} from "queries/chronology/overview";
|
||||
|
||||
export type ChronologyItemComponentProps = {
|
||||
item: ChronologyItem;
|
||||
item: ChronologyItemEntity;
|
||||
displayYear: boolean;
|
||||
};
|
||||
|
||||
|
@ -14,9 +11,8 @@ export default function ChronologyItemComponent(
|
|||
): JSX.Element {
|
||||
function generateAnchor(
|
||||
year: number,
|
||||
month: number,
|
||||
day: number,
|
||||
event?: number
|
||||
month: Maybe<number> | undefined,
|
||||
day: Maybe<number> | undefined
|
||||
): string {
|
||||
let result: string = "";
|
||||
result += year;
|
||||
|
@ -25,7 +21,10 @@ export default function ChronologyItemComponent(
|
|||
return result;
|
||||
}
|
||||
|
||||
function generateYear(displayed_date: string, year: number): string {
|
||||
function generateYear(
|
||||
displayed_date: Maybe<string> | undefined,
|
||||
year: number
|
||||
): string {
|
||||
if (displayed_date) {
|
||||
return displayed_date;
|
||||
} else {
|
||||
|
@ -33,7 +32,10 @@ export default function ChronologyItemComponent(
|
|||
}
|
||||
}
|
||||
|
||||
function generateDate(month: number, day: number): string {
|
||||
function generateDate(
|
||||
month: Maybe<number> | undefined,
|
||||
day: Maybe<number> | undefined
|
||||
): string {
|
||||
let lut = [
|
||||
"Jan",
|
||||
"Feb",
|
||||
|
@ -60,6 +62,7 @@ export default function ChronologyItemComponent(
|
|||
return result;
|
||||
}
|
||||
|
||||
if (props.item && props.item.attributes) {
|
||||
return (
|
||||
<div
|
||||
className={styles.chronologyItem}
|
||||
|
@ -85,16 +88,27 @@ export default function ChronologyItemComponent(
|
|||
</p>
|
||||
|
||||
<div className={styles.events}>
|
||||
{props.item.attributes.events.map((event: ChronologyItemsEvent) => (
|
||||
{props.item.attributes.events?.map((event) => {
|
||||
if (event) {
|
||||
return (
|
||||
<div className={styles.event} key={event.id}>
|
||||
{event.translations.map((translation) => (
|
||||
{event.translations?.map((translation) => {
|
||||
if (translation)
|
||||
return (
|
||||
<>
|
||||
{translation.title ? <h3>{translation.title}</h3> : ""}
|
||||
{translation.title ? (
|
||||
<h3>{translation.title}</h3>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{translation.description ? (
|
||||
<p
|
||||
className={
|
||||
event.translations.length > 1 ? styles.bulletItem : ""
|
||||
event.translations &&
|
||||
event.translations.length > 1
|
||||
? styles.bulletItem
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{translation.description}
|
||||
|
@ -108,16 +122,24 @@ export default function ChronologyItemComponent(
|
|||
""
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
|
||||
<p className={styles.source}>
|
||||
{event.source.data
|
||||
{event.source &&
|
||||
event.source.data &&
|
||||
event.source.data.attributes
|
||||
? "(" + event.source.data.attributes.name + ")"
|
||||
: "(WARNING: NO SOURCE!)"}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import styles from "styles/Chronology/ChronologyYearComponent.module.css";
|
||||
import { ChronologyItem } from "queries/chronology/overview";
|
||||
import ChronologyItemComponent from "components/Chronology/ChronologyItemComponent";
|
||||
import { ChronologyItemEntity } from "graphql/operations-types";
|
||||
|
||||
type ChronologyYearComponentProps = {
|
||||
items: ChronologyItem[];
|
||||
year: number;
|
||||
items: ChronologyItemEntity[];
|
||||
};
|
||||
|
||||
export default function ChronologyYearComponent(
|
||||
|
@ -12,13 +13,9 @@ export default function ChronologyYearComponent(
|
|||
return (
|
||||
<div
|
||||
className={styles.chronologyYear}
|
||||
id={
|
||||
props.items.length > 1
|
||||
? props.items[0].attributes.year.toString()
|
||||
: undefined
|
||||
}
|
||||
id={props.items.length > 1 ? props.year.toString() : undefined}
|
||||
>
|
||||
{props.items.map((item: ChronologyItem, index: number) => (
|
||||
{props.items.map((item: ChronologyItemEntity, index: number) => (
|
||||
<ChronologyItemComponent
|
||||
key={index}
|
||||
item={item}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import styles from "styles/Library/LibraryItemComponent.module.css";
|
||||
import { LibraryItem } from "queries/library";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { BasicDate, getAssetURL } from "queries/helpers";
|
||||
import { LibraryItemEntity } from "graphql/operations-types";
|
||||
|
||||
export type LibraryItemComponentProps = {
|
||||
item: LibraryItem;
|
||||
item: LibraryItemEntity;
|
||||
};
|
||||
|
||||
export default function LibraryItemComponent(
|
||||
|
|
|
@ -5,7 +5,7 @@ import Link from "next/link";
|
|||
type NavOptionProps = {
|
||||
url: string;
|
||||
icon?: string;
|
||||
title: string;
|
||||
title: string | null | undefined;
|
||||
subtitle?: string;
|
||||
border?: boolean;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
query getEras($language_code: String) {
|
||||
chronologyEras {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
slug
|
||||
starting_year
|
||||
ending_year
|
||||
title(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query getChronologyItems($language_code: String) {
|
||||
chronologyItems(
|
||||
pagination: { limit: -1 }
|
||||
sort: ["year:asc", "month:asc", "day:asc"]
|
||||
) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
year
|
||||
month
|
||||
day
|
||||
displayed_date
|
||||
events {
|
||||
id
|
||||
source {
|
||||
data {
|
||||
attributes {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
translations(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
description
|
||||
note
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query getLibraryItemsPreview($language_code: String) {
|
||||
libraryItems(
|
||||
filters: { root_item: { eq: true } }
|
||||
pagination: { limit: -1 }
|
||||
sort: ["slug:asc"]
|
||||
) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
title
|
||||
subtitle
|
||||
slug
|
||||
thumbnail {
|
||||
data {
|
||||
attributes {
|
||||
name
|
||||
alternativeText
|
||||
caption
|
||||
width
|
||||
height
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
release_date {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
price {
|
||||
amount
|
||||
currency {
|
||||
data {
|
||||
attributes {
|
||||
symbol
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
size {
|
||||
width
|
||||
height
|
||||
thickness
|
||||
}
|
||||
descriptions(filters: { language: { code: { eq: $language_code } } }) {
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
import {
|
||||
GetChronologyItemsQuery,
|
||||
GetChronologyItemsQueryVariables,
|
||||
GetErasQuery,
|
||||
GetErasQueryVariables,
|
||||
GetLibraryItemsPreviewQuery,
|
||||
GetLibraryItemsPreviewQueryVariables,
|
||||
} from "graphql/operations-types";
|
||||
|
||||
const graphQL = async (query: string, variables?: string) => {
|
||||
const res = await fetch(process.env.URL_GRAPHQL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
query: query,
|
||||
variables: variables,
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
Authorization: "Bearer " + process.env.ACCESS_TOKEN,
|
||||
},
|
||||
});
|
||||
return (await res.json()).data;
|
||||
};
|
||||
|
||||
function getQueryFromOperations(queryName: string): string {
|
||||
const fs = require("fs");
|
||||
const operations: string = fs.readFileSync(
|
||||
"./src/graphql/operation.graphql",
|
||||
"utf8"
|
||||
);
|
||||
let startingIndex = -1;
|
||||
let endingIndex = -1;
|
||||
const lines = operations.split("\n");
|
||||
lines.map((line, index) => {
|
||||
if (startingIndex === -1) {
|
||||
if (line.startsWith(`query ${queryName}`)) startingIndex = index;
|
||||
} else if (endingIndex === -1) {
|
||||
if (line.startsWith("query")) endingIndex = index;
|
||||
}
|
||||
});
|
||||
return lines.slice(startingIndex, endingIndex).join("\n");
|
||||
}
|
||||
|
||||
export async function getEras(
|
||||
variables: GetErasQueryVariables
|
||||
): Promise<GetErasQuery> {
|
||||
const query = getQueryFromOperations("getEras");
|
||||
return await graphQL(query, JSON.stringify(variables));
|
||||
}
|
||||
|
||||
export async function getChronologyItems(
|
||||
variables: GetChronologyItemsQueryVariables
|
||||
): Promise<GetChronologyItemsQuery> {
|
||||
const query = getQueryFromOperations("getChronologyItems");
|
||||
return await graphQL(query, JSON.stringify(variables));
|
||||
}
|
||||
|
||||
export async function getLibraryItemsPreview(
|
||||
variables: GetLibraryItemsPreviewQueryVariables
|
||||
): Promise<GetLibraryItemsPreviewQuery> {
|
||||
const query = getQueryFromOperations("getLibraryItemsPreview");
|
||||
return await graphQL(query, JSON.stringify(variables));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,19 +4,18 @@ import SubPanel from "components/Panels/SubPanel";
|
|||
import ReturnButton from "components/Panels/ReturnButton";
|
||||
import NavOption from "components/Panels/NavOption";
|
||||
import ChronologyYearComponent from "components/Chronology/ChronologyYearComponent";
|
||||
import {
|
||||
getChronologyItems,
|
||||
getChronologyEras,
|
||||
ChronologyItem,
|
||||
ChronologyItemsEvent,
|
||||
} from "queries/chronology/overview";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import { ChronologyEraEntityResponseCollection } from "queries/types";
|
||||
import {
|
||||
ChronologyItemEntity,
|
||||
GetChronologyItemsQuery,
|
||||
GetErasQuery,
|
||||
} from "graphql/operations-types";
|
||||
import { getEras, getChronologyItems } from "graphql/operations";
|
||||
|
||||
type Props = {
|
||||
chronologyItems: ChronologyItem[];
|
||||
chronologyEras: ChronologyEraEntityResponseCollection;
|
||||
};
|
||||
interface Props {
|
||||
chronologyItems: GetChronologyItemsQuery;
|
||||
chronologyEras: GetErasQuery;
|
||||
}
|
||||
|
||||
applyCustomAppProps(ChronologyOverview, {
|
||||
useSubPanel: true,
|
||||
|
@ -25,68 +24,66 @@ applyCustomAppProps(ChronologyOverview, {
|
|||
|
||||
export default function ChronologyOverview(props: Props): JSX.Element {
|
||||
// Group by year the Chronology items
|
||||
let chronologyItemYearGroups: ChronologyItem[][] = [];
|
||||
props.chronologyItems.map((item: ChronologyItem) => {
|
||||
|
||||
let chronologyItemYearGroups: ChronologyItemEntity[][] = [];
|
||||
|
||||
if (props.chronologyItems.chronologyItems) {
|
||||
props.chronologyItems.chronologyItems.data.map((item) => {
|
||||
if (item && item.attributes) {
|
||||
if (!chronologyItemYearGroups.hasOwnProperty(item.attributes.year)) {
|
||||
chronologyItemYearGroups[item.attributes.year] = [item];
|
||||
} else {
|
||||
chronologyItemYearGroups[item.attributes.year].push(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<SubPanel>
|
||||
|
||||
<ReturnButton url="/chronology" title="Chronology" />
|
||||
<hr />
|
||||
|
||||
{props.chronologyEras.data.map((era) => (
|
||||
{props.chronologyEras.chronologyEras
|
||||
? props.chronologyEras.chronologyEras.data.map((era) => (
|
||||
<>
|
||||
{era.attributes && era.attributes.title ? (
|
||||
<NavOption
|
||||
key={era.id}
|
||||
url={"#" + era.attributes.slug}
|
||||
title={
|
||||
era.attributes.title.length ? era.attributes.title[0].title : ""
|
||||
era.attributes.title[0]
|
||||
? era.attributes.title[0].title
|
||||
: ""
|
||||
}
|
||||
subtitle={
|
||||
era.attributes.starting_year + " → " + era.attributes.ending_year
|
||||
era.attributes.starting_year +
|
||||
" → " +
|
||||
era.attributes.ending_year
|
||||
}
|
||||
border={true}
|
||||
/>
|
||||
))}
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
))
|
||||
: ""}
|
||||
</SubPanel>
|
||||
|
||||
<ContentPanel>
|
||||
{props.chronologyItems.map((item: ChronologyItem) => {
|
||||
if (!item.attributes.year)
|
||||
console.warn("Missing year on ChronologyItem (" + item.id + ")");
|
||||
item.attributes.events.map((event: ChronologyItemsEvent) => {
|
||||
if (!event.source.data) {
|
||||
console.warn(
|
||||
"Missing Source on ChronologyItem (" +
|
||||
item.id +
|
||||
"), Event (" +
|
||||
event.id +
|
||||
")"
|
||||
{chronologyItemYearGroups.map((items, index: number) => {
|
||||
if (items && items[0].attributes?.year) {
|
||||
return (
|
||||
<ChronologyYearComponent
|
||||
key={index}
|
||||
year={items[0].attributes?.year}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (event.translations.length < 1) {
|
||||
console.warn(
|
||||
"Missing Translation on ChronologyItem (" +
|
||||
item.id +
|
||||
"), Event (" +
|
||||
event.id +
|
||||
")"
|
||||
);
|
||||
}
|
||||
});
|
||||
})}
|
||||
|
||||
{chronologyItemYearGroups.map(
|
||||
(items: ChronologyItem[], index: number) => {
|
||||
return <ChronologyYearComponent key={index} items={items} />;
|
||||
}
|
||||
)}
|
||||
</ContentPanel>
|
||||
</>
|
||||
);
|
||||
|
@ -95,8 +92,10 @@ export default function ChronologyOverview(props: Props): JSX.Element {
|
|||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
return {
|
||||
props: {
|
||||
chronologyItems: await getChronologyItems(context.locale),
|
||||
chronologyEras: await getChronologyEras(context.locale),
|
||||
chronologyItems: await getChronologyItems({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
chronologyEras: await getEras({ language_code: context.locale }),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { GetStaticProps } from "next";
|
||||
import SubPanel from "components/Panels/SubPanel";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import { LibraryItem, getLibraryItems } from "queries/library/index";
|
||||
import LibraryItemComponent from "components/Library/LibraryItemComponent";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import { GetLibraryItemsPreviewQuery } from "graphql/operations-types";
|
||||
import { getLibraryItemsPreview } from "graphql/operations";
|
||||
|
||||
type Props = {
|
||||
libraryItems: LibraryItem[];
|
||||
libraryItems: GetLibraryItemsPreviewQuery;
|
||||
};
|
||||
|
||||
applyCustomAppProps(Library, {
|
||||
|
@ -15,6 +16,8 @@ applyCustomAppProps(Library, {
|
|||
});
|
||||
|
||||
export default function Library(props: Props): JSX.Element {
|
||||
|
||||
console.log(props);
|
||||
return (
|
||||
<>
|
||||
<SubPanel>
|
||||
|
@ -29,7 +32,7 @@ export default function Library(props: Props): JSX.Element {
|
|||
</SubPanel>
|
||||
|
||||
<ContentPanel>
|
||||
{props.libraryItems.map((item: LibraryItem) => (
|
||||
{props.libraryItems.libraryItems?.data.map((item) => (
|
||||
<LibraryItemComponent key={item.id} item={item} />
|
||||
))}
|
||||
</ContentPanel>
|
||||
|
@ -40,7 +43,7 @@ export default function Library(props: Props): JSX.Element {
|
|||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
return {
|
||||
props: {
|
||||
libraryItems: await getLibraryItems(context.locale),
|
||||
libraryItems: await getLibraryItemsPreview({language_code: context.locale}),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
import { queryGraphQL } from "queries/helpers";
|
||||
import { Source } from "queries/helpers";
|
||||
import { ChronologyEraEntityResponseCollection } from "queries/types";
|
||||
|
||||
export type ChronologyItem = {
|
||||
id: string;
|
||||
attributes: {
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
displayed_date: string;
|
||||
events: ChronologyItemsEvent[];
|
||||
};
|
||||
};
|
||||
|
||||
export type ChronologyItemsEvent = {
|
||||
id: string;
|
||||
source: Source;
|
||||
translations: {
|
||||
title: string;
|
||||
description: string;
|
||||
note: string;
|
||||
status: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export async function getChronologyItems(
|
||||
language_code: string | undefined
|
||||
): Promise<ChronologyItem[]> {
|
||||
return (
|
||||
await queryGraphQL(
|
||||
`
|
||||
{
|
||||
chronologyItems (pagination: {limit: -1}, sort: ["year:asc", "month:asc", "day:asc"]) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
year
|
||||
month
|
||||
day
|
||||
displayed_date
|
||||
events {
|
||||
id
|
||||
source {
|
||||
data {
|
||||
attributes {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
translations(filters: { language: { code: { eq: "${language_code}" } } }) {
|
||||
title
|
||||
description
|
||||
note
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
).chronologyItems.data;
|
||||
}
|
||||
|
||||
/*
|
||||
export type ChronologyEra = {
|
||||
id: string;
|
||||
attributes: ChronologyEraAttributes;
|
||||
};
|
||||
|
||||
export type ChronologyEraAttributes = {
|
||||
slug: string;
|
||||
starting_year: number;
|
||||
ending_year: number;
|
||||
title: ChronologyEraTranslation[];
|
||||
};
|
||||
|
||||
export type ChronologyEraTranslation = {
|
||||
title: string;
|
||||
};
|
||||
*/
|
||||
|
||||
export async function getChronologyEras(
|
||||
language_code: string | undefined
|
||||
): Promise<ChronologyEraEntityResponseCollection> {
|
||||
return (
|
||||
await queryGraphQL(
|
||||
`
|
||||
{
|
||||
chronologyEras {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
slug
|
||||
starting_year
|
||||
ending_year
|
||||
title (filters: {language: {code: {eq: "${language_code}"}}}){
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
).chronologyEras;
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
export const queryGraphQL = async (query: String) => {
|
||||
export const queryGraphQL = async (query: string, variables?: string) => {
|
||||
const res = await fetch(process.env.URL_GRAPHQL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
query: query,
|
||||
variables: variables
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
|
@ -12,17 +13,6 @@ export const queryGraphQL = async (query: String) => {
|
|||
return (await res.json()).data;
|
||||
};
|
||||
|
||||
export const queryGraphQLSystem = async (query: string) => {
|
||||
const res = await fetch(
|
||||
process.env.URL_GRAPHQL_SYSTEM +
|
||||
"?access_token=" +
|
||||
process.env.ACCESS_TOKEN +
|
||||
"&query=" +
|
||||
query
|
||||
);
|
||||
return (await res.json()).data;
|
||||
};
|
||||
|
||||
export function getAssetURL(url: string): string {
|
||||
return process.env.NEXT_PUBLIC_URL_CMS + url;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue