Skip to content

Commit

Permalink
Use cache-api instead of QueryAPI for Proposals and Rfp's (#982)
Browse files Browse the repository at this point in the history
* feat: fetch from devhub-cache-api-rs.fly.dev

* @Megha-Dev-19 WIP

* wip

* fmt

* wip

* events and devhub are ready to be reviewed

* feat: infra proposals

* fmt

* feat: rfps infra

* remove comments

* fix: spelling

* fix: spelling

* replace all nearqueryapi in devhub related to proposals and rfps

* devhub: simplemde, acceptedTerms, passing instance

* fix: devhub

* refactor events: deleted SimpleMDE and LinkedProposalsDropdown for both

* test: replace all references of queryapi in tests

* test: fix linkedProposals and simpleMDE test :)

* test: skip discussions test for now

* clean up SimpleMDE

* infra: SimpleMDE, LinkedDropdown rfp + proposal, Proposal + Rfp.jsx, remove fetchgraphql from common

* test: fix events test, 1. had to deploy events with new cors policy, 2. passing instance down to simplemde, 3. mock the test on the right api path.

* test: infra -- fix: should show correct linked RFP to a proposal in feed page

* test: infra -- fix: should create proposal and link an RFP

* remove comments

* test: @petersalomonsen fixed!

* fmt

* test: discussions test back in

* test: skip discussions test

* revert: changes to rfp comment test
  • Loading branch information
Tguntenaar authored Nov 26, 2024
1 parent 5f930bc commit 2878cca
Show file tree
Hide file tree
Showing 42 changed files with 679 additions and 1,882 deletions.
3 changes: 2 additions & 1 deletion instances/devhub.near/aliases.mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
6 changes: 3 additions & 3 deletions instances/devhub.near/widget/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function Page() {
return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.entity.proposal.Editor"}
props={{ ...passProps }}
props={{ ...passProps, instance: "devhub.near" }}
/>
);
}
Expand All @@ -163,15 +163,15 @@ function Page() {
return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.page.proposals"}
props={passProps}
props={{ ...passProps, instance: "devhub.near" }}
/>
);
}
case "proposal": {
return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.entity.proposal.Proposal"}
props={passProps}
props={{ ...passProps, instance: "devhub.near" }}
/>
);
}
Expand Down
1 change: 1 addition & 0 deletions instances/devhub.near/widget/config/data.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const Compose = ({
"${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE"
}
props={{
instance: props.instance,
data: { handler: state.handler, content: state.data },
onChange: (content) => {
State.update({ data: content, handler: "update" });
Expand Down Expand Up @@ -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" });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
const { getLinkUsingCurrentGateway } = VM.require(
"${REPL_DEVHUB}/widget/core.lib.url"
) || { getLinkUsingCurrentGateway: () => {} };

const instance = props.instance ?? "";
const { cacheUrl, contract } = VM.require(`${instance}/widget/config.data`);

const data = props.data;
const onChange = props.onChange ?? (() => {});
const onChangeKeyup = props.onChangeKeyup ?? (() => {}); // in case where we want immediate action
Expand All @@ -30,21 +34,8 @@ 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_DEVHUB}/widget/app?page=proposal&id=`
`${contract}/widget/app?page=proposal&id=`
);

const code = `
Expand Down Expand Up @@ -88,11 +79,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}
Expand Down Expand Up @@ -129,7 +120,6 @@ let isEditorInitialized = false;
let followingData = {};
let profilesData = {};
let proposalLink = '';
let query = '';
let showAccountAutoComplete = ${showAccountAutoComplete};
let showProposalIdAutoComplete = ${showProposalIdAutoComplete};
Expand Down Expand Up @@ -183,12 +173,11 @@ function getSuggestedAccounts(term) {
return results;
}
async function asyncFetch(endpoint, { method, headers, body }) {
async function asyncFetch(endpoint, { method, headers }) {
try {
const response = await fetch(endpoint, {
method: method,
headers: headers,
body: body
});
if (!response.ok) {
Expand All @@ -212,46 +201,28 @@ function extractNumbers(str) {
return numbers;
};
function searchCacheApi(searchProposalId) {
let searchInput = encodeURI(searchProposalId);
let searchUrl = "${cacheUrl}/proposals/search/" + searchInput;
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?.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;
};
Expand Down Expand Up @@ -402,7 +373,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;
Expand Down Expand Up @@ -439,6 +410,7 @@ 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...';
Expand All @@ -460,8 +432,10 @@ if (showProposalIdAutoComplete) {
const proposalIdInput = cm.getRange(referenceCursorStart, cursor);
dropdown.innerHTML = ''; // Clear previous content
dropdown.appendChild(loader); // Show loader
const suggestedProposals = await getSuggestedProposals(proposalIdInput);
// Clear dropdown including loader
dropdown.innerHTML = suggestedProposals
.map(
(item) =>
Expand Down Expand Up @@ -496,7 +470,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;
Expand Down Expand Up @@ -545,9 +519,6 @@ window.addEventListener("message", (event) => {
if (event.data.profilesData) {
profilesData = JSON.parse(event.data.profilesData);
}
if (event.data.query) {
query = event.data.query;
}
if (event.data.proposalLink) {
proposalLink = event.data.proposalLink;
}
Expand All @@ -570,7 +541,6 @@ return (
content: props.data?.content ?? "",
followingData,
profilesData: JSON.stringify(profilesData),
query: query,
handler: props.data.handler,
proposalLink: proposalLink,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ const ContentEditor = useMemo(() => {
<Widget
src="${REPL_DEVHUB}/widget/devhub.components.molecule.Compose"
props={{
instance: "${REPL_DEVHUB}",
data: content,
onChange: setContent,
height: "250",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,43 @@ State.init({
proposalBlockHeight: null,
});

const proposalId = props.proposalId;
const instance = props.instance ?? "";

const QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql`;
const 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,
}),
});
};
const { cacheUrl } = VM.require(`${instance}/widget/config.data`);

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 fetchAndSetProposalSnapshot = () => {
if (!props.proposalId) {
return;
}
asyncFetch(`${cacheUrl}/proposal/${props.proposalId}/snapshots`, {
method: "GET",
headers: { accept: "application/json" },
})
.then((response) => {
if (!response.ok) {
console.error(`Failed to fetch snapshots: ${response.status}`);
}
return response.body;
})
.then((snapshots) => {
if (!Array.isArray(snapshots) || snapshots.length === 0) {
console.error("No snapshots found");
}

const variables = {
limit: 10,
offset,
where: { proposal_id: { _eq: proposalId } },
// 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);
});
};

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 });
}
}
});
// Fetch snapshot data on component mount
fetchAndSetProposalSnapshot();

let acceptedTermsVersion = Near.block().header.height;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ const parseProposalKeyAndValue = (key, modifiedValue, originalValue) => {
accepted
<Widget
src={"${REPL_DEVHUB}/widget/devhub.entity.proposal.AcceptedTerms"}
props={{ proposalId: proposalId }}
props={{ ...props, proposalId: proposalId }}
/>
</span>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const Compose = useMemo(() => {
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Compose"}
props={{
instance: props.instance,
data: comment,
onChangeKeyup: setComment,
autocompleteEnabled: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ const DescriptionComponent = useMemo(() => {
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Compose"}
props={{
instance: props.instance,
data: description,
onChange: setDescription,
autocompleteEnabled: true,
Expand All @@ -908,7 +909,7 @@ const ConsentComponent = 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
</>
Expand Down
Loading

0 comments on commit 2878cca

Please sign in to comment.