import { useState, useEffect } from 'react' import { siteConfig } from 'site/site.config.mjs' import { nsMerge } from 'shared/utils.mjs' import { UserIcon, FlagIcon, ChatIcon, BoolYesIcon, WarningIcon, DownIcon, } from 'shared/components/icons.mjs' import { TimeAgo, ns as timeAgoNs } from 'shared/components/timeago/index.mjs' import { Mdx } from 'shared/components/mdx/dynamic.mjs' import { WebLink } from 'shared/components/link.mjs' import { useTranslation } from 'next-i18next' export const ns = nsMerge('support', timeAgoNs) /* * GitHub GraphQL queries must be properly quoted and can't handle newlines */ const query = { open: 'query { ' + 'repository(owner: "freesewing", name: "freesewing") { ' + ' issues(states: OPEN, labels: ["statusReported", "statusConfirmed"], first: 20) { ' + ' nodes { ' + ' title body createdAt url number updatedAt ' + ' author { login url } ' + ' labels (first: 5) { edges { node { name } } } ' + ' comments(last: 3) { edges { node { body createdAt url author { login url } } } } ' + ' timelineItems(last: 15, itemTypes:[ ISSUE_COMMENT, CLOSED_EVENT,ASSIGNED_EVENT,REOPENED_EVENT, REFERENCED_EVENT]) { edges { node { ' + ' __typename ' + ' ... on ClosedEvent { createdAt actor { url login } } ' + ' ... on ReopenedEvent { createdAt actor { url login } } ' + ' ... on ReferencedEvent { createdAt actor { url login } commit { url oid message } } ' + ' ... on IssueComment { createdAt body url author { url login } } ' + ' ... on AssignedEvent { createdAt actor { url login } assignee { ... on User { login url } } } ' + ' } } } ' + ' } } } } ', closed: 'query { ' + 'repository(owner: "freesewing", name: "freesewing") { ' + ' issues(states: CLOSED, labels: ["statusResolved"], first: 20) { ' + ' nodes { ' + ' title body url number createdAt closedAt ' + ' author { login url } ' + ' comments(last: 3) { edges { node { body createdAt url author { login url } } } } ' + ' timelineItems(last: 15, itemTypes:[ ISSUE_COMMENT, CLOSED_EVENT,ASSIGNED_EVENT,REOPENED_EVENT, REFERENCED_EVENT]) { edges { node { ' + ' __typename ' + ' ... on ClosedEvent { createdAt actor { url login } } ' + ' ... on ReopenedEvent { createdAt actor { url login } } ' + ' ... on ReferencedEvent { createdAt actor { url login } commit { url oid message } } ' + ' ... on IssueComment { createdAt body url author { url login } } ' + ' ... on AssignedEvent { createdAt actor { url login } assignee { ... on User { login url } } } ' + ' } } } ' + ' } } } } ', } /* * Helper method * Runs a GraphQL query and returns the result as JSON */ const runQuery = async (query) => { let result try { result = await fetch('https://api.github.com/graphql', { method: 'POST', headers: { Authorization: `Bearer ${siteConfig.issueToken}`, }, body: JSON.stringify({ query }), }) } catch (err) { console.log(err) return false } const data = await result.json() return data } /* * Helper method to filter out GraphQL nodes based on a label set on them */ const filterOnLabel = (nodes, label) => nodes.filter((node) => node.labels.edges.filter((edge) => edge.node.name === label).length > 0 ? true : false ) /* * Method that load status issues from GitHub and * sets the result with the setter method passed to it. * * If issues are found, this will create and object * with reported, confirmed, and resolved as keys and * the list of issues as value of those keys. */ const loadStatusIssues = async (setIssues) => { const open = await runQuery(query.open) const closed = await runQuery(query.closed) const now = Date.now() setIssues({ reported: filterOnLabel(open.data.repository.issues.nodes, 'statusReported'), confirmed: filterOnLabel(open.data.repository.issues.nodes, 'statusConfirmed'), resolved: closed.data.repository.issues.nodes.filter((node) => { const closed = new Date(node.closedAt).valueOf() // Only show what was closed in the last 36 hours return now - closed < 36 * 60 * 60 * 1000 }), }) } const AssignedEvent = ({ evt, t }) => (
{props.evt.node.__typeName}
//null const Component = events[props.evt.node.__typename] || Null return{JSON.stringify(props.evt.node, null, 2)}} const Issue = ({ issue, type, t }) => { const [detail, setDetail] = useState(false) const btnClasses = 'w-full my-1 rounded hover:bg-opacity-10 hover:bg-secondary text-left text-base-content p-1 px-2 flex flex-row items-center justify-between' if (!detail) return ( ) return (
Loading...
) : issues === false ? ( <> {t('support:status')}