Skip to content

Commit

Permalink
refactor: staging mode (#613)
Browse files Browse the repository at this point in the history
* feat: rename staging mode to template preview mode

* fix(react): fetch template from preview urls only in preview mode

* docs: add changeset
  • Loading branch information
guerrap authored Mar 8, 2024
1 parent f721852 commit 3a10552
Show file tree
Hide file tree
Showing 24 changed files with 128 additions and 102 deletions.
8 changes: 8 additions & 0 deletions .changeset/long-carpets-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@carrot-kpi/shared-state": patch
"@carrot-kpi/host-frontend": patch
"@carrot-kpi/react": patch
"@carrot-kpi/sdk": patch
---

Rename staging mode to template preview mode, minor fix when loading templates
54 changes: 30 additions & 24 deletions packages/frontend/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,41 @@ paste the values there.
## Running modes

The frontend supports 3 different running modes: **dev**, **staging** and
**standard**.
**production**.

In standard mode the frontend will behave exactly as it would in production, and
fetch templates data directly from the blockchain (or the subgraph if not in
decentralization mode) and in the case of templates from decentralized storage
option, directly using the CIDs specified on-chain in the manager contracts.
This should in general result in a stabler experience, as only stable templates
should be allowed to reach the on-chain state.
In production mode the frontend will fetch templates data directly from the
blockchain (or the subgraph if not in decentralization mode) and in the case of
templates from decentralized storage option, directly using the CIDs specified
on-chain in the manager contracts. This should in general result in a stabler
experience, as only stable templates should be allowed to reach the on-chain
state.

Optionally, templates can also specify a `stagingURL` key in their `base.json`
specification file. When the frontend is running in staging mode the template's
federated modules (both **page** and **creation form**) will be loaded from that
URL instead of the on-chain specified decentralized storage CIDs.
Optionally, templates can also specify a `previewUrl` key in their `base.json`
specification file, that expects `development` and `staging` as sub-keys. When
the frontend is running in staging or dev mode the template's federated modules
(both **page** and **creation form**) will be loaded from that URL instead of
the on-chain specified decentralized storage CIDs.

This helps while testing out new features as it means that each template
developer can potentially set up a CI flow to build the template's frontend at
each commit and serve it through a static server (using services such as
[**Vercel**](https://vercel.com/carrot-kpi) or
[**Netlify**](https://www.netlify.com/) for example). It's then possible to add
the hosting URL in the `base.json` file under the `stagingURL` key, and any host
frontend instance running in staging mode will try to load the template's
the hosting URL in the `base.json` file under the `previewUrl` key, and any host
frontend instance running in staging or dev mode will try to load the template's
frontend from there instead of the IPFS CID specified on-chain (which, again,
contains the latest **stable** and **Carrot Labs checked** version of the
template at hand).

It's clear then that staging mode can be used to test out bleeding-edge features
of Carrot that have reached a certain maturity stage but that are **not yet
ready for production**.
It's clear then that staging and dev modes can be used to test out bleeding-edge
features of Carrot that have reached a certain maturity stage but that are **not
yet ready for production**.

> **Warning**: we recognize the risk that template developers could potentially
> push malicious code in staging mode template builds, and as such the mode
> itself is limited to only interact with testnets. Additionally, a warning will
> be visible while the frontend is running in staging mode encouraging the user
> to excercise maximum caution.
> push malicious code in staging or dev mode template builds, and as such the
> mode itself is limited to only interact with testnets. Additionally, a warning
> will be visible while the frontend is running in staging mode encouraging the
> user to excercise maximum caution.
Dev mode is simply a flag that is set to true in the shared state. Its role is
either to be read by templates or other libraries to tell them they can use dev
Expand All @@ -115,9 +116,9 @@ The frontend supports 3 different build modes: **library**, **staging** and
In production mode the frontend will be built to an optimized app ready to be
released in production, and all the available features will be enabled.

Staging mode will pretty much result in the same build, but with `stagingURL`
template loading enabled (see the "running modes" section above for more
details).
Staging or dev mode will pretty much result in the same build, but with
`previewUrl` template loading enabled (see the "running modes" section above for
more details).

Some features of the app are cut off depending on the chosen mode thanks to a
`__BUILDING_MODE__` global set to whatever the `BUILDING_MODE` env is at build
Expand All @@ -138,7 +139,7 @@ Various pieces of the app would not be functional in library mode, so we use the
`__BUILDING_MODE__` global in order to remove those pieces from the end bundle
at build time. When building in library mode through Rollup, the
`__BUILDING_MODE__` is set to `library` by default, while when building in
production and staging mode through Webpack it's set based on the
production, staging and dev mode through Webpack it's set based on the
`BUILDING_MODE` env.

## Building
Expand All @@ -156,6 +157,11 @@ Three different commands are available to build the host frontend:
`WALLETCONNECT_PROJECT_ID` and `FATHOM_SITE_ID` envs are optional and will
activate either WalletConnect or Fathom privacy preserving tracking features
only if specified.
- `build:dev`: this will build the host frontend in dev mode. The build's output
will be placed under the `build` folder, which will contain a frontend app
ready to be published. In this build the `WALLETCONNECT_PROJECT_ID` and
`FATHOM_SITE_ID` envs are optional and will activate either WalletConnect or
Fathom privacy preserving tracking features only if specified.
- `build:library`: this will bundle the app in library format, ready to be
consumed by template developers that want functional playground modes for
their template frontends. The end bundle is put under `dist` and the
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/cypress/pages/home-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export class HomePage extends BasePage {
);
this.compareText(
selectors.settings.stagingMode_Text,
textData.stagingMode,
textData.templatePreviewMode,
);
}
// selects networks from network dropdown and checks if it's been selected
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/cypress/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const textData = {
interfaceSettings: "Interface settings",
darkTheme: "Dark theme",
decentralizationMode: "Decentralization mode",
stagingMode: "Staging mode",
templatePreviewMode: "Template preview mode",
heroSectionTitle: "Reach your goals with a Carrot",
heroSectionDescription:
"Easy and powerful tool to create conditional tokens allowing an effective method to achieve any goal desirable using permissionless, decentralized technologies.",
Expand Down
16 changes: 8 additions & 8 deletions packages/frontend/src/components/connect-wallet/preferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Switch, Typography } from "@carrot-kpi/ui";
import {
usePreferDecentralization,
useSetPreferDecentralization,
useSetStagingMode,
useStagingMode,
useSetTemplatePreviewMode,
useTemplatePreviewMode,
} from "@carrot-kpi/react";
import { useTranslation } from "react-i18next";
import { useAccount } from "wagmi";
Expand All @@ -16,8 +16,8 @@ export const Preferences = () => {
const preferDecentralization = usePreferDecentralization();
const setPreferDecentralization = useSetPreferDecentralization();

const stagingMode = useStagingMode();
const setStagingMode = useSetStagingMode();
const templatePreviewMode = useTemplatePreviewMode();
const setTemplatePreviewMode = useSetTemplatePreviewMode();

// const [darkThemeSwitch, setDarkThemeSwitch] =
// useState<HTMLDivElement | null>(null);
Expand Down Expand Up @@ -120,16 +120,16 @@ export const Preferences = () => {
variant="base"
weight="bold"
>
{t("preferences.stagingMode")}
{t("preferences.templatePreviewMode")}
</Typography>
<Switch
data-testid="staging-mode-switch"
checked={stagingMode}
onChange={setStagingMode}
checked={templatePreviewMode}
onChange={setTemplatePreviewMode}
/>
</div>
<Typography variant="sm" className={{ root: "p-4" }}>
{t("preferences.stagingMode.info")}
{t("preferences.templatePreviewMode.info")}
</Typography>
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/staging-mode-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const StagingModeBanner = () => {
className={{ root: "text-center px-4 py-2" }}
>
<Typography data-testid="staging-banner-text" variant="sm">
{t("stagingMode.warning")}
{t("templatePreviewMode.warning")}
</Typography>
</FeedbackBox>
);
Expand Down
10 changes: 5 additions & 5 deletions packages/frontend/src/i18n/resources/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { CARROT_KPI_FRONTEND_I18N_NAMESPACE } from "../../constants";

export const en = {
[CARROT_KPI_FRONTEND_I18N_NAMESPACE]: {
"stagingMode.warning":
"You are using Carrot templates' staging versions. Reach out to the team in Discord for the LIVE released and audited version.",
"templatePreviewMode.warning":
"You are using Carrot templates' preview versions. Reach out to the team in Discord for the LIVE released and audited version.",
"video.notSupported": "The browser doesn't support the video tag.",
"connect.wallet": "Connect",
"connect.wallet.unknown": "Unknown",
Expand Down Expand Up @@ -50,9 +50,9 @@ export const en = {
"preferences.decentralization": "Decentralization mode",
"preferences.decentralization.info":
"Decentralization mode tries to route all calls to decentralized options. Onchain calls will be made directly to the targeted blockchain and IPFS data will always be sourced from IPFS directly.\n\nTo get the maximum out of the option, specify your custom RPC and IPFS node URLs below to make Carrot unstoppable.",
"preferences.stagingMode": "Staging mode",
"preferences.stagingMode.info":
"Staging mode loads template frontends from a developer-specified URL instead of loading the official on-chain registered frontend from IPFS.\n\nDisable the option if you want to test the (stabler) on-chain templates as opposed to the bleeding edge version of each template.",
"preferences.templatePreviewMode": "Template preview mode",
"preferences.templatePreviewMode.info":
"Template preview mode loads template frontends from a developer-specified URL instead of loading the official on-chain registered frontend from IPFS.\n\nDisable the option if you want to test the (stabler) on-chain templates as opposed to the bleeding edge version of each template.",
loading: "Loading",
search: "Search...",
"coming.soon.dark.theme": "Dark theme coming soon",
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/library-mode-entrypoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface RootProps {
kpiTokenTemplateBaseURL?: string;
oracleTemplateBaseURL?: string;
templateId?: number;
enableStagingMode?: boolean;
enableTemplatePreviewMode?: boolean;
}

export const Root = ({
Expand All @@ -31,7 +31,7 @@ export const Root = ({
oracleTemplateBaseURL,
ipfsGatewayURL,
templateId,
enableStagingMode,
enableTemplatePreviewMode,
}: RootProps) => {
const config = createConfig({
chains: [supportedChain] as const,
Expand All @@ -53,7 +53,7 @@ export const Root = ({
kpiTokenTemplateBaseURL={kpiTokenTemplateBaseURL}
oracleTemplateBaseURL={oracleTemplateBaseURL}
ipfsGatewayURL={ipfsGatewayURL}
enableStagingMode={enableStagingMode}
enableTemplatePreviewMode={enableTemplatePreviewMode}
/>
<SharedEntrypoint
config={config}
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/pages/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import { Home } from "./home";
import { Page } from "./page";
import { Campaigns } from "./campaigns";
import { CreateWithTemplateId } from "./create-with-template-id";
import { useStagingMode } from "@carrot-kpi/react";
import { useTemplatePreviewMode } from "@carrot-kpi/react";
import { StagingModeBanner } from "../components/staging-mode-banner";

interface AppProps {
templateId?: number;
}

export const App = ({ templateId }: AppProps) => {
const stagingMode = useStagingMode();
const templatePreviewMode = useTemplatePreviewMode();

const router = createHashRouter(
createRoutesFromElements(
Expand All @@ -35,7 +35,7 @@ export const App = ({ templateId }: AppProps) => {

return (
<>
{stagingMode && <StagingModeBanner />}
{templatePreviewMode && <StagingModeBanner />}
<RouterProvider router={router} />
</>
);
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/standalone-entrypoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ReactSharedStateProvider } from "@carrot-kpi/shared-state";
import {
useSetDevMode,
useSetIPFSGatewayURL,
useSetStagingMode,
useSetTemplatePreviewMode,
} from "@carrot-kpi/react";
import { readonly } from "./connectors";

Expand Down Expand Up @@ -61,11 +61,11 @@ export const config = createConfig({

export const Root = () => {
const setDevMode = useSetDevMode();
const setStagingMode = useSetStagingMode();
const setTemplatePreviewMode = useSetTemplatePreviewMode();
const setIPFSGatewayURL = useSetIPFSGatewayURL();

setDevMode(false);
setStagingMode(__ENVIRONMENT__ !== "prod");
setTemplatePreviewMode(__ENVIRONMENT__ !== "prod");
setIPFSGatewayURL(IPFS_GATEWAY_URL);

return (
Expand Down
10 changes: 5 additions & 5 deletions packages/frontend/src/updaters/library-mode-shared-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@ import {
useSetIPFSGatewayURL,
useSetKPITokenTemplateBaseURL,
useSetOracleTemplateBaseURL,
useSetStagingMode,
useSetTemplatePreviewMode,
} from "@carrot-kpi/react";

interface LibraryModeSharedStateUpdaterProps {
ipfsGatewayURL: string;
kpiTokenTemplateBaseURL?: string;
oracleTemplateBaseURL?: string;
enableStagingMode?: boolean;
enableTemplatePreviewMode?: boolean;
}

export const LibraryModeSharedStateUpdater = ({
kpiTokenTemplateBaseURL,
oracleTemplateBaseURL,
ipfsGatewayURL,
enableStagingMode = false,
enableTemplatePreviewMode = false,
}: LibraryModeSharedStateUpdaterProps) => {
const setDevMode = useSetDevMode();
const setStagingMode = useSetStagingMode();
const setTemplatePreviewMode = useSetTemplatePreviewMode();
const setIPFSGatewayURL = useSetIPFSGatewayURL();
const setKPITokenTemplateBaseURL = useSetKPITokenTemplateBaseURL();
const setOracleTemplateBaseURL = useSetOracleTemplateBaseURL();

setDevMode(true);
setStagingMode(enableStagingMode);
setTemplatePreviewMode(enableTemplatePreviewMode);
setIPFSGatewayURL(ipfsGatewayURL);
setKPITokenTemplateBaseURL(kpiTokenTemplateBaseURL);
setOracleTemplateBaseURL(oracleTemplateBaseURL);
Expand Down
24 changes: 12 additions & 12 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,20 @@
"import": "./dist/es/hooks/useSetPreferDecentralization.mjs",
"default": "./dist/cjs/hooks/useSetPreferDecentralization.cjs"
},
"./useSetStagingMode": {
"types": "./dist/types/hooks/useSetStagingMode.d.ts",
"import": "./dist/es/hooks/useSetStagingMode.mjs",
"default": "./dist/cjs/hooks/useSetStagingMode.cjs"
"./useSetTemplatePreviewMode": {
"types": "./dist/types/hooks/useSetTemplatePreviewMode.d.ts",
"import": "./dist/es/hooks/useSetTemplatePreviewMode.mjs",
"default": "./dist/cjs/hooks/useSetTemplatePreviewMode.cjs"
},
"./useSetTheme": {
"types": "./dist/types/hooks/useSetTheme.d.ts",
"import": "./dist/es/hooks/useSetTheme.mjs",
"default": "./dist/cjs/hooks/useSetTheme.cjs"
},
"./useStagingMode": {
"types": "./dist/types/hooks/useStagingMode.d.ts",
"import": "./dist/es/hooks/useStagingMode.mjs",
"default": "./dist/cjs/hooks/useStagingMode.cjs"
"./useTemplatePreviewMode": {
"types": "./dist/types/hooks/useTemplatePreviewMode.d.ts",
"import": "./dist/es/hooks/useTemplatePreviewMode.mjs",
"default": "./dist/cjs/hooks/useTemplatePreviewMode.cjs"
},
"./useTemplateModule": {
"types": "./dist/types/hooks/useTemplateModule.d.ts",
Expand Down Expand Up @@ -320,14 +320,14 @@
"useSetPreferDecentralization": [
"./dist/types/hooks/useSetPreferDecentralization.d.ts"
],
"useSetStagingMode": [
"./dist/types/hooks/useSetStagingMode.d.ts"
"useSetTemplatePreviewMode": [
"./dist/types/hooks/useSetTemplatePreviewMode.d.ts"
],
"useSetTheme": [
"./dist/types/hooks/useSetTheme.d.ts"
],
"useStagingMode": [
"./dist/types/hooks/useStagingMode.d.ts"
"useTemplatePreviewMode": [
"./dist/types/hooks/useTemplatePreviewMode.d.ts"
],
"useTemplateModule": [
"./dist/types/hooks/useTemplateModule.d.ts"
Expand Down
4 changes: 2 additions & 2 deletions packages/react/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export default [
"src/hooks/useSetKPITokenTemplateBaseURL.ts",
"src/hooks/useSetOracleTemplateBaseURL.ts",
"src/hooks/useSetPreferDecentralization.ts",
"src/hooks/useSetStagingMode.ts",
"src/hooks/useSetTemplatePreviewMode.ts",
"src/hooks/useSetTheme.ts",
"src/hooks/useStagingMode.ts",
"src/hooks/useTemplatePreviewMode.ts",
"src/hooks/useTemplateModule.ts",
"src/hooks/useTheme.ts",
"src/hooks/useTokenLists.ts",
Expand Down
6 changes: 3 additions & 3 deletions packages/react/src/components/template-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useTemplateModule } from "../hooks/useTemplateModule";
import { addBundleForTemplate } from "../i18n";
import { useState } from "react";
import { cva } from "class-variance-authority";
import { useStagingMode } from "../hooks/useStagingMode";
import { useTemplatePreviewMode } from "../hooks/useTemplatePreviewMode";
import { useTheme } from "../hooks/useTheme";
import { useMedia } from "react-use";
import { ErrorBoundary } from "./error-boundary";
Expand Down Expand Up @@ -35,11 +35,11 @@ export function TemplateComponent({
additionalProps = {},
}: BaseTemplateComponentProps) {
const { chain } = useAccount();
const stagingMode = useStagingMode();
const templatePreviewMode = useTemplatePreviewMode();

const entry =
chain && template
? `${chain.id}-${template.id}-${template.version}-${template.address}-${type}-staging-${stagingMode}`
? `${chain.id}-${template.id}-${template.version}-${template.address}-${type}-staging-${templatePreviewMode}`
: undefined;

const { loading, bundle, Component } = useTemplateModule({
Expand Down
Loading

0 comments on commit 3a10552

Please sign in to comment.