From b5e9375cadab052460bb38817df525226878262b Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 6 Nov 2024 23:45:35 +0700 Subject: [PATCH 01/52] feat: fetch from devhub-cache-api-rs.fly.dev --- .../widget/devhub/entity/proposal/Feed.jsx | 80 +++++++++++-------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index a10e52241..73671293b 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -354,9 +354,6 @@ const FeedPage = () => { const buildWhereClause = () => { let where = {}; - if (state.author) { - where = { author_id: { _eq: state.author }, ...where }; - } if (state.category) { if (isInfra || isEvents) { @@ -366,13 +363,6 @@ const FeedPage = () => { } } - if (state.stage) { - // timeline is stored as jsonb - where = { - timeline: { _cast: { String: { _regex: `${state.stage}` } } }, - ...where, - }; - } if (state.input) { const { number, text } = separateNumberAndText(state.input); if (number) { @@ -399,6 +389,30 @@ const FeedPage = () => { fetchProposals(state.data.length); }; + /** + * { name: { _iregex: `${text}` } }, + { summary: { _iregex: `${text}` } }, + { descriptio + */ + + function fetchCacheApi(variables) { + // TODO: move to config + const ENDPOINT = "https://devhub-cache-api-rs.fly.dev"; + console.log("Fetching cache api", variables); + + return asyncFetch( + `${ENDPOINT}/proposals?offset=${variables.offset}&limit=${variables.limit}&stage=${variables.stage}&author_id=${variables.author_id}&category=${variables.category}`, + { + method: "GET", + headers: { + accept: "application/json", + }, + } + ).catch((error) => { + console.log("Error fetching cache api", error); + }); + } + const fetchProposals = (offset) => { if (!offset) { offset = 0; @@ -409,32 +423,32 @@ const FeedPage = () => { const variables = { limit: FETCH_LIMIT, offset, - where: buildWhereClause(), + author_id: state.author, + stage: state.stage, + category: state.category, }; - fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - if (result.status === 200) { - if (result.body.data) { - const data = result.body.data[proposalFeedIndexerQueryName]; - const totalResult = - result.body.data[`${proposalFeedIndexerQueryName}_aggregate`]; - const promises = data.map((item) => { - if (isNumber(item.linked_rfp)) { - return fetchGraphQL(rfpQuery, "GetLatestSnapshot", { - where: { rfp_id: { _eq: item.linked_rfp } }, - }).then((result) => { - const rfpData = result.body.data?.[rfpFeedIndexerQueryName]; - return { ...item, rfpData: rfpData[0] }; - }); - } else { - return Promise.resolve(item); - } - }); - Promise.all(promises).then((res) => { - State.update({ aggregatedCount: totalResult.aggregate.count }); - fetchBlockHeights(res, offset); + fetchCacheApi(variables).then((result) => { + console.log("result", result); + let data = result.body.records; + let totalResult = { aggregate: { count: data.length } }; // TODO + + const promises = data.map((item) => { + if (isNumber(item.linked_rfp)) { + return; // TODO index RFPs + fetchGraphQL(rfpQuery, "GetLatestSnapshot", { + where: { rfp_id: { _eq: item.linked_rfp } }, + }).then((result) => { + const rfpData = result.body.data?.[rfpFeedIndexerQueryName]; + return { ...item, rfpData: rfpData[0] }; }); + } else { + return Promise.resolve(item); } - } + }); + Promise.all(promises).then((res) => { + State.update({ aggregatedCount: totalResult.aggregate.count }); + fetchBlockHeights(res, offset); + }); }); }; From 48d8365a04a7f5c5492bbbe59c7ff2ae8e4185e7 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 12 Nov 2024 16:48:23 -0800 Subject: [PATCH 02/52] @Megha-Dev-19 WIP --- instances/devhub.near/aliases.mainnet.json | 3 +- .../widget/devhub/entity/proposal/Feed.jsx | 30 +++++++++---------- .../feature/proposal-search/by-sort.jsx | 10 +++---- .../aliases.mainnet.json | 3 +- .../aliases.mainnet.json | 3 +- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/instances/devhub.near/aliases.mainnet.json b/instances/devhub.near/aliases.mainnet.json index e153b8a83..a877fe047 100644 --- a/instances/devhub.near/aliases.mainnet.json +++ b/instances/devhub.near/aliases.mainnet.json @@ -10,5 +10,6 @@ "REPL_RPC_URL": "https://rpc.mainnet.near.org", "REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME": "polyprogrammist_near_devhub_prod_v1_proposals_with_latest_snapshot", "REPL_INDEXER_HASURA_ROLE": "polyprogrammist_near", - "REPL_POSTHOG_API_KEY": "01234567890123456789012345678901234567890123456" + "REPL_POSTHOG_API_KEY": "01234567890123456789012345678901234567890123456", + "REPL_CACHE_URL": "https://devhub-cache-api-rs.fly.dev" } diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 73671293b..a4ca1bb9c 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -389,19 +389,20 @@ const FeedPage = () => { fetchProposals(state.data.length); }; - /** - * { name: { _iregex: `${text}` } }, - { summary: { _iregex: `${text}` } }, - { descriptio - */ - function fetchCacheApi(variables) { - // TODO: move to config - const ENDPOINT = "https://devhub-cache-api-rs.fly.dev"; + const ENDPOINT = "${REPL_CACHE_URL}"; + console.log("Fetching endpoint", ENDPOINT); console.log("Fetching cache api", variables); return asyncFetch( - `${ENDPOINT}/proposals?offset=${variables.offset}&limit=${variables.limit}&stage=${variables.stage}&author_id=${variables.author_id}&category=${variables.category}`, + `${ENDPOINT}/proposals?\ + order=${variables.sort}\ + &limit=${variables.limit}\ + &offset=${variables.offset}\ + &filters.category=${variables.category}\ + &filters.labels=${variables.labels}\ + &filters.author_id=${variables.author_id}\ + &filters.stage=${variables.stage}`, { method: "GET", headers: { @@ -421,20 +422,21 @@ const FeedPage = () => { State.update({ loading: true }); const FETCH_LIMIT = 10; const variables = { + order: state.sort, limit: FETCH_LIMIT, offset, + category: state.category, + labels: state.labels, author_id: state.author, stage: state.stage, - category: state.category, }; fetchCacheApi(variables).then((result) => { console.log("result", result); let data = result.body.records; - let totalResult = { aggregate: { count: data.length } }; // TODO + let totalResult = { aggregate: { count: result.body.total_records } }; // TODO const promises = data.map((item) => { if (isNumber(item.linked_rfp)) { - return; // TODO index RFPs fetchGraphQL(rfpQuery, "GetLatestSnapshot", { where: { rfp_id: { _eq: item.linked_rfp } }, }).then((result) => { @@ -462,10 +464,8 @@ const FeedPage = () => { ...new Set([...newItems, ...state.data].map((i) => JSON.stringify(i))), ].map((i) => JSON.parse(i)); // Sorting in the front end - if (state.sort === "proposal_id" || state.sort === "") { + if (state.sort === "id_desc" || state.sort === "") { items.sort((a, b) => b.proposal_id - a.proposal_id); - } else if (state.sort === "views") { - items.sort((a, b) => b.views - a.views); } return items; diff --git a/instances/devhub.near/widget/devhub/feature/proposal-search/by-sort.jsx b/instances/devhub.near/widget/devhub/feature/proposal-search/by-sort.jsx index 7fa65fca0..192361033 100644 --- a/instances/devhub.near/widget/devhub/feature/proposal-search/by-sort.jsx +++ b/instances/devhub.near/widget/devhub/feature/proposal-search/by-sort.jsx @@ -1,11 +1,9 @@ const options = [ { label: "All", value: "" }, - { label: "Most recent", value: "proposal_id" }, // proposal_id desc - { label: "Most viewed", value: "views" }, // views desc - // TODO add track_comments function to devhub to track it in the indexer - // { label: "Most commented", value: "" }, // comments desc - // { label: "Unanswered", value: "" }, // where comments = 0 - // where comments = 0 + { label: "Most recent", value: "id_desc" }, // proposal_id desc + { label: "Oldest", value: "id_asc" }, // proposal_id desc + { label: "Recently updated", value: "ts_desc" }, // timestamp desc + { label: "Least recently updated", value: "ts_asc" }, // timestamp asc ]; const setSelected = props.onStateChange ?? (() => {}); diff --git a/instances/events-committee.near/aliases.mainnet.json b/instances/events-committee.near/aliases.mainnet.json index efd479a11..39dc1ec40 100644 --- a/instances/events-committee.near/aliases.mainnet.json +++ b/instances/events-committee.near/aliases.mainnet.json @@ -11,5 +11,6 @@ "REPL_SOCIAL_CONTRACT": "social.near", "REPL_RPC_URL": "https://rpc.mainnet.near.org", "REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME": "thomasguntenaar_near_event_committee_prod_v1_proposals_with_latest_snapshot", - "REPL_INDEXER_HASURA_ROLE": "thomasguntenaar_near" + "REPL_INDEXER_HASURA_ROLE": "thomasguntenaar_near", + "REPL_CACHE_URL": "https://events-cache-api-rs.fly.dev" } diff --git a/instances/infrastructure-committee.near/aliases.mainnet.json b/instances/infrastructure-committee.near/aliases.mainnet.json index 0a6c6b158..d23768897 100644 --- a/instances/infrastructure-committee.near/aliases.mainnet.json +++ b/instances/infrastructure-committee.near/aliases.mainnet.json @@ -9,5 +9,6 @@ "REPL_RFP_INDEXER_QUERY_NAME": "polyprogrammist_near_devhub_ic_v1_rfp_snapshots", "REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME": "polyprogrammist_near_devhub_ic_v1_proposals_with_latest_snapshot", "REPL_PROPOSAL_QUERY_NAME": "polyprogrammist_near_devhub_ic_v1_proposal_snapshots", - "REPL_INDEXER_HASURA_ROLE": "polyprogrammist_near" + "REPL_INDEXER_HASURA_ROLE": "polyprogrammist_near", + "REPL_CACHE_URL": "https://infra-cache-api-rs.fly.dev" } From c6fde6020aaf8ccdb34714ce2270784b99136ac0 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 12 Nov 2024 17:10:45 -0800 Subject: [PATCH 03/52] wip --- .../widget/devhub/entity/proposal/Feed.jsx | 144 ++++-------------- 1 file changed, 30 insertions(+), 114 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index a4ca1bb9c..63eba6e38 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -10,7 +10,6 @@ const { proposalFeedAnnouncement, availableCategoryOptions, proposalFeedIndexerQueryName, - indexerHasuraRole, isDevhub, isInfra, isEvents, @@ -269,14 +268,19 @@ const getProposal = (proposal_id) => { }); }; +const getRfp = (rfp_id) => { + return Near.asyncView(contract, "get_rfp", { + rfp_id, + }); +}; + const FeedPage = () => { - const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql`; State.init({ data: [], author: "", stage: "", - sort: "", + sort: "id_desc", category: "", input: "", loading: false, @@ -286,104 +290,6 @@ const FeedPage = () => { currentlyDisplaying: 0, }); - const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${proposalFeedIndexerQueryName}_bool_exp = {}) { - ${proposalFeedIndexerQueryName}( - offset: $offset - limit: $limit - order_by: {proposal_id: desc} - where: $where - ) { - author_id - block_height - name - category - summary - editor_id - proposal_id - ts - timeline - views - labels - linked_rfp - } - ${proposalFeedIndexerQueryName}_aggregate( - order_by: {proposal_id: desc} - where: $where - ) { - aggregate { - count - } - } - }`; - - const rfpQuery = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${rfpFeedIndexerQueryName}_bool_exp = {}) { - ${rfpFeedIndexerQueryName}( - offset: $offset - limit: $limit - order_by: {rfp_id: desc} - where: $where - ) { - name - rfp_id - } - }`; - - function fetchGraphQL(operationsDoc, operationName, variables) { - return asyncFetch(QUERYAPI_ENDPOINT, { - method: "POST", - headers: { "x-hasura-role": indexerHasuraRole }, - body: JSON.stringify({ - query: operationsDoc, - variables: variables, - operationName: operationName, - }), - }); - } - - function separateNumberAndText(str) { - const numberRegex = /\d+/; - - if (numberRegex.test(str)) { - const number = str.match(numberRegex)[0]; - const text = str.replace(numberRegex, "").trim(); - return { number: parseInt(number), text }; - } else { - return { number: null, text: str.trim() }; - } - } - - const buildWhereClause = () => { - let where = {}; - - if (state.category) { - if (isInfra || isEvents) { - where = { labels: { _contains: state.category }, ...where }; - } else { - where = { category: { _eq: state.category }, ...where }; - } - } - - if (state.input) { - const { number, text } = separateNumberAndText(state.input); - if (number) { - where = { proposal_id: { _eq: number }, ...where }; - } - - if (text) { - where = { - _or: [ - { name: { _iregex: `${text}` } }, - { summary: { _iregex: `${text}` } }, - { description: { _iregex: `${text}` } }, - ], - ...where, - }; - } - } - - return where; - }; - const makeMoreItems = () => { State.update({ makeMoreLoader: true }); fetchProposals(state.data.length); @@ -394,15 +300,24 @@ const FeedPage = () => { console.log("Fetching endpoint", ENDPOINT); console.log("Fetching cache api", variables); + let fetchUrl = `${ENDPOINT}/proposals?order=${variables.order}&limit=${variables.limit}&offset=${variables.offset}`; + + if (variables.author_id) { + fetchUrl += `&filters.author_id=${variables.author_id}`; + } + if (variables.stage) { + fetchUrl += `&filters.stage=${variables.stage}`; + } + if (variables.category) { + if (isInfra || isEvents) { + fetchUrl += `&filters.labels=${variables.category}`; + } else { + fetchUrl += `&filters.category=${variables.category}`; + } + } + console.log("Fetching.. ", fetchUrl); return asyncFetch( - `${ENDPOINT}/proposals?\ - order=${variables.sort}\ - &limit=${variables.limit}\ - &offset=${variables.offset}\ - &filters.category=${variables.category}\ - &filters.labels=${variables.labels}\ - &filters.author_id=${variables.author_id}\ - &filters.stage=${variables.stage}`, + fetchUrl, { method: "GET", headers: { @@ -437,12 +352,13 @@ const FeedPage = () => { const promises = data.map((item) => { if (isNumber(item.linked_rfp)) { - fetchGraphQL(rfpQuery, "GetLatestSnapshot", { - where: { rfp_id: { _eq: item.linked_rfp } }, - }).then((result) => { - const rfpData = result.body.data?.[rfpFeedIndexerQueryName]; + // TODO fetch individual rfp's -> name & rfp_id + getRfp(item.linked_rfp).then((result) => { + + console.log({ result }) + const rfpData = result.body.data; return { ...item, rfpData: rfpData[0] }; - }); + }) } else { return Promise.resolve(item); } From 97d10d5cee34fea6da74d0cb9fbccbc0f73e0859 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 12 Nov 2024 17:11:00 -0800 Subject: [PATCH 04/52] fmt --- .../widget/devhub/entity/proposal/Feed.jsx | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 63eba6e38..ce8dff6ae 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -275,7 +275,6 @@ const getRfp = (rfp_id) => { }; const FeedPage = () => { - State.init({ data: [], author: "", @@ -316,15 +315,12 @@ const FeedPage = () => { } } console.log("Fetching.. ", fetchUrl); - return asyncFetch( - fetchUrl, - { - method: "GET", - headers: { - accept: "application/json", - }, - } - ).catch((error) => { + return asyncFetch(fetchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { console.log("Error fetching cache api", error); }); } @@ -354,11 +350,10 @@ const FeedPage = () => { if (isNumber(item.linked_rfp)) { // TODO fetch individual rfp's -> name & rfp_id getRfp(item.linked_rfp).then((result) => { - - console.log({ result }) + console.log({ result }); const rfpData = result.body.data; return { ...item, rfpData: rfpData[0] }; - }) + }); } else { return Promise.resolve(item); } From c4d856e48df87e5eee193d5c42b3c1c577bb4f3e Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 21:05:20 -0600 Subject: [PATCH 05/52] wip --- .../widget/devhub/entity/proposal/Feed.jsx | 114 ++++++++++++------ 1 file changed, 79 insertions(+), 35 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index ce8dff6ae..f0e99d97e 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -294,6 +294,55 @@ const FeedPage = () => { fetchProposals(state.data.length); }; + function searchCacheApi() { + const ENDPOINT = "${REPL_CACHE_URL}"; + + let searchTerm = state.input; + let searchInput = encodeURI(searchTerm); + let searchUrl = `${ENDPOINT}/proposals/search/${searchInput}`; + + return asyncFetch(searchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }) + .then((result) => { + console.log(result); + }) + .catch((error) => { + console.log("Error searching cache api", error); + }); + } + + const searchProposals = () => { + if (state.loading) return; + State.update({ loading: true }); + + searchCacheApi().then((result) => { + console.log("result", result); + // let data = result.body.records; + // let totalResult = { aggregate: { count: result.body.total_records } }; // TODO + + // const promises = data.map((item) => { + // if (isNumber(item.linked_rfp)) { + // // TODO fetch individual rfp's -> name & rfp_id + // getRfp(item.linked_rfp).then((result) => { + // console.log({ result }); + // const rfpData = result.body.data; + // return { ...item, rfpData: rfpData[0] }; + // }); + // } else { + // return Promise.resolve(item); + // } + // }); + // Promise.all(promises).then((res) => { + // State.update({ aggregatedCount: totalResult.aggregate.count }); + // fetchBlockHeights(res, offset); + // }); + }); + }; + function fetchCacheApi(variables) { const ENDPOINT = "${REPL_CACHE_URL}"; console.log("Fetching endpoint", ENDPOINT); @@ -336,19 +385,18 @@ const FeedPage = () => { order: state.sort, limit: FETCH_LIMIT, offset, - category: state.category, - labels: state.labels, - author_id: state.author, - stage: state.stage, + category: state.category ? encodeURIComponent(state.category) : "", + author_id: state.author ? encodeURIComponent(state.author) : "", + stage: state.stage ? encodeURIComponent(state.stage) : "", }; fetchCacheApi(variables).then((result) => { console.log("result", result); let data = result.body.records; - let totalResult = { aggregate: { count: result.body.total_records } }; // TODO const promises = data.map((item) => { + console.log("item.linked_rfp ", item.linked_rfp); if (isNumber(item.linked_rfp)) { - // TODO fetch individual rfp's -> name & rfp_id + // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id getRfp(item.linked_rfp).then((result) => { console.log({ result }); const rfpData = result.body.data; @@ -359,7 +407,7 @@ const FeedPage = () => { } }); Promise.all(promises).then((res) => { - State.update({ aggregatedCount: totalResult.aggregate.count }); + State.update({ aggregatedCount: result.body.total_records }); fetchBlockHeights(res, offset); }); }); @@ -383,38 +431,34 @@ const FeedPage = () => { }; const fetchBlockHeights = (data, offset) => { - let promises = data.map((item) => getProposal(item.proposal_id)); - Promise.all(promises).then((blockHeights) => { - data = data.map((item, index) => ({ - ...item, - timeline: JSON.parse(item.timeline), - social_db_post_block_height: - blockHeights[index].social_db_post_block_height, - })); - if (offset) { - let newData = mergeItems(data); - State.update({ - data: newData, - currentlyDisplaying: newData.length, - loading: false, - searchLoader: false, - makeMoreLoader: false, - }); - } else { - State.update({ - data, - currentlyDisplaying: data.length, - loading: false, - searchLoader: false, - makeMoreLoader: false, - }); - } - }); + data = data.map((item, index) => ({ + ...item, + timeline: JSON.parse(item.timeline), + })); + if (offset) { + let newData = mergeItems(data); + State.update({ + data: newData, + currentlyDisplaying: newData.length, + loading: false, + searchLoader: false, + makeMoreLoader: false, + }); + } else { + State.update({ + data, + currentlyDisplaying: data.length, + loading: false, + searchLoader: false, + makeMoreLoader: false, + }); + } }; + // TODO use the search here useEffect(() => { const handler = setTimeout(() => { - fetchProposals(); + searchProposals(); }, 1000); return () => { From 32965d6e3335293b968e06db6757909e3d387f1d Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 21:29:50 -0600 Subject: [PATCH 06/52] events and devhub are ready to be reviewed --- .../widget/devhub/entity/proposal/Feed.jsx | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index f0e99d97e..8880506c0 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -301,18 +301,15 @@ const FeedPage = () => { let searchInput = encodeURI(searchTerm); let searchUrl = `${ENDPOINT}/proposals/search/${searchInput}`; + console.log(searchUrl); return asyncFetch(searchUrl, { method: "GET", headers: { accept: "application/json", }, - }) - .then((result) => { - console.log(result); - }) - .catch((error) => { - console.log("Error searching cache api", error); - }); + }).catch((error) => { + console.log("Error searching cache api", error); + }); } const searchProposals = () => { @@ -321,25 +318,25 @@ const FeedPage = () => { searchCacheApi().then((result) => { console.log("result", result); - // let data = result.body.records; - // let totalResult = { aggregate: { count: result.body.total_records } }; // TODO - - // const promises = data.map((item) => { - // if (isNumber(item.linked_rfp)) { - // // TODO fetch individual rfp's -> name & rfp_id - // getRfp(item.linked_rfp).then((result) => { - // console.log({ result }); - // const rfpData = result.body.data; - // return { ...item, rfpData: rfpData[0] }; - // }); - // } else { - // return Promise.resolve(item); - // } - // }); - // Promise.all(promises).then((res) => { - // State.update({ aggregatedCount: totalResult.aggregate.count }); - // fetchBlockHeights(res, offset); - // }); + let data = result.body.records; + + const promises = data.map((item) => { + console.log("item.linked_rfp ", item.linked_rfp); + if (isNumber(item.linked_rfp)) { + // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id + getRfp(item.linked_rfp).then((result) => { + console.log({ result }); + const rfpData = result.body.data; + return { ...item, rfpData: rfpData[0] }; + }); + } else { + return Promise.resolve(item); + } + }); + Promise.all(promises).then((res) => { + State.update({ aggregatedCount: result.body.total_records }); + fetchBlockHeights(res, offset); + }); }); }; @@ -455,10 +452,13 @@ const FeedPage = () => { } }; - // TODO use the search here useEffect(() => { const handler = setTimeout(() => { - searchProposals(); + if (state.input) { + searchProposals(); + } else { + fetchProposals(); + } }, 1000); return () => { From bc05626858fe284c0ac5642bf772282fe66dafdc Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 23:11:14 -0600 Subject: [PATCH 07/52] feat: infra proposals --- .../widget/devhub/entity/proposal/Feed.jsx | 17 +- .../widget/components/proposals/Feed.jsx | 311 ++++++++---------- 2 files changed, 148 insertions(+), 180 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 8880506c0..8453c9733 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -275,6 +275,7 @@ const getRfp = (rfp_id) => { }; const FeedPage = () => { + State.init({ data: [], author: "", @@ -312,7 +313,7 @@ const FeedPage = () => { }); } - const searchProposals = () => { + function searchProposals() { if (state.loading) return; State.update({ loading: true }); @@ -369,9 +370,9 @@ const FeedPage = () => { }).catch((error) => { console.log("Error fetching cache api", error); }); - } + }; - const fetchProposals = (offset) => { + function fetchProposals(offset) { if (!offset) { offset = 0; } @@ -387,16 +388,14 @@ const FeedPage = () => { stage: state.stage ? encodeURIComponent(state.stage) : "", }; fetchCacheApi(variables).then((result) => { - console.log("result", result); - let data = result.body.records; - - const promises = data.map((item) => { + const body = result.body; + const promises = body.records.map((item) => { console.log("item.linked_rfp ", item.linked_rfp); if (isNumber(item.linked_rfp)) { // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id getRfp(item.linked_rfp).then((result) => { console.log({ result }); - const rfpData = result.body.data; + const rfpData = body.data; return { ...item, rfpData: rfpData[0] }; }); } else { @@ -404,7 +403,7 @@ const FeedPage = () => { } }); Promise.all(promises).then((res) => { - State.update({ aggregatedCount: result.body.total_records }); + State.update({ aggregatedCount: body.total_records }); fetchBlockHeights(res, offset); }); }); diff --git a/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx b/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx index 5e9dfe196..17317d56c 100644 --- a/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx +++ b/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx @@ -10,7 +10,6 @@ const { proposalFeedAnnouncement, availableCategoryOptions, proposalFeedIndexerQueryName, - indexerHasuraRole, isDevhub, isInfra, isEvents, @@ -269,14 +268,19 @@ const getProposal = (proposal_id) => { }); }; +const getRfp = (rfp_id) => { + return Near.asyncView(contract, "get_rfp", { + rfp_id, + }); +}; + const FeedPage = () => { - const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql`; State.init({ data: [], author: "", stage: "", - sort: "", + sort: "id_desc", category: "", input: "", loading: false, @@ -286,114 +290,6 @@ const FeedPage = () => { currentlyDisplaying: 0, }); - const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 20, $where: ${proposalFeedIndexerQueryName}_bool_exp = {}) { - ${proposalFeedIndexerQueryName}( - offset: $offset - limit: $limit - order_by: {proposal_id: desc} - where: $where - ) { - author_id - block_height - name - category - summary - editor_id - proposal_id - ts - timeline - views - labels - linked_rfp - } - ${proposalFeedIndexerQueryName}_aggregate( - order_by: {proposal_id: desc} - where: $where - ) { - aggregate { - count - } - } - }`; - - const rfpQuery = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 20, $where: ${rfpFeedIndexerQueryName}_bool_exp = {}) { - ${rfpFeedIndexerQueryName}( - offset: $offset - limit: $limit - order_by: {rfp_id: desc} - where: $where - ) { - name - rfp_id - } - }`; - - function fetchGraphQL(operationsDoc, operationName, variables) { - return asyncFetch(QUERYAPI_ENDPOINT, { - method: "POST", - headers: { "x-hasura-role": indexerHasuraRole }, - body: JSON.stringify({ - query: operationsDoc, - variables: variables, - operationName: operationName, - }), - }); - } - - function separateNumberAndText(str) { - const numberRegex = /\d+/; - - if (numberRegex.test(str)) { - const number = str.match(numberRegex)[0]; - const text = str.replace(numberRegex, "").trim(); - return { number: parseInt(number), text }; - } else { - return { number: null, text: str.trim() }; - } - } - - const buildWhereClause = () => { - let where = {}; - if (state.author) { - where = { author_id: { _eq: state.author }, ...where }; - } - - if (state.category) { - if (isInfra || isEvents) { - where = { labels: { _contains: state.category }, ...where }; - } else { - where = { category: { _eq: state.category }, ...where }; - } - } - - if (state.stage) { - // timeline is stored as jsonb - where = { - timeline: { _cast: { String: { _regex: `${state.stage}` } } }, - ...where, - }; - } - if (state.input) { - const { number, text } = separateNumberAndText(state.input); - if (number) { - where = { proposal_id: { _eq: number }, ...where }; - } - - if (text) { - where = { - _or: [ - { name: { _iregex: `${text}` } }, - { summary: { _iregex: `${text}` } }, - { description: { _iregex: `${text}` } }, - ], - ...where, - }; - } - } - - return where; - }; - const makeMoreItems = () => { State.update({ makeMoreLoader: true }); fetchProposals(state.data.length); @@ -406,7 +302,84 @@ const FeedPage = () => { REJECTED: 1, }; - const fetchProposals = (offset) => { + function searchCacheApi() { + const ENDPOINT = "${REPL_CACHE_URL}"; + + let searchTerm = state.input; + let searchInput = encodeURI(searchTerm); + let searchUrl = `${ENDPOINT}/proposals/search/${searchInput}`; + + console.log(searchUrl); + return asyncFetch(searchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { + console.log("Error searching cache api", error); + }); + }; + + function searchProposals() { + if (state.loading) return; + State.update({ loading: true }); + + searchCacheApi().then((result) => { + console.log("result", result); + let data = result.body.records; + + const promises = data.map((item) => { + console.log("item.linked_rfp ", item.linked_rfp); + if (isNumber(item.linked_rfp)) { + // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id + getRfp(item.linked_rfp).then((result) => { + console.log({ result }); + const rfpData = result.body.data; + return { ...item, rfpData: rfpData[0] }; + }); + } else { + return Promise.resolve(item); + } + }); + Promise.all(promises).then((res) => { + State.update({ aggregatedCount: result.body.total_records }); + fetchBlockHeights(res, offset); + }); + }); + }; + + function fetchCacheApi(variables) { + const ENDPOINT = "${REPL_CACHE_URL}"; + console.log("Fetching endpoint", ENDPOINT); + console.log("Fetching cache api", variables); + + let fetchUrl = `${ENDPOINT}/proposals?order=${variables.order}&limit=${variables.limit}&offset=${variables.offset}`; + + if (variables.author_id) { + fetchUrl += `&filters.author_id=${variables.author_id}`; + } + if (variables.stage) { + fetchUrl += `&filters.stage=${variables.stage}`; + } + if (variables.category) { + if (isInfra || isEvents) { + fetchUrl += `&filters.labels=${variables.category}`; + } else { + fetchUrl += `&filters.category=${variables.category}`; + } + } + console.log("Fetching.. ", fetchUrl); + return asyncFetch(fetchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { + console.log("Error fetching cache api", error); + }); + }; + + function fetchProposals(offset) { if (!offset) { offset = 0; } @@ -414,34 +387,32 @@ const FeedPage = () => { State.update({ loading: true }); const FETCH_LIMIT = 20; const variables = { + order: state.sort, limit: FETCH_LIMIT, offset, - where: buildWhereClause(), + category: state.category ? encodeURIComponent(state.category) : "", + author_id: state.author ? encodeURIComponent(state.author) : "", + stage: state.stage ? encodeURIComponent(state.stage) : "", }; - fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - if (result.status === 200) { - if (result.body.data) { - const data = result.body.data[proposalFeedIndexerQueryName]; - const totalResult = - result.body.data[`${proposalFeedIndexerQueryName}_aggregate`]; - const promises = data.map((item) => { - if (isNumber(item.linked_rfp)) { - return fetchGraphQL(rfpQuery, "GetLatestSnapshot", { - where: { rfp_id: { _eq: item.linked_rfp } }, - }).then((result) => { - const rfpData = result.body.data?.[rfpFeedIndexerQueryName]; - return { ...item, rfpData: rfpData[0] }; - }); - } else { - return Promise.resolve(item); - } - }); - Promise.all(promises).then((res) => { - State.update({ aggregatedCount: totalResult.aggregate.count }); - fetchBlockHeights(res, offset); + fetchCacheApi(variables).then((result) => { + const body = result.body; + const promises = body.records.map((item) => { + console.log("item.linked_rfp ", item.linked_rfp); + if (isNumber(item.linked_rfp)) { + // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id + getRfp(item.linked_rfp).then((result) => { + console.log({ result }); + const rfpData = body.data; + return { ...item, rfpData: rfpData[0] }; }); + } else { + return Promise.resolve(item); } - } + }); + Promise.all(promises).then((res) => { + State.update({ aggregatedCount: body.total_records }); + fetchBlockHeights(res, offset); + }); }); }; @@ -455,12 +426,11 @@ const FeedPage = () => { ...new Set([...newItems, ...state.data].map((i) => JSON.stringify(i))), ].map((i) => JSON.parse(i)); // Sorting in the front end - if (state.sort === "proposal_id" || state.sort === "") { + if (state.sort === "id_desc" || state.sort === "") { items.sort((a, b) => b.proposal_id - a.proposal_id); - } else if (state.sort === "views") { - items.sort((a, b) => b.views - a.views); } + // Show the accepted once before showing rejected proposals items.sort((a, b) => { return statusOrder[a.timeline.status] - statusOrder[b.timeline.status]; }); @@ -469,43 +439,42 @@ const FeedPage = () => { }; const fetchBlockHeights = (data, offset) => { - let promises = data.map((item) => getProposal(item.proposal_id)); - Promise.all(promises).then((blockHeights) => { - data = data.map((item, index) => ({ - ...item, - timeline: JSON.parse(item.timeline), - social_db_post_block_height: - blockHeights[index].social_db_post_block_height, - })); - if (offset) { - let newData = mergeItems(data); - State.update({ - data: newData, - currentlyDisplaying: newData.length, - loading: false, - searchLoader: false, - makeMoreLoader: false, - }); - } else { - let sorted = [...data].sort((a, b) => { - return ( - statusOrder[a.timeline.status] - statusOrder[b.timeline.status] - ); - }); - State.update({ - data: sorted, - currentlyDisplaying: data.length, - loading: false, - searchLoader: false, - makeMoreLoader: false, - }); - } - }); + data = data.map((item, index) => ({ + ...item, + timeline: JSON.parse(item.timeline), + })); + if (offset) { + let newData = mergeItems(data); + State.update({ + data: newData, + currentlyDisplaying: newData.length, + loading: false, + searchLoader: false, + makeMoreLoader: false, + }); + } else { + let sorted = [...data].sort((a, b) => { + return ( + statusOrder[a.timeline.status] - statusOrder[b.timeline.status] + ); + }); + State.update({ + data: sorted, + currentlyDisplaying: data.length, + loading: false, + searchLoader: false, + makeMoreLoader: false, + }); + } }; useEffect(() => { const handler = setTimeout(() => { - fetchProposals(); + if (state.input) { + searchProposals(); + } else { + fetchProposals(); + } }, 1000); return () => { From f126fc8698fe459e794ce1b7ab741e80b97ddfa8 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 23:11:33 -0600 Subject: [PATCH 08/52] fmt --- .../widget/devhub/entity/proposal/Feed.jsx | 7 +++---- .../widget/components/proposals/Feed.jsx | 13 +++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 8453c9733..9bfcfbe23 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -275,7 +275,6 @@ const getRfp = (rfp_id) => { }; const FeedPage = () => { - State.init({ data: [], author: "", @@ -339,7 +338,7 @@ const FeedPage = () => { fetchBlockHeights(res, offset); }); }); - }; + } function fetchCacheApi(variables) { const ENDPOINT = "${REPL_CACHE_URL}"; @@ -370,7 +369,7 @@ const FeedPage = () => { }).catch((error) => { console.log("Error fetching cache api", error); }); - }; + } function fetchProposals(offset) { if (!offset) { @@ -407,7 +406,7 @@ const FeedPage = () => { fetchBlockHeights(res, offset); }); }); - }; + } useEffect(() => { State.update({ searchLoader: true }); diff --git a/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx b/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx index 17317d56c..00658c569 100644 --- a/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx +++ b/instances/infrastructure-committee.near/widget/components/proposals/Feed.jsx @@ -275,7 +275,6 @@ const getRfp = (rfp_id) => { }; const FeedPage = () => { - State.init({ data: [], author: "", @@ -318,7 +317,7 @@ const FeedPage = () => { }).catch((error) => { console.log("Error searching cache api", error); }); - }; + } function searchProposals() { if (state.loading) return; @@ -346,7 +345,7 @@ const FeedPage = () => { fetchBlockHeights(res, offset); }); }); - }; + } function fetchCacheApi(variables) { const ENDPOINT = "${REPL_CACHE_URL}"; @@ -377,7 +376,7 @@ const FeedPage = () => { }).catch((error) => { console.log("Error fetching cache api", error); }); - }; + } function fetchProposals(offset) { if (!offset) { @@ -414,7 +413,7 @@ const FeedPage = () => { fetchBlockHeights(res, offset); }); }); - }; + } useEffect(() => { State.update({ searchLoader: true }); @@ -454,9 +453,7 @@ const FeedPage = () => { }); } else { let sorted = [...data].sort((a, b) => { - return ( - statusOrder[a.timeline.status] - statusOrder[b.timeline.status] - ); + return statusOrder[a.timeline.status] - statusOrder[b.timeline.status]; }); State.update({ data: sorted, From a4980a5b5ed98b3c872ca155359886802c1e96bc Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 23:47:59 -0600 Subject: [PATCH 09/52] feat: rfps infra --- .../widget/components/rfps/Feed.jsx | 179 ++++++++---------- 1 file changed, 82 insertions(+), 97 deletions(-) diff --git a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx index 9b82d5d1e..cfee27cf2 100644 --- a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx +++ b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx @@ -1,7 +1,3 @@ -const { fetchGraphQL } = VM.require( - `${REPL_INFRASTRUCTURE_COMMITTEE}/widget/core.common` -); - const { href } = VM.require(`${REPL_DEVHUB}/widget/core.lib.url`); href || (href = () => {}); @@ -110,8 +106,6 @@ const Heading = styled.div` const rfpLabelOptions = getGlobalLabels(); const FeedItem = ({ rfp, index }) => { - const accountId = rfp.author_id; - const profile = Social.get(`${accountId}/profile/**`, "final"); // We will have to get the rfp from the contract to get the block height. const blockHeight = parseInt(rfp.social_db_post_block_height); const item = { @@ -233,7 +227,7 @@ const FeedPage = () => { data: [], cachedItems: {}, stage: "", - sort: "", + sort: "id_desc", label: "", input: "", loading: false, @@ -243,91 +237,60 @@ const FeedPage = () => { isFiltered: false, }); - const queryName = "${REPL_RFP_FEED_INDEXER_QUERY_NAME}"; - - const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${queryName}_bool_exp = {}) { - ${queryName}( - offset: $offset - limit: $limit - order_by: {rfp_id: desc} - where: $where - ) { - author_id - block_height - name - summary - editor_id - rfp_id - timeline - views - labels - submission_deadline - linked_proposals - } - ${queryName}_aggregate( - order_by: {rfp_id: desc} - where: $where - ) { - aggregate { - count + function searchCacheApi() { + console.log( + `search url: ${REPL_CACHE_URL}/rfps/search/${encodeURI(state.input)}` + ); + return asyncFetch( + `${REPL_CACHE_URL}/rfps/search/${encodeURI(state.input)}`, + { + method: "GET", + headers: { + accept: "application/json", + }, } - } - }`; + ).catch((error) => { + console.log("Error searching cache api", error); + }); + } - function separateNumberAndText(str) { - const numberRegex = /\d+/; + function searchRfps() { + if (state.loading) return; + State.update({ loading: true }); - if (numberRegex.test(str)) { - const number = str.match(numberRegex)[0]; - const text = str.replace(numberRegex, "").trim(); - return { number: parseInt(number), text }; - } else { - return { number: null, text: str.trim() }; - } + searchCacheApi().then((result) => { + console.log("search result", result); + let body = result.body; + State.update({ aggregatedCount: body.total_records }); + fetchBlockHeights(body.records, 0); + }); } - const buildWhereClause = () => { - let where = {}; - - if (state.label) { - where = { labels: { _contains: state.label }, ...where }; - } + function fetchCacheApi(variables) { + let fetchUrl = `${REPL_CACHE_URL}/rfps?order=${variables.order}&limit=${variables.limit}&offset=${variables.offset}`; - if (state.stage) { - // timeline is stored as jsonb - where = { - timeline: { _cast: { String: { _regex: `${state.stage}` } } }, - ...where, - }; + if (variables.stage) { + fetchUrl += `&filters.stage=${variables.stage}`; } - if (state.input) { - const { number, text } = separateNumberAndText(state.input); - if (number) { - where = { rfp_id: { _eq: number }, ...where }; - } - - if (text) { - where = { - _or: [ - { name: { _iregex: `${text}` } }, - { summary: { _iregex: `${text}` } }, - { description: { _iregex: `${text}` } }, - ], - ...where, - }; + if (variables.category) { + if (isInfra || isEvents) { + fetchUrl += `&filters.labels=${variables.category}`; + } else { + fetchUrl += `&filters.category=${variables.category}`; } } - State.update({ isFiltered: Object.keys(where).length > 0 }); - return where; - }; - const buildOrderByClause = () => { - /** - * TODO - * Most commented -> edit contract and indexer - * Unanswered -> 0 comments - */ - }; + State.update({ isFiltered: variables.category || variables.stage }); + + return asyncFetch(fetchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { + console.log("Error fetching cache api", error); + }); + } const makeMoreItems = () => { if (state.aggregatedCount <= state.currentlyDisplaying) return; @@ -339,25 +302,33 @@ const FeedPage = () => { offset = 0; } if (state.loading) return; + State.update({ loading: true }); + const FETCH_LIMIT = 10; const variables = { + order: state.sort, limit: FETCH_LIMIT, offset, - where: buildWhereClause(), + category: state.category ? encodeURIComponent(state.category) : "", + stage: state.stage ? encodeURIComponent(state.stage) : "", }; - if (typeof fetchGraphQL !== "function") { - return; - } - fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - if (result.status === 200) { - if (result.body.data) { - const data = result.body.data?.[queryName]; - const totalResult = result.body.data?.[`${queryName}_aggregate`]; - State.update({ aggregatedCount: totalResult.aggregate.count }); - // Parse timeline - fetchBlockHeights(data, offset); - } - } + + // fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { + // if (result.status === 200) { + // if (result.body.data) { + // const data = result.body.data?.[queryName]; + // const totalResult = result.body.data?.[`${queryName}_aggregate`]; + // State.update({ aggregatedCount: totalResult.aggregate.count }); + // // Parse timeline + // fetchBlockHeights(data, offset); + // } + // } + // }); + + fetchCacheApi(variables).then((result) => { + const body = result.body; + State.update({ aggregatedCount: body.total_records }); + fetchBlockHeights(body.records, offset); }); }; @@ -390,7 +361,21 @@ const FeedPage = () => { useEffect(() => { fetchRfps(); - }, [state.input, state.sort, state.label, state.stage]); + }, [state.sort, state.label, state.stage]); + + useEffect(() => { + const handler = setTimeout(() => { + if (state.input) { + searchRfps(); + } else { + fetchRfps(); + } + }, 1000); + + return () => { + clearTimeout(handler); + }; + }, [state.input]); const mergeItems = (newItems) => { const items = [ From d9a8b6aa421dc382812f45c90c3255a4140f401b Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 14 Nov 2024 23:58:01 -0600 Subject: [PATCH 10/52] remove comments --- .../widget/components/rfps/Feed.jsx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx index cfee27cf2..691bcd8a3 100644 --- a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx +++ b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx @@ -313,18 +313,6 @@ const FeedPage = () => { stage: state.stage ? encodeURIComponent(state.stage) : "", }; - // fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - // if (result.status === 200) { - // if (result.body.data) { - // const data = result.body.data?.[queryName]; - // const totalResult = result.body.data?.[`${queryName}_aggregate`]; - // State.update({ aggregatedCount: totalResult.aggregate.count }); - // // Parse timeline - // fetchBlockHeights(data, offset); - // } - // } - // }); - fetchCacheApi(variables).then((result) => { const body = result.body; State.update({ aggregatedCount: body.total_records }); From e796489fba4b1e92c227cd2669ddc4243b677856 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 19 Nov 2024 13:04:44 -0600 Subject: [PATCH 11/52] fix: spelling --- .../widget/components/rfps/Feed.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx index 691bcd8a3..4efb5f7f4 100644 --- a/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx +++ b/instances/infrastructure-committee.near/widget/components/rfps/Feed.jsx @@ -163,7 +163,7 @@ const FeedItem = ({ rfp, index }) => { className="d-flex flex-column gap-1" style={{ maxWidth: "70%" }} > -
Summay
+
Summary
{rfp.summary}
@@ -239,7 +239,7 @@ const FeedPage = () => { function searchCacheApi() { console.log( - `search url: ${REPL_CACHE_URL}/rfps/search/${encodeURI(state.input)}` + `Searching url: ${REPL_CACHE_URL}/rfps/search/${encodeURI(state.input)}` ); return asyncFetch( `${REPL_CACHE_URL}/rfps/search/${encodeURI(state.input)}`, @@ -282,6 +282,7 @@ const FeedPage = () => { State.update({ isFiltered: variables.category || variables.stage }); + console.log(`Fetching url: ${fetchUrl}`); return asyncFetch(fetchUrl, { method: "GET", headers: { From ec7c6100c459849753c9b5fde7f1937ae15c1577 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Nov 2024 16:57:59 -0600 Subject: [PATCH 12/52] fix: spelling --- .../widget/devhub/entity/proposal/Editor.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/instances/events-committee.near/widget/devhub/entity/proposal/Editor.jsx b/instances/events-committee.near/widget/devhub/entity/proposal/Editor.jsx index 3feb433bc..8b5bb2777 100644 --- a/instances/events-committee.near/widget/devhub/entity/proposal/Editor.jsx +++ b/instances/events-committee.near/widget/devhub/entity/proposal/Editor.jsx @@ -520,7 +520,7 @@ useEffect(() => { } }, [props.transactionHashes]); -const DropdowntBtnContainer = styled.div` +const DropdownBtnContainer = styled.div` font-size: 13px; min-width: 150px; @@ -670,7 +670,7 @@ const SubmitBtn = () => { const selectedOption = btnOptions.find((i) => i.value === selectedStatus); return ( - +
{
)} -
+ ); }; @@ -972,7 +972,7 @@ const LinkedProposalsComponent = useMemo(() => { Link any relevant proposals (e.g. previous milestones). Date: Wed, 20 Nov 2024 17:16:04 -0600 Subject: [PATCH 13/52] replace all nearqueryapi in devhub related to proposals and rfps --- instances/devhub.near/widget/config/data.jsx | 1 + .../devhub/components/molecule/Compose.jsx | 2 + .../devhub/components/molecule/SimpleMDE.jsx | 66 +++++------ .../entity/addon/blogv2/editor/form.jsx | 1 + .../devhub/entity/proposal/AcceptedTerms.jsx | 69 ++++++------ .../entity/proposal/CommentsAndLogs.jsx | 2 +- .../devhub/entity/proposal/ComposeComment.jsx | 1 + .../widget/devhub/entity/proposal/Editor.jsx | 3 +- .../widget/devhub/entity/proposal/Feed.jsx | 11 +- .../proposal/LinkedProposalsDropdown.jsx | 105 ++++++------------ 10 files changed, 106 insertions(+), 155 deletions(-) diff --git a/instances/devhub.near/widget/config/data.jsx b/instances/devhub.near/widget/config/data.jsx index ce40e902a..b6abb2da2 100644 --- a/instances/devhub.near/widget/config/data.jsx +++ b/instances/devhub.near/widget/config/data.jsx @@ -90,6 +90,7 @@ return { contract: "devhub.near", proposalFeedIndexerQueryName: "polyprogrammist_near_devhub_prod_v1_proposals_with_latest_snapshot", + cacheUrl: "${REPL_CACHE_URL}", indexerHasuraRole: "polyprogrammist_near", isDevhub: true, proposalFeedAnnouncement, diff --git a/instances/devhub.near/widget/devhub/components/molecule/Compose.jsx b/instances/devhub.near/widget/devhub/components/molecule/Compose.jsx index 0ae8c0b62..a3b377016 100644 --- a/instances/devhub.near/widget/devhub/components/molecule/Compose.jsx +++ b/instances/devhub.near/widget/devhub/components/molecule/Compose.jsx @@ -95,6 +95,7 @@ const Compose = ({ "${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE" } props={{ + ...props, data: { handler: state.handler, content: state.data }, onChange: (content) => { State.update({ data: content, handler: "update" }); @@ -163,6 +164,7 @@ const Compose = ({ "${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE" } props={{ + ...props, data: { handler: state.handler, content: state.data }, onChange: (content) => { State.update({ data: content, handler: "update" }); diff --git a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx index aa4a9a04e..7ead84ab9 100644 --- a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx +++ b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx @@ -5,6 +5,10 @@ const { getLinkUsingCurrentGateway } = VM.require( "${REPL_DEVHUB}/widget/core.lib.url" ) || { getLinkUsingCurrentGateway: () => {} }; + +const instance = props.instance ?? ""; +console.log("Instance simplemde", instance); + const data = props.data; const onChange = props.onChange ?? (() => {}); const onChangeKeyup = props.onChangeKeyup ?? (() => {}); // in case where we want immediate action @@ -88,11 +92,11 @@ const code = ` } .CodeMirror { - min-height:200px !important; // for autocomplete to be visble + min-height:200px !important; // for autocomplete to be visible } .CodeMirror-scroll { - min-height:200px !important; // for autocomplete to be visble + min-height:200px !important; // for autocomplete to be visible } ${embeddCSS} @@ -212,46 +216,28 @@ function extractNumbers(str) { return numbers; }; +function searchCacheApi(searchProposalId) { + let searchInput = encodeURI(searchProposalId); + let searchUrl = "${cacheUrl}/proposals/search/" + searchInput; + + console.log("searchUrl, ", searchUrl); + return asyncFetch(searchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { + console.log("Error searching cache api", error); + }); +} + async function getSuggestedProposals(id) { let results = []; - const variables = { - limit: 5, - offset: 0, - where: {}, - }; + if (id) { - const proposalId = extractNumbers(id); - if (proposalId) { - variables["where"] = { proposal_id: { _eq: id } }; - } else { - variables["where"] = { - _or: [ - { name: { _iregex: id } }, - { summary: { _iregex: id } }, - { description: { _iregex: id } }, - ], - }; - } + const searchResults = await searchCacheApi(id); + results = searchResults.body.records; } - await asyncFetch("https://near-queryapi.api.pagoda.co/v1/graphql", { - method: "POST", - headers: { "x-hasura-role": "${REPL_INDEXER_HASURA_ROLE}" }, - body: JSON.stringify({ - query: query, - variables: variables, - operationName: "GetLatestSnapshot", - }), - }) - .then((res) => { - const proposals = - res?.data?.[ - "${REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME}" - ]; - results = proposals; - }) - .catch((error) => { - console.error(error); - }); return results; }; @@ -402,7 +388,7 @@ if (showAccountAutoComplete) { }); }); } - // show dropwdown only when @ is at first place or when there is a space before @ + // show dropdown only when @ is at first place or when there is a space before @ if (!mentionToken && (token.string === "@" && cursor.ch === 1 || token.string === "@" && cm.getTokenAt({line:cursor.line, ch: cursor.ch - 1}).string == ' ')) { mentionToken = token; mentionCursorStart = cursor; @@ -496,7 +482,7 @@ if (showProposalIdAutoComplete) { } } - // show dropwdown only when there is space before # or it's first char + // show dropdown only when there is space before # or it's first char if (!proposalId && (token.string === "#" && cursor.ch === 1 || token.string === "#" && cm.getTokenAt({line:cursor.line, ch: cursor.ch - 1}).string == ' ')) { proposalId = token; referenceCursorStart = cursor; diff --git a/instances/devhub.near/widget/devhub/entity/addon/blogv2/editor/form.jsx b/instances/devhub.near/widget/devhub/entity/addon/blogv2/editor/form.jsx index f5cbcf8d3..ff6063996 100644 --- a/instances/devhub.near/widget/devhub/entity/addon/blogv2/editor/form.jsx +++ b/instances/devhub.near/widget/devhub/entity/addon/blogv2/editor/form.jsx @@ -172,6 +172,7 @@ const ContentEditor = useMemo(() => { { - return asyncFetch(QUERYAPI_ENDPOINT, { - method: "POST", - headers: { "x-hasura-role": "${REPL_INDEXER_HASURA_ROLE}" }, - body: JSON.stringify({ - query: operationsDoc, - variables: variables, - operationName: operationName, - }), - }); -}; +console.log("Instance accepted terms", instance); -const queryName = "${REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME}"; -const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${queryName}_bool_exp = {}) { - ${queryName}( - offset: $offset - limit: $limit - order_by: {proposal_id: desc} - where: $where - ) { - block_height - } - }`; +const { cacheUrl } = VM.require(`${instance}/widget/config.data`); -const variables = { - limit: 10, - offset, - where: { proposal_id: { _eq: proposalId } }, -}; +const fetchAndSetProposalSnapshot = async () => { + try { + const response = await asyncFetch( + `${cacheUrl}/proposal/${props.proposalId}/snapshots`, + { + method: "GET", + headers: { accept: "application/json" }, + } + ); + + if (!response.ok) { + throw new Error(`Failed to fetch snapshots: ${response.status}`); + } -fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - if (result.status === 200) { - if (result.body.data) { - const data = result.body.data?.[queryName]; - State.update({ proposalBlockHeight: data[0].block_height }); + const snapshots = response.body; + if (!Array.isArray(snapshots) || snapshots.length === 0) { + throw new Error("No snapshots found"); } + + // Get the most recent snapshot + const latestSnapshot = snapshots.reduce((latest, current) => + current.block_height > latest.block_height ? current : latest + ); + + State.update({ proposalBlockHeight: latestSnapshot.block_height }); + } catch (error) { + console.error("Failed to fetch proposal snapshot:", error); } -}); +}; + +// Fetch snapshot data on component mount +fetchAndSetProposalSnapshot(); let acceptedTermsVersion = Near.block().header.height; +// TODO refactor this if (state.proposalBlockHeight !== null) { const data = fetch( `https://mainnet.neardata.xyz/v0/block/${state.proposalBlockHeight}` diff --git a/instances/devhub.near/widget/devhub/entity/proposal/CommentsAndLogs.jsx b/instances/devhub.near/widget/devhub/entity/proposal/CommentsAndLogs.jsx index 8da752e75..f3236305e 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/CommentsAndLogs.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/CommentsAndLogs.jsx @@ -331,7 +331,7 @@ const parseProposalKeyAndValue = (key, modifiedValue, originalValue) => { accepted ); diff --git a/instances/devhub.near/widget/devhub/entity/proposal/ComposeComment.jsx b/instances/devhub.near/widget/devhub/entity/proposal/ComposeComment.jsx index 7e8209392..317fb0149 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/ComposeComment.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/ComposeComment.jsx @@ -199,6 +199,7 @@ const Compose = useMemo(() => { { { src={ "${REPL_DEVHUB}/widget/devhub.entity.proposal.AcceptedTerms" } - props={{ proposalId: proposalId, portal: "DevHub" }} + props={{ ...props, proposalId: proposalId, portal: "DevHub" }} /> and commit to honoring it diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 9bfcfbe23..2f0b38540 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -10,6 +10,7 @@ const { proposalFeedAnnouncement, availableCategoryOptions, proposalFeedIndexerQueryName, + cacheUrl, isDevhub, isInfra, isEvents, @@ -295,13 +296,11 @@ const FeedPage = () => { }; function searchCacheApi() { - const ENDPOINT = "${REPL_CACHE_URL}"; - let searchTerm = state.input; let searchInput = encodeURI(searchTerm); - let searchUrl = `${ENDPOINT}/proposals/search/${searchInput}`; + let searchUrl = `${cacheUrl}/proposals/search/${searchInput}`; - console.log(searchUrl); + console.log("searchUrl, ", searchUrl); return asyncFetch(searchUrl, { method: "GET", headers: { @@ -341,11 +340,9 @@ const FeedPage = () => { } function fetchCacheApi(variables) { - const ENDPOINT = "${REPL_CACHE_URL}"; - console.log("Fetching endpoint", ENDPOINT); console.log("Fetching cache api", variables); - let fetchUrl = `${ENDPOINT}/proposals?order=${variables.order}&limit=${variables.limit}&offset=${variables.offset}`; + let fetchUrl = `${cacheUrl}/proposals?order=${variables.order}&limit=${variables.limit}&offset=${variables.offset}`; if (variables.author_id) { fetchUrl += `&filters.author_id=${variables.author_id}`; diff --git a/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx b/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx index 53d6eba9e..ee0c5348c 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx @@ -1,24 +1,17 @@ const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url"); href || (href = () => {}); +const instance = props.instance ?? ""; + +console.log("Instance linked proposals dropdown", instance); + +const { cacheUrl, contract } = VM.require(`${instance}/widget/config.data`); + const linkedProposals = props.linkedProposals; const onChange = props.onChange; const [selectedProposals, setSelectedProposals] = useState(linkedProposals); const [proposalsOptions, setProposalsOptions] = useState([]); const [searchProposalId, setSearchProposalId] = useState(""); -const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql`; -const queryName = "${REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME}"; -const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${queryName}_bool_exp = {}) { -${queryName}( - offset: $offset - limit: $limit - order_by: {proposal_id: desc} - where: $where -) { - name - proposal_id -} -}`; useEffect(() => { if (JSON.stringify(linkedProposals) !== JSON.stringify(selectedProposals)) { @@ -32,72 +25,42 @@ useEffect(() => { } }, [selectedProposals]); -function separateNumberAndText(str) { - const numberRegex = /\d+/; - - if (numberRegex.test(str)) { - const number = str.match(numberRegex)[0]; - const text = str.replace(numberRegex, "").trim(); - return { number: parseInt(number), text }; - } else { - return { number: null, text: str.trim() }; - } -} - -const buildWhereClause = () => { - let where = {}; - const { number, text } = separateNumberAndText(searchProposalId); +function searchCacheApi() { + let searchInput = encodeURI(searchProposalId); + let searchUrl = `${cacheUrl}/proposals/search/${searchInput}`; - if (number) { - where = { proposal_id: { _eq: number }, ...where }; - } - - if (text) { - where = { name: { _ilike: `%${text}%` }, ...where }; - } - - return where; -}; - -function fetchGraphQL(operationsDoc, operationName, variables) { - return asyncFetch(QUERYAPI_ENDPOINT, { - method: "POST", - headers: { "x-hasura-role": "${REPL_INDEXER_HASURA_ROLE}" }, - body: JSON.stringify({ - query: operationsDoc, - variables: variables, - operationName: operationName, - }), + console.log("searchUrl, ", searchUrl); + return asyncFetch(searchUrl, { + method: "GET", + headers: { + accept: "application/json", + }, + }).catch((error) => { + console.log("Error searching cache api", error); }); } -const fetchProposals = () => { - const FETCH_LIMIT = 30; - const variables = { - limit: FETCH_LIMIT, - offset: 0, - where: buildWhereClause(), - }; - fetchGraphQL(query, "GetLatestSnapshot", variables).then(async (result) => { - if (result.status === 200) { - if (result.body.data) { - const proposalsData = result.body.data[queryName]; +function searchProposals() { + if (state.loading) return; + State.update({ loading: true }); + + searchCacheApi().then((result) => { + console.log("result", result); + let proposalsData = result.body.records; - const data = []; - for (const prop of proposalsData) { - data.push({ - label: "# " + prop.proposal_id + " : " + prop.name, - value: prop.proposal_id, - }); - } - setProposalsOptions(data); - } + const data = []; + for (const prop of proposalsData) { + data.push({ + label: "# " + prop.proposal_id + " : " + prop.name, + value: prop.proposal_id, + }); } + setProposalsOptions(data); }); -}; +} useEffect(() => { - fetchProposals(); + searchProposals(); }, [searchProposalId]); return ( @@ -108,7 +71,7 @@ return ( Date: Wed, 20 Nov 2024 19:57:39 -0600 Subject: [PATCH 14/52] devhub: simplemde, acceptedTerms, passing instance --- instances/devhub.near/widget/app.jsx | 6 +- .../devhub/components/molecule/SimpleMDE.jsx | 14 ++++- .../devhub/entity/proposal/AcceptedTerms.jsx | 55 +++++++++---------- .../widget/devhub/entity/proposal/Feed.jsx | 3 - 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/instances/devhub.near/widget/app.jsx b/instances/devhub.near/widget/app.jsx index 221dce7de..42f9044c6 100644 --- a/instances/devhub.near/widget/app.jsx +++ b/instances/devhub.near/widget/app.jsx @@ -154,7 +154,7 @@ function Page() { return ( ); } @@ -163,7 +163,7 @@ function Page() { return ( ); } @@ -171,7 +171,7 @@ function Page() { return ( ); } diff --git a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx index 7ead84ab9..d604db978 100644 --- a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx +++ b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx @@ -8,6 +8,8 @@ const { getLinkUsingCurrentGateway } = VM.require( const instance = props.instance ?? ""; console.log("Instance simplemde", instance); +const { cacheUrl, contract } = VM.require(`${instance}/widget/config.data`); +console.log("Contract in simplemde", contract); const data = props.data; const onChange = props.onChange ?? (() => {}); @@ -48,7 +50,7 @@ ${queryName}( }`; const proposalLink = getLinkUsingCurrentGateway( - `${REPL_DEVHUB}/widget/app?page=proposal&id=` + `${contract}/widget/app?page=proposal&id=` ); const code = ` @@ -195,6 +197,10 @@ async function asyncFetch(endpoint, { method, headers, body }) { body: body }); + // TODO: CORS issue: origin is null in iframe + console.log("Response", response); + + if (!response.ok) { throw new Error("HTTP error!"); } @@ -218,6 +224,7 @@ function extractNumbers(str) { function searchCacheApi(searchProposalId) { let searchInput = encodeURI(searchProposalId); + // TODO: CORS issue: origin is null in iframe let searchUrl = "${cacheUrl}/proposals/search/" + searchInput; console.log("searchUrl, ", searchUrl); @@ -233,10 +240,11 @@ function searchCacheApi(searchProposalId) { async function getSuggestedProposals(id) { let results = []; - + console.log("getSuggestedProposals", id); + if (id) { const searchResults = await searchCacheApi(id); - results = searchResults.body.records; + results = searchResults?.body?.records || []; } return results; }; diff --git a/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx b/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx index fd04f408b..11759f624 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx @@ -6,41 +6,41 @@ State.init({ proposalBlockHeight: null, }); -// TODO is instance defined:? const instance = props.instance ?? ""; - +// TODO is instance defined:? console.log("Instance accepted terms", instance); const { cacheUrl } = VM.require(`${instance}/widget/config.data`); -const fetchAndSetProposalSnapshot = async () => { - try { - const response = await asyncFetch( - `${cacheUrl}/proposal/${props.proposalId}/snapshots`, - { - method: "GET", - headers: { accept: "application/json" }, +const fetchAndSetProposalSnapshot = () => { + if (!props.proposalId) { + return; + } + asyncFetch(`${cacheUrl}/proposal/${props.proposalId}/snapshots`, { + method: "GET", + headers: { accept: "application/json" }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`Failed to fetch snapshots: ${response.status}`); + } + return response.body; + }) + .then((snapshots) => { + if (!Array.isArray(snapshots) || snapshots.length === 0) { + throw new Error("No snapshots found"); } - ); - - if (!response.ok) { - throw new Error(`Failed to fetch snapshots: ${response.status}`); - } - - const snapshots = response.body; - if (!Array.isArray(snapshots) || snapshots.length === 0) { - throw new Error("No snapshots found"); - } - // Get the most recent snapshot - const latestSnapshot = snapshots.reduce((latest, current) => - current.block_height > latest.block_height ? current : latest - ); + // Get the most recent snapshot + const latestSnapshot = snapshots.reduce((latest, current) => + current.block_height > latest.block_height ? current : latest + ); - State.update({ proposalBlockHeight: latestSnapshot.block_height }); - } catch (error) { - console.error("Failed to fetch proposal snapshot:", error); - } + State.update({ proposalBlockHeight: latestSnapshot.block_height }); + }) + .catch((error) => { + console.error("Failed to fetch proposal snapshot:", error); + }); }; // Fetch snapshot data on component mount @@ -48,7 +48,6 @@ fetchAndSetProposalSnapshot(); let acceptedTermsVersion = Near.block().header.height; -// TODO refactor this if (state.proposalBlockHeight !== null) { const data = fetch( `https://mainnet.neardata.xyz/v0/block/${state.proposalBlockHeight}` diff --git a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx index 2f0b38540..c4efc026d 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/Feed.jsx @@ -300,7 +300,6 @@ const FeedPage = () => { let searchInput = encodeURI(searchTerm); let searchUrl = `${cacheUrl}/proposals/search/${searchInput}`; - console.log("searchUrl, ", searchUrl); return asyncFetch(searchUrl, { method: "GET", headers: { @@ -320,7 +319,6 @@ const FeedPage = () => { let data = result.body.records; const promises = data.map((item) => { - console.log("item.linked_rfp ", item.linked_rfp); if (isNumber(item.linked_rfp)) { // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id getRfp(item.linked_rfp).then((result) => { @@ -386,7 +384,6 @@ const FeedPage = () => { fetchCacheApi(variables).then((result) => { const body = result.body; const promises = body.records.map((item) => { - console.log("item.linked_rfp ", item.linked_rfp); if (isNumber(item.linked_rfp)) { // TODO fetch individual rfp's via the cache instead of RPC directly -> name & rfp_id getRfp(item.linked_rfp).then((result) => { From e721ee603be62fea29b96624f3d8007ff0b537e8 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Nov 2024 21:02:22 -0600 Subject: [PATCH 15/52] fix: devhub --- .../devhub/components/molecule/SimpleMDE.jsx | 18 ++++++++++++------ .../devhub/entity/proposal/AcceptedTerms.jsx | 5 +++-- .../proposal/LinkedProposalsDropdown.jsx | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx index d604db978..ddffe7563 100644 --- a/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx +++ b/instances/devhub.near/widget/devhub/components/molecule/SimpleMDE.jsx @@ -433,9 +433,11 @@ if (showProposalIdAutoComplete) { let proposalId; let referenceCursorStart; const dropdown = document.getElementById("referencedropdown"); + // Create loader element once and store it const loader = document.createElement('div'); loader.className = 'loader'; loader.textContent = 'Loading...'; + let isLoaderAttached = false; simplemde.codemirror.on("keydown", () => { if (proposalId && event.key === 'ArrowDown') { @@ -453,15 +455,22 @@ if (showProposalIdAutoComplete) { try { const proposalIdInput = cm.getRange(referenceCursorStart, cursor); dropdown.innerHTML = ''; // Clear previous content - dropdown.appendChild(loader); // Show loader + + if (!isLoaderAttached) { + dropdown.appendChild(loader); + isLoaderAttached = true; + } const suggestedProposals = await getSuggestedProposals(proposalIdInput); + + // Clear dropdown including loader dropdown.innerHTML = suggestedProposals .map( (item) => '
  • ' ) .join(""); + isLoaderAttached = false; dropdown.querySelectorAll("li").forEach((li) => { li.addEventListener("click", () => { @@ -482,11 +491,8 @@ if (showProposalIdAutoComplete) { }); } catch (error) { console.error('Error fetching data:', error); - // Handle error: Remove loader - dropdown.innerHTML = ''; // Clear previous content - } finally { - // Remove loader - dropdown.removeChild(loader); + dropdown.innerHTML = ''; // Clear content on error + isLoaderAttached = false; } } diff --git a/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx b/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx index 11759f624..eb1bf2399 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/AcceptedTerms.jsx @@ -21,14 +21,15 @@ const fetchAndSetProposalSnapshot = () => { headers: { accept: "application/json" }, }) .then((response) => { + console.log("Response accepted terms", response); if (!response.ok) { - throw new Error(`Failed to fetch snapshots: ${response.status}`); + console.error(`Failed to fetch snapshots: ${response.status}`); } return response.body; }) .then((snapshots) => { if (!Array.isArray(snapshots) || snapshots.length === 0) { - throw new Error("No snapshots found"); + console.error("No snapshots found"); } // Get the most recent snapshot diff --git a/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx b/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx index ee0c5348c..7e2bca4b2 100644 --- a/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx +++ b/instances/devhub.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx @@ -91,7 +91,7 @@ return ( setSelectedProposals(updatedLinkedProposals); }} > - + ); @@ -100,7 +100,7 @@ return ( { if (!selectedProposals.some((item) => item.value === v.value)) { setSelectedProposals([...selectedProposals, v]); From e17e72c5b6a318f9f0ace7b69f03c4e91cd9327b Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 20 Nov 2024 21:03:18 -0600 Subject: [PATCH 16/52] refactor events: deleted SimpleMDE and LinkedProposalsDropdown for both --- .../events-committee.near/widget/app.jsx | 2 +- .../widget/config/data.jsx | 1 + .../devhub/components/molecule/Compose.jsx | 2 +- .../devhub/components/molecule/SimpleMDE.jsx | 598 ------------------ .../proposal/LinkedProposalsDropdown.jsx | 158 ----- 5 files changed, 3 insertions(+), 758 deletions(-) delete mode 100644 instances/events-committee.near/widget/devhub/components/molecule/SimpleMDE.jsx delete mode 100644 instances/events-committee.near/widget/devhub/entity/proposal/LinkedProposalsDropdown.jsx diff --git a/instances/events-committee.near/widget/app.jsx b/instances/events-committee.near/widget/app.jsx index e8969533e..eb764b350 100644 --- a/instances/events-committee.near/widget/app.jsx +++ b/instances/events-committee.near/widget/app.jsx @@ -34,7 +34,7 @@ function Page() { return ( ); } diff --git a/instances/events-committee.near/widget/config/data.jsx b/instances/events-committee.near/widget/config/data.jsx index b16e70e46..f9445cfb1 100644 --- a/instances/events-committee.near/widget/config/data.jsx +++ b/instances/events-committee.near/widget/config/data.jsx @@ -46,6 +46,7 @@ return { proposalFeedIndexerQueryName: "thomasguntenaar_near_event_committee_prod_v1_proposals_with_latest_snapshot", indexerHasuraRole: "thomasguntenaar_near", + cacheUrl: "${REPL_CACHE_URL}", isEvents: true, proposalFeedAnnouncement, availableCategoryOptions: categoryOptions, diff --git a/instances/events-committee.near/widget/devhub/components/molecule/Compose.jsx b/instances/events-committee.near/widget/devhub/components/molecule/Compose.jsx index 637f4c8dc..8e5d01c24 100644 --- a/instances/events-committee.near/widget/devhub/components/molecule/Compose.jsx +++ b/instances/events-committee.near/widget/devhub/components/molecule/Compose.jsx @@ -85,7 +85,7 @@ const Compose = ({ {state.selectedTab === "editor" ? ( <> { diff --git a/instances/events-committee.near/widget/devhub/components/molecule/SimpleMDE.jsx b/instances/events-committee.near/widget/devhub/components/molecule/SimpleMDE.jsx deleted file mode 100644 index d5de9fecd..000000000 --- a/instances/events-committee.near/widget/devhub/components/molecule/SimpleMDE.jsx +++ /dev/null @@ -1,598 +0,0 @@ -/** - * iframe embedding a SimpleMDE component - * https://github.com/sparksuite/simplemde-markdown-editor - */ -const { getLinkUsingCurrentGateway } = VM.require( - "${REPL_DEVHUB}/widget/core.lib.url" -) || { getLinkUsingCurrentGateway: () => {} }; -const data = props.data; -const onChange = props.onChange ?? (() => {}); -const onChangeKeyup = props.onChangeKeyup ?? (() => {}); // in case where we want immediate action -const height = props.height ?? "390"; -const className = props.className ?? "w-100"; -const embeddCSS = props.embeddCSS; -const sortedRelevantUsers = props.sortedRelevantUsers || []; - -State.init({ - iframeHeight: height, - message: props.data, -}); - -const profilesData = Social.get("*/profile/name", "final") ?? {}; -const followingData = - Social.get(`${context.accountId}/graph/follow/**`, "final") ?? {}; - -// SIMPLEMDE CONFIG // -const fontFamily = props.fontFamily ?? "sans-serif"; -const alignToolItems = props.alignToolItems ?? "right"; -const placeholder = props.placeholder ?? ""; -const showAccountAutoComplete = props.showAutoComplete ?? false; -const showProposalIdAutoComplete = props.showProposalIdAutoComplete ?? false; -const autoFocus = props.autoFocus ?? false; - -const queryName = "${REPL_PROPOSAL_FEED_INDEXER_QUERY_NAME}"; -const query = `query GetLatestSnapshot($offset: Int = 0, $limit: Int = 10, $where: ${queryName}_bool_exp = {}) { -${queryName}( - offset: $offset - limit: $limit - order_by: {proposal_id: desc} - where: $where -) { - name - proposal_id -} -}`; - -const proposalLink = getLinkUsingCurrentGateway( - `${REPL_EVENTS}/widget/app?page=proposal&id=` -); - -const code = ` - - - - - - - - - - - - - - - - - - - - - - - -`; - -return ( -