add getarticlepost
This commit is contained in:
parent
823b0c10b2
commit
3a5e2e8ce9
|
@ -1,30 +1,28 @@
|
|||
import { Article } from '@/components/Article'
|
||||
import { TableOfContents } from '@/components/TableOfContents'
|
||||
import { ArticleProps } from '@/pages/article/[slug]'
|
||||
import styled from '@emotion/styled'
|
||||
import { useState } from 'react'
|
||||
import { uiConfigs } from '@/configs/ui.configs'
|
||||
import { ArticleContainerContext } from '@/containers/ArticleContainer.Context'
|
||||
import { UnbodyGoogleDoc } from '@/lib/unbody/unbody.types'
|
||||
|
||||
const ArticleContainer = (props: ArticleProps) => {
|
||||
const { post } = props
|
||||
interface Props {
|
||||
data: UnbodyGoogleDoc
|
||||
}
|
||||
|
||||
const ArticleContainer = (props: Props) => {
|
||||
const { data } = props
|
||||
const [tocIndex, setTocIndex] = useState(0)
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{typeof post !== 'undefined' ? (
|
||||
<ArticleContainerContext.Provider
|
||||
value={{ tocIndex: tocIndex, setTocIndex: setTocIndex }}
|
||||
>
|
||||
<TableOfContents contents={post.toc ?? []} />
|
||||
<Article data={post} />
|
||||
<TableOfContents contents={data.toc ?? []} />
|
||||
{/*<Article data={data} />*/}
|
||||
<Right />
|
||||
</ArticleContainerContext.Provider>
|
||||
) : (
|
||||
<div style={{ marginTop: '108px', textAlign: 'center' }}>
|
||||
<h3>Loading</h3>
|
||||
</div>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ export namespace UnbodyGraphQl {
|
|||
result: string
|
||||
startPosition: number
|
||||
}
|
||||
|
||||
interface AdditionalnumbererpretationSource {
|
||||
concept: string
|
||||
occurrence: number
|
||||
|
@ -22,7 +23,7 @@ export namespace UnbodyGraphQl {
|
|||
}
|
||||
|
||||
interface AdditionalFeatureProjection {
|
||||
vector: [number]
|
||||
vector: number[]
|
||||
}
|
||||
|
||||
interface AdditionalNearestNeighborsNeighbor {
|
||||
|
@ -43,11 +44,11 @@ export namespace UnbodyGraphQl {
|
|||
}
|
||||
|
||||
interface AdditionalClassification {
|
||||
basedOn: [string]
|
||||
classifiedFields: [string]
|
||||
basedOn: string[]
|
||||
classifiedFields: string[]
|
||||
completed: string
|
||||
id: string
|
||||
scope: [string]
|
||||
scope: string[]
|
||||
}
|
||||
|
||||
export interface AdditionalProps {
|
||||
|
@ -58,7 +59,7 @@ export namespace UnbodyGraphQl {
|
|||
id: string
|
||||
lastUpdateTimeUnix: string
|
||||
score: string
|
||||
vector: [number]
|
||||
vector: number[]
|
||||
|
||||
interpretation: Additionalnumbererpretation
|
||||
nearestNeighbors: AdditionalNearestNeighbors
|
||||
|
@ -83,6 +84,7 @@ export namespace UnbodyGraphQl {
|
|||
|
||||
export namespace Fragments {
|
||||
export interface TocItem {}
|
||||
|
||||
export interface FootnoteItem {}
|
||||
}
|
||||
|
||||
|
@ -163,7 +165,7 @@ export namespace UnbodyGraphQl {
|
|||
organizerEmail: string
|
||||
organizerId: string
|
||||
organizerSelf: boolean
|
||||
recurrence: [string]
|
||||
recurrence: string[]
|
||||
remoteId: string
|
||||
sequence: number
|
||||
sourceId: string
|
||||
|
@ -176,8 +178,8 @@ export namespace UnbodyGraphQl {
|
|||
attachments: Array<ImageBlock>
|
||||
}
|
||||
|
||||
export namespace Explore {
|
||||
interface ExploreNearObjectInpObj {
|
||||
export namespace Filters {
|
||||
interface NearObjectInpObj {
|
||||
beacon?: string
|
||||
certainty?: number
|
||||
distance?: number
|
||||
|
@ -206,7 +208,7 @@ export namespace UnbodyGraphQl {
|
|||
force?: number
|
||||
}
|
||||
|
||||
interface Txt2VecC11yExploreNearTextInpObj {
|
||||
interface Txt2VecC11yNearTextInpObj {
|
||||
moveTo?: Txt2VecC11yExploreMoveTo
|
||||
certainty?: number
|
||||
distance?: number
|
||||
|
@ -214,24 +216,133 @@ export namespace UnbodyGraphQl {
|
|||
concepts?: string[]
|
||||
}
|
||||
|
||||
interface ExploreNearVectorInpObj {
|
||||
interface NearVectorInpObj {
|
||||
distance?: number
|
||||
vector?: number[]
|
||||
certainty?: number
|
||||
}
|
||||
|
||||
interface QnATransformersExploreAskInpObj {
|
||||
interface QnATransformersAskInpObj {
|
||||
question: string
|
||||
properties?: string[]
|
||||
}
|
||||
|
||||
export interface ExploreArgs {
|
||||
nearObject?: ExploreNearObjectInpObj
|
||||
nearText?: Txt2VecC11yExploreNearTextInpObj
|
||||
ask?: QnATransformersExploreAskInpObj
|
||||
nearObject?: NearObjectInpObj
|
||||
nearText?: Txt2VecC11yNearTextInpObj
|
||||
ask?: QnATransformersAskInpObj
|
||||
offset?: number
|
||||
limit?: number
|
||||
nearVector?: ExploreNearVectorInpObj
|
||||
nearVector?: NearVectorInpObj
|
||||
}
|
||||
|
||||
enum GroupInpObjTypeEnum {
|
||||
closest = 'closest',
|
||||
merge = 'merge',
|
||||
}
|
||||
|
||||
export interface GroupInpObj {
|
||||
force: number
|
||||
type: GroupInpObjTypeEnum
|
||||
}
|
||||
|
||||
export interface HybridInpObj {
|
||||
query: string
|
||||
alpha: number
|
||||
vector: number[]
|
||||
}
|
||||
|
||||
interface WhereGeoRangeGeoCoordinatesInpObj {
|
||||
latitude: number
|
||||
longitude: number
|
||||
}
|
||||
|
||||
interface WhereGeoRangeDistanceInpObj {
|
||||
max: number
|
||||
}
|
||||
|
||||
export interface WhereGeoRangeInpObj {
|
||||
geoCoordinates: WhereGeoRangeGeoCoordinatesInpObj
|
||||
distance: WhereGeoRangeDistanceInpObj
|
||||
}
|
||||
|
||||
export enum WhereOperatorEnum {
|
||||
GreaterThanEqual = 'GreaterThanEqual',
|
||||
WithinGeoRange = 'WithinGeoRange',
|
||||
IsNull = 'IsNull',
|
||||
And = 'And',
|
||||
Like = 'Like',
|
||||
Not = 'Not',
|
||||
NotEqual = 'NotEqual',
|
||||
GreaterThan = 'GreaterThan',
|
||||
LessThan = 'LessThan',
|
||||
LessThanEqual = 'LessThanEqual',
|
||||
Or = 'Or',
|
||||
Equal = 'Equal',
|
||||
}
|
||||
|
||||
export interface WhereOperandsInpObj {
|
||||
operator?: WhereOperatorEnum
|
||||
path: [String]
|
||||
operands?: [WhereOperandsInpObj]
|
||||
valueGeoRange?: WhereGeoRangeInpObj
|
||||
valueNumber?: number
|
||||
valueBoolean?: boolean
|
||||
valueString?: string
|
||||
valueText?: string
|
||||
valueDate?: string
|
||||
valueInt?: number
|
||||
}
|
||||
|
||||
export enum ObjTypeEnum {
|
||||
asc = 'asc',
|
||||
desc = 'desc',
|
||||
}
|
||||
|
||||
export interface Bm25InpObj {
|
||||
properties?: string[]
|
||||
query: string
|
||||
}
|
||||
|
||||
export interface AskInpObj {
|
||||
question: string
|
||||
properties?: string[]
|
||||
}
|
||||
|
||||
export interface SortInpObj {
|
||||
path: string[]
|
||||
order: string
|
||||
}
|
||||
|
||||
export interface WhereInpObj {
|
||||
path: string[]
|
||||
valueInt?: number
|
||||
valueNumber?: number
|
||||
valueGeoRange?: WhereGeoRangeInpObj
|
||||
operator?: WhereOperatorEnum
|
||||
operands?: WhereOperandsInpObj[]
|
||||
valueBoolean?: boolean
|
||||
valuestring?: string
|
||||
valueDate?: string
|
||||
valueText?: string
|
||||
valueString?: string
|
||||
}
|
||||
|
||||
export interface GetDocsArgs {
|
||||
where?: WhereInpObj
|
||||
bm25?: Bm25InpObj
|
||||
ask?: AskInpObj
|
||||
sort?: ObjTypeEnum[]
|
||||
|
||||
nearText?: Txt2VecC11yNearTextInpObj
|
||||
nearVector?: NearVectorInpObj
|
||||
nearObject?: NearObjectInpObj
|
||||
|
||||
offset?: number
|
||||
limit?: number
|
||||
|
||||
group?: GroupInpObj
|
||||
hybrid?: HybridInpObj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ export type UnbodyGoogleCalendarEvent = UnbodyGraphQl.GoogleCalendarEvent
|
|||
export type UnbodyTextBlock = UnbodyGraphQl.TextBlock
|
||||
export type UnbodyImageBlock = UnbodyGraphQl.ImageBlock
|
||||
export type UnbodyAudio = UnbodyGraphQl.AudioFile
|
||||
export type UnbodyExploreArgs = UnbodyGraphQl.Explore.ExploreArgs
|
||||
export type UnbodyGetFilters = UnbodyGraphQl.Filters.GetDocsArgs
|
||||
|
||||
export * as UnbodyGraphQl from './unbody-content.types'
|
||||
|
||||
export type UnbodyGraphQlResponse<T> = {
|
||||
data: {
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
import { UnbodyExploreArgs } from './unbody.types'
|
||||
import { UnbodyGetFilters } from './unbody.types'
|
||||
import { UnbodyGraphQl } from './unbody-content.types'
|
||||
|
||||
export const pareseExploreArgs = (args: UnbodyExploreArgs = {}): string => {
|
||||
const operators = Object.values(UnbodyGraphQl.Filters.WhereOperatorEnum)
|
||||
|
||||
export const parseFilterArgs = (args: UnbodyGetFilters = {}): string => {
|
||||
const parse = (obj: any): string | number => {
|
||||
if (typeof obj === 'number') {
|
||||
return obj
|
||||
}
|
||||
|
||||
if (
|
||||
typeof obj === 'string' &&
|
||||
operators.includes(obj as UnbodyGraphQl.Filters.WhereOperatorEnum)
|
||||
) {
|
||||
return obj
|
||||
}
|
||||
|
||||
//TODO needs to be improved in order to support more complex queries
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
const props = obj.map((value) => `${parse(value)}`).join(',')
|
||||
return `[${props}]`
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { GetStaticPropsContext } from 'next'
|
||||
import { ArticleLayout } from '@/layouts/ArticleLayout'
|
||||
import { ReactNode } from 'react'
|
||||
import ArticleContainer from '@/containers/ArticleContainer'
|
||||
import { UnbodyGoogleDoc, UnbodyImageBlock } from '@/lib/unbody/unbody.types'
|
||||
import {
|
||||
getAllArticlePostSlugs,
|
||||
getArticlePost,
|
||||
} from '@/services/unbody.service'
|
||||
import { ArticlePostData } from '@/types/data.types'
|
||||
|
||||
type ArticleProps = {
|
||||
data: ArticlePostData | null
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
|
||||
const { remoteId } = params!
|
||||
if (!remoteId) {
|
||||
return {
|
||||
notFound: true,
|
||||
}
|
||||
}
|
||||
|
||||
const article = await getArticlePost(remoteId as string)
|
||||
|
||||
return {
|
||||
props: {
|
||||
data: article,
|
||||
error: !!article,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// @jinho lets handle the error directly in thew page component
|
||||
const ArticlePage = (props: ArticleProps) => {
|
||||
if (!props.data) return <div>Opps...</div>
|
||||
|
||||
return (
|
||||
<div>{props.data.title}</div>
|
||||
// <ArticleContainer post={props.data}
|
||||
// error={props.error}
|
||||
// />
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getAllArticlePostSlugs()
|
||||
return {
|
||||
paths: posts.map((post) => ({ params: { remoteId: `${post.remoteId}` } })),
|
||||
fallback: true,
|
||||
}
|
||||
}
|
||||
|
||||
ArticlePage.getLayout = function getLayout(page: ReactNode) {
|
||||
return <ArticleLayout>{page}</ArticleLayout>
|
||||
}
|
||||
|
||||
export default ArticlePage
|
|
@ -1,67 +0,0 @@
|
|||
import { GetStaticPropsContext } from 'next'
|
||||
import { ArticleLayout } from '@/layouts/ArticleLayout'
|
||||
import { ReactNode } from 'react'
|
||||
import ArticleContainer from '@/containers/ArticleContainer'
|
||||
import { UnbodyGoogleDoc, UnbodyImageBlock } from '@/lib/unbody/unbody.types'
|
||||
import { getArticlePost } from '@/services/unbody.service'
|
||||
import { PostDataProps } from '@/components/Post/Post'
|
||||
|
||||
export type ArticleProps = {
|
||||
post: PostDataProps
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
|
||||
const slug = params?.slug
|
||||
console.log('slug', slug) // TODO : fetch data based on slug
|
||||
let post: Partial<UnbodyGoogleDoc> = {}
|
||||
let error = null
|
||||
|
||||
try {
|
||||
const posts = await getArticlePost()
|
||||
post = posts[0]
|
||||
} catch (e) {
|
||||
error = JSON.stringify(e)
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
post: {
|
||||
date: post.modifiedAt,
|
||||
title: post.title,
|
||||
summary: post.summary,
|
||||
//@ts-ignore
|
||||
blocks: post.blocks
|
||||
?.map((block) => `${block.html}\n`)
|
||||
.slice(2)
|
||||
.join(''), // temporary solution for HTML/CSS work
|
||||
author: 'Cameron Williamson',
|
||||
authorEmail: 'leo@acid.info',
|
||||
tags: ['Tools', 'Cyber Punk', 'Docs'],
|
||||
//@ts-ignore
|
||||
toc: JSON.parse(post?.toc),
|
||||
...(post.blocks && post.blocks!.length > 0
|
||||
? { coverImage: post.blocks![0] as UnbodyImageBlock }
|
||||
: {}),
|
||||
},
|
||||
error,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const ArticlePage = (props: ArticleProps) => {
|
||||
return <ArticleContainer post={props.post} error={props.error} />
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return {
|
||||
paths: [{ params: { slug: 'sth' } }],
|
||||
fallback: true,
|
||||
}
|
||||
}
|
||||
|
||||
ArticlePage.getLayout = function getLayout(page: ReactNode) {
|
||||
return <ArticleLayout>{page}</ArticleLayout>
|
||||
}
|
||||
|
||||
export default ArticlePage
|
|
@ -1,12 +1,11 @@
|
|||
import { GetGoogleDocQuery } from '.'
|
||||
import { UnbodyExploreArgs } from '@/lib/unbody/unbody.types'
|
||||
import { UnbodyGetFilters } from '@/lib/unbody/unbody.types'
|
||||
|
||||
const defaultArgs: UnbodyExploreArgs = {
|
||||
const defaultArgs: UnbodyGetFilters = {
|
||||
limit: 1,
|
||||
nearText: { concepts: ['home'] },
|
||||
}
|
||||
|
||||
export const getArticlePostQuery = (args: UnbodyExploreArgs = defaultArgs) =>
|
||||
export const getArticlePostQuery = (args: UnbodyGetFilters = defaultArgs) =>
|
||||
GetGoogleDocQuery(args)(`
|
||||
sourceId
|
||||
remoteId
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import { gql } from 'graphql-request'
|
||||
|
||||
import { GetGoogleDocQuery, GetQuery } from '.'
|
||||
import { pareseExploreArgs } from '@/lib/unbody/unbody.utils'
|
||||
import { UnbodyExploreArgs } from '@/lib/unbody/unbody.types'
|
||||
import { UnbodyGetFilters } from '@/lib/unbody/unbody.types'
|
||||
|
||||
const defaultArgs: UnbodyExploreArgs = {
|
||||
const defaultArgs: UnbodyGetFilters = {
|
||||
limit: 10,
|
||||
nearText: { concepts: ['home'] },
|
||||
}
|
||||
|
||||
export const getHomePagePostsQuery = (args: UnbodyExploreArgs = defaultArgs) =>
|
||||
export const getHomePagePostsQuery = (args: UnbodyGetFilters = defaultArgs) =>
|
||||
GetGoogleDocQuery(args)(`
|
||||
title
|
||||
summary
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { GetGoogleDocQuery } from '.'
|
||||
import { UnbodyGetFilters } from '@/lib/unbody/unbody.types'
|
||||
|
||||
const defaultArgs: UnbodyGetFilters = {}
|
||||
|
||||
export const getAllPostsSlugQuery = (args: UnbodyGetFilters = defaultArgs) =>
|
||||
GetGoogleDocQuery(args)(`
|
||||
remoteId
|
||||
`)
|
|
@ -1,7 +1,9 @@
|
|||
import { UnbodyExploreArgs } from '@/lib/unbody/unbody.types'
|
||||
import { pareseExploreArgs } from '@/lib/unbody/unbody.utils'
|
||||
import { UnbodyGetFilters } from '@/lib/unbody/unbody.types'
|
||||
import { parseFilterArgs } from '@/lib/unbody/unbody.utils'
|
||||
|
||||
export const GetQuery = (q: string) => `query { Get{ ${q} } }`
|
||||
|
||||
export const GetGoogleDocQuery = (args: UnbodyExploreArgs) => (q: string) =>
|
||||
GetQuery(`GoogleDoc(${pareseExploreArgs(args)}){ ${q} }`)
|
||||
export const GetGoogleDocQuery = (args: UnbodyGetFilters) => (q: string) => {
|
||||
if (Object.keys(args).length === 0) return GetQuery(`GoogleDoc{ ${q} }`)
|
||||
return GetQuery(`GoogleDoc(${parseFilterArgs(args)}){ ${q} }`)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,14 @@ import { UnbodyClient } from '@/lib/unbody/client.class'
|
|||
import {
|
||||
UnbodyGoogleDoc,
|
||||
UnbodyGraphQlResponseGoogleDoc,
|
||||
UnbodyGetFilters,
|
||||
} from '@/lib/unbody/unbody.types'
|
||||
|
||||
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
|
||||
|
||||
import { getArticlePostQuery } from '@/queries/getPost'
|
||||
import { getHomePagePostsQuery } from '@/queries/getPosts'
|
||||
import { getAllPostsSlugQuery } from '@/queries/getPostsSlugs'
|
||||
|
||||
const { UNBODY_API_KEY, UNBODY_LPE_PROJECT_ID } = process.env
|
||||
|
||||
|
@ -24,10 +29,33 @@ export const getHomepagePosts = (): Promise<HomepagePost[]> => {
|
|||
.then(({ data }) => data.Get.GoogleDoc)
|
||||
}
|
||||
|
||||
export const getArticlePost = (): Promise<HomepagePost[]> => {
|
||||
export const getAllArticlePostSlugs = (): Promise<{ remoteId: string }[]> => {
|
||||
console.log(getAllPostsSlugQuery())
|
||||
return unbody
|
||||
.request<UnbodyGraphQlResponseGoogleDoc>(getArticlePostQuery())
|
||||
.request<UnbodyGraphQlResponseGoogleDoc>(getAllPostsSlugQuery())
|
||||
.then(({ data }) => data.Get.GoogleDoc)
|
||||
}
|
||||
|
||||
export const getArticlePost = (id: string): Promise<UnbodyGoogleDoc> => {
|
||||
const query = getArticlePostQuery({
|
||||
where: {
|
||||
path: ['remoteId'],
|
||||
operator: UnbodyGraphQl.Filters.WhereOperatorEnum.Equal,
|
||||
valueString: id,
|
||||
},
|
||||
})
|
||||
|
||||
return unbody
|
||||
.request<UnbodyGraphQlResponseGoogleDoc>(getArticlePostQuery())
|
||||
.then(({ data }) => {
|
||||
const article = data.Get.GoogleDoc[0]
|
||||
return {
|
||||
...article,
|
||||
toc: JSON.parse(
|
||||
article.toc as string,
|
||||
) as Array<UnbodyGraphQl.Fragments.TocItem>,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default unbody
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { UnbodyGoogleDoc } from '@/lib/unbody/unbody.types'
|
||||
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
|
||||
|
||||
export interface ArticlePostData extends UnbodyGoogleDoc {
|
||||
toc: Array<UnbodyGraphQl.Fragments.TocItem>
|
||||
}
|
Loading…
Reference in New Issue