Browse Source

add state ton sites

main
matthew 2 years ago
parent
commit
cb77527509
  1. 3
      searching-front/app/core/commonTypes.ts
  2. 1
      searching-front/app/core/components/Footer/styles.module.css
  3. 2
      searching-front/app/core/components/Header/Header.tsx
  4. 2
      searching-front/app/core/components/SearchForm/SearchForm.tsx
  5. 4
      searching-front/app/core/hooks/useCurrentTheme.ts
  6. 12
      searching-front/app/core/pages/Search/Search.tsx
  7. 141
      searching-front/app/core/pages/State/State.tsx
  8. 1
      searching-front/app/core/pages/State/index.ts
  9. 67
      searching-front/app/core/pages/State/styles.module.css
  10. 4
      searching-front/app/i18n/en.ts
  11. 3
      searching-front/app/i18n/ru.ts
  12. 2
      searching-front/app/search-requests/queries/getSearchRequests.ts
  13. 11
      searching-front/app/stateSites/queries/getActualSitesState.ts
  14. 6
      searching-front/app/stateSites/queries/getHistoryOfSitesState.ts
  15. 58
      searching-front/package-lock.json
  16. 6
      searching-front/package.json
  17. 58
      searching-front/pages/state.tsx
  18. 17
      searching-front/services/influxTest.ts
  19. 57
      searching-front/services/modules/influxdb/helpers.ts
  20. 36
      searching-front/services/modules/influxdb/index.ts
  21. 11
      searching-front/services/modules/influxdb/types.ts

3
searching-front/app/core/commonTypes.ts

@ -0,0 +1,3 @@
export interface StaticPageProps<T>{
props: T
}

1
searching-front/app/core/components/Footer/styles.module.css

@ -1,4 +1,5 @@
.root { .root {
margin-top: 30px;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
justify-content: center; justify-content: center;

2
searching-front/app/core/components/Header/Header.tsx

@ -7,7 +7,7 @@ import s from "./styles.module.css"
const Header = () => { const Header = () => {
const { route } = useRouter() const { route } = useRouter()
const shouldShowSearchForm = route === Routes.SearchPage().pathname const shouldShowSearchForm = route !== Routes.Home().pathname
const router = useRouter() const router = useRouter()
const toMain = async () => { const toMain = async () => {
await router.push("/") await router.push("/")

2
searching-front/app/core/components/SearchForm/SearchForm.tsx

@ -115,8 +115,6 @@ const SearchForm = () => {
setInputFocused(true) setInputFocused(true)
}, []) }, [])
debugger
return ( return (
<AnimatePresence> <AnimatePresence>
<motion.div layoutId="searchForm" className={s.root}> <motion.div layoutId="searchForm" className={s.root}>

4
searching-front/app/core/hooks/useCurrentTheme.ts

@ -6,5 +6,9 @@ const COOKIE_NAME = "theme"
export const useCurrentTheme = () => { export const useCurrentTheme = () => {
const { cookies } = useContext(ServerSidePropsContext) const { cookies } = useContext(ServerSidePropsContext)
if (cookies) {
return jsCookies.get(COOKIE_NAME) || cookies[COOKIE_NAME] || "light" return jsCookies.get(COOKIE_NAME) || cookies[COOKIE_NAME] || "light"
} else {
return "light"
}
} }

12
searching-front/app/core/pages/Search/Search.tsx

@ -13,7 +13,7 @@ const Search = () => {
const router = useRouter() const router = useRouter()
const { t } = useTranslation() const { t } = useTranslation()
const [page, setPage] = useState(0) const [page, setPage] = useState(0)
const text = router.query.query as string; const text = router.query.query as string
const [res] = useQuery( const [res] = useQuery(
getSearchResult, getSearchResult,
{ text, page }, { text, page },
@ -33,17 +33,23 @@ const Search = () => {
))} ))}
</div> </div>
<div className={s.pagination}> <div className={s.pagination}>
{res.pagesCount > 1 && (
<Pagination <Pagination
onPageChange={onPageChange} onPageChange={onPageChange}
currentPage={page} currentPage={page}
pagesCount={res.pagesCount} pagesCount={res.pagesCount}
/> />
)}
</div> </div>
</div> </div>
) )
} else if (res && !res.hits.length) { } else if (res && !res.hits.length) {
return <div>{t("searchPage.notFound")}<b>«{text}»</b></div> return (
<div>
{t("searchPage.notFound")}
<b>«{text}»</b>
</div>
)
} }
return "loading" return "loading"
} }

141
searching-front/app/core/pages/State/State.tsx

@ -0,0 +1,141 @@
import { Doughnut, Line } from "react-chartjs-2"
import { format } from "date-fns"
import { useQuery } from "@blitzjs/rpc"
import { useState } from "react"
import { useTranslation } from "react-i18next"
import { ChartData } from "chart.js/auto"
import getActualSitesState from "app/stateSites/queries/getActualSitesState"
import getHistoryOfSitesState from "app/stateSites/queries/getHistoryOfSitesState"
import { InfluxPeriod } from "services/modules/influxdb/types"
import { cn } from "app/core/helpers/common"
import s from "./styles.module.css"
interface HistoryOfStateItem {
value: number
time: string
}
interface HistoryOfState {
all: HistoryOfStateItem[]
available: HistoryOfStateItem[]
}
export interface StatePageProps {
actualState: Awaited<ReturnType<typeof getActualSitesState>>
historyOfState: HistoryOfState
}
const availableSitesColor = "#08c"
const allSitesColor = "hsl(200 15% 81% / 1)"
const getDohnutData = (data: number[]) => ({
labels: ["Available", "All"],
datasets: [
{
data: data,
backgroundColor: [availableSitesColor, allSitesColor],
borderColor: [availableSitesColor, "rgba(0,0,0,0)"],
borderWidth: 1,
},
],
})
const liteOptions = {
responsive: true,
plugins: {
legend: {
display: false,
},
tooltip: {
intersect: false,
},
},
scales: {
x: {
display: false,
},
},
}
export const getGraphData = (
data: HistoryOfStateItem[],
label: string,
color: string
): ChartData<"line", number[], string> => ({
labels: data.map((item) => format(new Date(item.time), "dd.MM.yy hh:mm")),
datasets: [
{
label,
data: data.map((item) => item.value),
backgroundColor: color,
borderColor: color,
tension: 0.3,
},
],
})
interface HistoryItemProps {
data: ChartData<"line", number[], string>
title: string
}
const HistoryItem = ({ data, title }: HistoryItemProps) => {
return (
<div className={s.historyStateItem}>
<div>{title}</div>
<Line options={liteOptions} data={data} />
</div>
)
}
const State = ({ actualState, historyOfState: historyOfStatePreloaded }: StatePageProps) => {
const [historyPeriod, setHistoryPeriod] = useState(InfluxPeriod.D)
const { t } = useTranslation()
const [historyOfState] = useQuery(getHistoryOfSitesState, historyPeriod, {
suspense: false,
keepPreviousData: true,
initialData: historyOfStatePreloaded,
})
console.log(historyPeriod, historyOfState)
return (
<div className={s.root}>
<div className={s.title}>{t("state.title")}</div>
<div className={s.doughnutAvailable}>
<Doughnut
data={getDohnutData([actualState.availableDomainsCount, actualState.allDomainsCount])}
/>
</div>
<div className={s.actualStateWrapper}>
<span className={s.availableCount}>{actualState.availableDomainsCount}</span>{" "}
{t("state.siteOutOf")} <span className={s.allCount}>{actualState.allDomainsCount}</span>
<span className={s.areNowAvailable}>{t("state.areNowAvailable")}</span>
</div>
{historyOfState && (
<div className={s.historyStateWrapper}>
<div className={s.historyStatePeriodsWrapper}>
{Object.values(InfluxPeriod).map((i) => (
<button
onClick={() => setHistoryPeriod(i)}
className={cn(s.historyStatePeriodsItem, { [s.active]: historyPeriod === i })}
>
{i}
</button>
))}
</div>
<HistoryItem
title="All sites count"
data={getGraphData(historyOfState.all, "All sites count", availableSitesColor)}
/>
<HistoryItem
title="Available sites count"
data={getGraphData(historyOfState.available, "Available sites count", allSitesColor)}
/>
</div>
)}
</div>
)
}
export default State

1
searching-front/app/core/pages/State/index.ts

@ -0,0 +1 @@
export { default } from "./State"

67
searching-front/app/core/pages/State/styles.module.css

@ -0,0 +1,67 @@
.root {
/* margin-right: var(--logoWrapperWidth); */
}
.actualStateWrapper {
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.availableCount {
font-size: 100px;
margin-right: 10px;
color: var(--button_primary);
font-weight: bold;
}
.allCount {
margin: 0px 10px;
font-size: 30px;
color: var(--text_secondary);
font-weight: bold;
}
.areNowAvailable {
}
.doughnutAvailable {
width: 200px;
margin: auto;
}
.title {
font-size: 40px;
text-align: center;
margin: auto;
margin-bottom: 20px;
/* font-weight: 500; */
}
.historyStateWrapper {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
max-width: 1000px;
margin: auto;
}
.historyStateItem {
width: 400px;
}
.historyStatePeriodsWrapper {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 10px;
}
.historyStatePeriodsItem {
border-radius: 5px;
margin: 5px;
border: none;
background: rgba(0, 0, 0, 0.04);
cursor: pointer;
}
.historyStatePeriodsItem.active {
background: var(--button_primary);
color: white;
}

4
searching-front/app/i18n/en.ts

@ -7,6 +7,10 @@ const en = {
"footer.linkContacts": "Contact Us", "footer.linkContacts": "Contact Us",
"footer.linkAnnouncments": "Announcments", "footer.linkAnnouncments": "Announcments",
"footer.linkFeedback": "Feedback", "footer.linkFeedback": "Feedback",
"state.title": "State Of Ton Sites",
"state.siteOutOf": " sites out of ",
"state.areNowAvailable": " are now available!",
}, },
} }

3
searching-front/app/i18n/ru.ts

@ -7,6 +7,9 @@ const ru = {
"footer.linkContacts": "Связаться с нами", "footer.linkContacts": "Связаться с нами",
"footer.linkAnnouncments": "Новости", "footer.linkAnnouncments": "Новости",
"footer.linkFeedback": "Оставить обратную связь", "footer.linkFeedback": "Оставить обратную связь",
"state.siteOutOf": " сайтов из ",
"state.areNowAvailable": " сейчас доступны!",
}, },
} }

2
searching-front/app/search-requests/queries/getSearchRequests.ts

@ -5,7 +5,7 @@ import { z } from "zod";
const GetSearchRequest = z.object({ const GetSearchRequest = z.object({
// This accepts type of undefined, but is required at runtime // This accepts type of undefined, but is required at runtime
text: z.string() text: z.string().optional()
}); });
export default resolver.pipe( export default resolver.pipe(

11
searching-front/app/stateSites/queries/getActualSitesState.ts

@ -0,0 +1,11 @@
import db from "db"
export default async function getActualSitesState() {
const allDomainsCount = await db.nftDomain.count()
const availableDomainsCount = await db.nftDomain.count({ where: { available: true } })
return {
allDomainsCount,
availableDomainsCount,
}
}

6
searching-front/app/stateSites/queries/getHistoryOfSitesState.ts

@ -0,0 +1,6 @@
import influxdb from "services/modules/influxdb"
import { InfluxPeriod } from "services/modules/influxdb/types"
export default async function getActualSitesState(period: InfluxPeriod = InfluxPeriod.W) {
return await influxdb.getHistoryOfState(period)
}

58
searching-front/package-lock.json generated

@ -20,18 +20,22 @@
"@types/textversionjs": "1.1.1", "@types/textversionjs": "1.1.1",
"axios": "0.27.2", "axios": "0.27.2",
"blitz": "2.0.0-beta.3", "blitz": "2.0.0-beta.3",
"chart.js": "3.9.1",
"cheerio": "1.0.0-rc.12", "cheerio": "1.0.0-rc.12",
"classnames": "2.3.1", "classnames": "2.3.1",
"date-fns": "2.29.3",
"dotenv": "16.0.1", "dotenv": "16.0.1",
"framer-motion": "7.2.1", "framer-motion": "7.2.1",
"html-to-text": "8.2.1", "html-to-text": "8.2.1",
"i": "0.3.7", "i": "0.3.7",
"i18next": "21.9.1", "i18next": "21.9.1",
"install": "0.13.0",
"jsdom": "20.0.0", "jsdom": "20.0.0",
"next": "12.2.5", "next": "12.2.5",
"node-fetch": "3.2.10", "node-fetch": "3.2.10",
"npm": "8.18.0", "npm": "8.18.0",
"react": "18.2.0", "react": "18.2.0",
"react-chartjs-2": "4.3.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "7.34.2", "react-hook-form": "7.34.2",
"react-i18next": "11.18.6", "react-i18next": "11.18.6",
@ -4426,6 +4430,11 @@
"is-regex": "^1.0.3" "is-regex": "^1.0.3"
} }
}, },
"node_modules/chart.js": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
},
"node_modules/cheerio": { "node_modules/cheerio": {
"version": "1.0.0-rc.12", "version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
@ -5261,6 +5270,18 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.3", "version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
@ -8223,6 +8244,14 @@
"css-in-js-utils": "^2.0.0" "css-in-js-utils": "^2.0.0"
} }
}, },
"node_modules/install": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
"integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/internal-slot": { "node_modules/internal-slot": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
@ -13728,6 +13757,15 @@
"react-dom": ">= 16.14" "react-dom": ">= 16.14"
} }
}, },
"node_modules/react-chartjs-2": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==",
"peerDependencies": {
"chart.js": "^3.5.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-dnd": { "node_modules/react-dnd": {
"version": "14.0.5", "version": "14.0.5",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-14.0.5.tgz", "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-14.0.5.tgz",
@ -19794,6 +19832,11 @@
"is-regex": "^1.0.3" "is-regex": "^1.0.3"
} }
}, },
"chart.js": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
},
"cheerio": { "cheerio": {
"version": "1.0.0-rc.12", "version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
@ -20434,6 +20477,11 @@
"whatwg-url": "^11.0.0" "whatwg-url": "^11.0.0"
} }
}, },
"date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
},
"debug": { "debug": {
"version": "4.3.3", "version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
@ -22515,6 +22563,11 @@
"css-in-js-utils": "^2.0.0" "css-in-js-utils": "^2.0.0"
} }
}, },
"install": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
"integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA=="
},
"internal-slot": { "internal-slot": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
@ -26419,6 +26472,11 @@
"react-window": "^1.8.6" "react-window": "^1.8.6"
} }
}, },
"react-chartjs-2": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA=="
},
"react-dnd": { "react-dnd": {
"version": "14.0.5", "version": "14.0.5",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-14.0.5.tgz", "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-14.0.5.tgz",

6
searching-front/package.json

@ -3,7 +3,7 @@
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"watcher": "ts-node-esm ./services/main.ts", "watcher": "ts-node-esm ./services/main.ts",
"influx": "ts-node-esm ./services/influx.ts", "influx": "ts-node-esm ./services/influxTest.ts",
"parser": "ts-node-esm ./services/parser.ts", "parser": "ts-node-esm ./services/parser.ts",
"dev": "blitz dev", "dev": "blitz dev",
"build": "blitz build", "build": "blitz build",
@ -38,18 +38,22 @@
"@types/textversionjs": "1.1.1", "@types/textversionjs": "1.1.1",
"axios": "0.27.2", "axios": "0.27.2",
"blitz": "2.0.0-beta.3", "blitz": "2.0.0-beta.3",
"chart.js": "3.9.1",
"cheerio": "1.0.0-rc.12", "cheerio": "1.0.0-rc.12",
"classnames": "2.3.1", "classnames": "2.3.1",
"date-fns": "2.29.3",
"dotenv": "16.0.1", "dotenv": "16.0.1",
"framer-motion": "7.2.1", "framer-motion": "7.2.1",
"html-to-text": "8.2.1", "html-to-text": "8.2.1",
"i": "0.3.7", "i": "0.3.7",
"i18next": "21.9.1", "i18next": "21.9.1",
"install": "0.13.0",
"jsdom": "20.0.0", "jsdom": "20.0.0",
"next": "12.2.5", "next": "12.2.5",
"node-fetch": "3.2.10", "node-fetch": "3.2.10",
"npm": "8.18.0", "npm": "8.18.0",
"react": "18.2.0", "react": "18.2.0",
"react-chartjs-2": "4.3.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hook-form": "7.34.2", "react-hook-form": "7.34.2",
"react-i18next": "11.18.6", "react-i18next": "11.18.6",

58
searching-front/pages/state.tsx

@ -0,0 +1,58 @@
import { Suspense } from "react"
import Layout from "app/core/layouts/Layout"
import getActualSitesState from "app/stateSites/queries/getActualSitesState"
import getHistoryOfSitesState from "app/stateSites/queries/getHistoryOfSitesState"
import { BlitzPage } from "@blitzjs/next"
import State from "app/core/pages/State"
import { gSP } from "app/blitz-server"
import { ErrorBoundary } from "@blitzjs/next"
import {
ServerSidePropsContext,
} from "app/core/contextProviders/serverSidePropsProvider"
import { StatePageProps } from "app/core/pages/State/State"
import { StaticPageProps } from "app/core/commonTypes"
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
const StatePage: BlitzPage<StatePageProps> = (props) => {
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// reset the state of your app so the error doesn't happen again
}}
>
<ServerSidePropsContext.Provider value={props}>
<Layout title="State of TON Sites" withoutPaddings>
<Suspense fallback="Loading...">
<State {...props} />
</Suspense>
</Layout>
</ServerSidePropsContext.Provider>
</ErrorBoundary>
)
}
export const getStaticProps = gSP(async ({ params, ctx }): StaticPageProps<StatePageProps> => {
const actualState = await getActualSitesState();
const historyOfState = await getHistoryOfSitesState();
return {
props: {
actualState,
historyOfState
},
}
})
export default StatePage

17
searching-front/services/influxTest.ts

@ -0,0 +1,17 @@
import path from "path"
import dotenv from "dotenv"
dotenv.config({ path: path.resolve(__dirname, "../.env.local") })
import { Ctx } from "blitz"
import db from "db"
import { InfluxPeriod } from "./modules/influxdb/types"
import influxdb from "./modules/influxdb"
export default async function run(period:InfluxPeriod = InfluxPeriod.W) {
const res = await influxdb.getHistoryOfState(period);
console.log(res)
}
run()

57
searching-front/services/modules/influxdb/helpers.ts

@ -1,46 +1,51 @@
import { fluxDuration } from "@influxdata/influxdb-client"; import { fluxDuration } from "@influxdata/influxdb-client"
import { influxBucket, influxHost, influxPointName } from "./constants"; import { influxBucket, influxHost, influxPointName } from "./constants"
import { InfluxField, InfluxPeriod } from "./types"; import { InfluxField, InfluxPeriod } from "./types"
export const influxQuery = (field: InfluxField, fetchPeriod: InfluxPeriod) => { export const influxQuery = (field: InfluxField, fetchPeriod: InfluxPeriod) => {
let start; let start
let period; let period
switch (fetchPeriod) { switch (fetchPeriod) {
case InfluxPeriod.H: case InfluxPeriod.H:
start ='-1h' start = "-1h"
period = '6m' period = "6m"
break
case InfluxPeriod.D: case InfluxPeriod.D:
start ='-1d' start = "-1d"
period = '144m' period = "144m"
case InfluxPeriod.W: break
start ='-1w' // case InfluxPeriod.W:
period = '1008m' // start = "-1w"
case InfluxPeriod.M: // period = "1008m"
start ='-1mo' // break
period = '3d' // case InfluxPeriod.M:
case InfluxPeriod.Y: // start = "-1mo"
start ='-1y' // period = "3d"
period = '36d' // break
case InfluxPeriod.tenminute: // case InfluxPeriod.Y:
start ='10m' // start = "-1y"
period = '1m' // period = "36d"
// break
// case InfluxPeriod.tenminute:
// start ='-10m'
// period = '1m'
} }
const influxPeriod = fluxDuration(period); const query = `from(bucket: "${influxBucket}")
const influxStart = fluxDuration(start);
return `from(bucket: "${influxBucket}")
|> range(start: ${start}, stop: now()) |> range(start: ${start}, stop: now())
|> filter(fn: (r) => r["host"] == "${influxHost}") |> filter(fn: (r) => r["host"] == "${influxHost}")
|> filter(fn: (r) => r["_field"] == "${field}") |> filter(fn: (r) => r["_field"] == "${field}")
|> filter(fn: (r) => r["_measurement"] == "${influxPointName}") |> filter(fn: (r) => r["_measurement"] == "${influxPointName}")
|> aggregateWindow(every: ${period}, fn: mean, createEmpty: false) |> aggregateWindow(every: ${period}, fn: mean, createEmpty: false)
|> yield(name: "mean")` |> yield(name: "mean")`
return query
} }
export const processInfluxResult = (res: unknown[]) => { export const processInfluxResult = (res: unknown[]) => {
return res.map(i=>({ return res.map((i) => ({
value: i._value, value: i._value,
time: i._time time: i._time,
})) }))
} }

36
searching-front/services/modules/influxdb/index.ts

@ -1,17 +1,17 @@
import { fluxDuration, InfluxDB } from "@influxdata/influxdb-client" import { fluxDuration, InfluxDB } from "@influxdata/influxdb-client"
import { Point } from "@influxdata/influxdb-client" import { Point } from "@influxdata/influxdb-client"
import { influxBucket, influxHost, influxOrg, influxPointName, influxToken } from "./constants" import { influxBucket, influxHost, influxOrg, influxPointName, influxToken } from "./constants"
import { influxQuery, processInfluxResult } from "./helpers"; import { influxQuery, processInfluxResult } from "./helpers"
import { InfluxField, InfluxPeriod } from "./types" import { InfluxField, InfluxPeriod } from "./types"
interface WriteSitesCounteParams { interface WriteSitesCounteParams {
all: number; all: number
available: number; available: number
} }
interface QueryParams { interface QueryParams {
field: InfluxField; field: InfluxField
period: InfluxPeriod; period: InfluxPeriod
} }
class InfluxDb { class InfluxDb {
@ -26,8 +26,11 @@ class InfluxDb {
} }
writeSitesCount({ all, available }: WriteSitesCounteParams) { writeSitesCount({ all, available }: WriteSitesCounteParams) {
const writeApi = this.getWriteApi() const writeApi = this.getWriteApi()
const pointAll = new Point(influxPointName).intField(InfluxField.ALL_SITES,all); const pointAll = new Point(influxPointName).intField(InfluxField.ALL_SITES, all)
const pointAvailable = new Point(influxPointName).intField(InfluxField.AVAILABLE_SITES,available); const pointAvailable = new Point(influxPointName).intField(
InfluxField.AVAILABLE_SITES,
available
)
writeApi.writePoint(pointAll) writeApi.writePoint(pointAll)
writeApi.writePoint(pointAvailable) writeApi.writePoint(pointAvailable)
writeApi.close() writeApi.close()
@ -35,17 +38,26 @@ class InfluxDb {
async query({ field, period }: QueryParams) { async query({ field, period }: QueryParams) {
const queryApi = this.client.getQueryApi(influxOrg) const queryApi = this.client.getQueryApi(influxOrg)
const query = influxQuery(field, period); const query = influxQuery(field, period)
const result = await queryApi.collectRows(query) const result = await queryApi.collectRows(query)
console.log(processInfluxResult(result)); return processInfluxResult(result);
} }
getAllSiteCounts(period:InfluxPeriod){
this.query({ async getHistoryOfState(period: InfluxPeriod) {
const all = await this.query({
field: InfluxField.ALL_SITES, field: InfluxField.ALL_SITES,
period period,
}) })
const available = await this.query({
field: InfluxField.AVAILABLE_SITES,
period,
})
return {
all,
available,
}
} }
} }

11
searching-front/services/modules/influxdb/types.ts

@ -1,10 +1,9 @@
export enum InfluxPeriod { export enum InfluxPeriod {
H='H', H='Hour',
D='D', D='Day',
W='W', // W='Week',
M='M', // M='Month',
Y='Y', // Y='Year',
tenminute='tenminute',
} }
export enum InfluxField { export enum InfluxField {

Loading…
Cancel
Save