diff --git a/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx index b2f5c593c2..138ac3a7a4 100644 --- a/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx +++ b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx @@ -147,7 +147,7 @@ export class TemplatesSelectionPlugin extends ViewPlugin { ['ERC721', 'secondary'], ['ERC1155', 'primary'], ]} - title='Template explorer' + title='Workspace Templates' description="Select a template to create a workspace or to add it to current workspace" > { diff --git a/apps/remix-ide/src/app/plugins/templates-selection/templates.ts b/apps/remix-ide/src/app/plugins/templates-selection/templates.ts index 169aae0277..1a70bcd906 100644 --- a/apps/remix-ide/src/app/plugins/templates-selection/templates.ts +++ b/apps/remix-ide/src/app/plugins/templates-selection/templates.ts @@ -3,7 +3,7 @@ export const templates = (intl, plugin) => { { name: "Generic", items: [ - { value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'A default project' }, + { value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'The default project' }, { value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' } ] }, @@ -14,102 +14,102 @@ export const templates = (intl, plugin) => { value: "ozerc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], - description: 'A simple ERC20 project' + description: 'A simple fungible token contract' }, { - value: "ozerc721", - displayName: "ERC721 (NFT)", - tagList: ["ERC721", "Solidity"], - description: 'A simple ERC721 (aka NFT) project' + value: "ozerc20", + displayName: "ERC20", + description: "An ERC20 contract with:", + tagList: ["Solidity"], + opts: { + mintable: true + } }, { - value: "ozerc1155", - tagList: ["Solidity"], - displayName: "ERC1155", - description: 'A simple ERC1155 (multi token) project' + value: "ozerc20", + displayName: "ERC20", + description: "An ERC20 contract with:", + tagList: ["Solidity", "ERC20"], + opts: { + mintable: true, + burnable: true + }, }, { value: "ozerc20", displayName: "ERC20", - description: "A standard interface for fungible tokens", - tagList: ["Solidity"], + description: "An ERC20 contract with:", opts: { - mintable: true - } + mintable: true, + pausable: true + }, + tagList: ["ERC20", "Solidity"] }, { value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", - tagList: ["Solidity", "ERC721"], - opts: { - mintable: true - } + displayName: "ERC721", + tagList: ["ERC721", "Solidity"], + description: 'A simple non-fungible token (NFT) contract' }, { - value: "ozerc1155", - displayName: "ERC1155", - tagList: ["Solidity"], - description: "A standard interface for contracts that manage multiple token types", + value: "ozerc721", + displayName: "ERC721", + description: "An ERC721 contract with:", + tagList: ["Solidity", "ERC721"], opts: { mintable: true } }, { - value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", - tagList: ["Solidity", "ERC20"], + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "An ERC721 contract with:", opts: { mintable: true, burnable: true }, + tagList: ["ERC721", "Solidity"] }, { value: "ozerc721", displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + description: "An ERC721 contract with:", opts: { mintable: true, - burnable: true + pausable: true }, tagList: ["ERC721", "Solidity"] }, { value: "ozerc1155", + tagList: ["Solidity"], displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", - opts: { - mintable: true, - burnable: true - }, - tagList: ["ERC1155", "Solidity"] + description: 'A simple multi token contract' }, { - value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", + value: "ozerc1155", + displayName: "ERC1155", + tagList: ["Solidity"], + description: "An ERC1155 contract with:", opts: { - mintable: true, - pausable: true - }, - tagList: ["ERC20", "Solidity"] + mintable: true + } }, { - value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + value: "ozerc1155", + displayName: "ERC1155", + description: "An ERC1155 contract with:", opts: { mintable: true, - pausable: true + burnable: true }, - tagList: ["ERC721", "Solidity"] + tagList: ["ERC1155", "Solidity"] }, { value: "ozerc1155", displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", - tagList: ["ERC20"], + description: "An ERC1155 contract with:", + tagList: ["ERC1155"], opts: { mintable: true, pausable: true @@ -122,120 +122,120 @@ export const templates = (intl, plugin) => { items: [ { value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", + displayName: "UUPS ERC20", + description: "A simple ERC20 contract using the Universal Upgradeable Proxy Standard (UUPS) pattern", opts: { upgradeable: 'uups' }, tagList: ["ERC20", "Solidity"] }, { - value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + value: "ozerc20", + displayName: "UUPS ERC20", + description: "UUSP ERC20 contract with:", opts: { - upgradeable: 'uups' + upgradeable: 'uups', + mintable: true }, - tagList: ["ERC721", "Solidity"] + tagList: ["ERC20", "Solidity"] }, { - value: "ozerc1155", - displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", + value: "ozerc20", + displayName: "UUPS ERC20", + description: "UUSP ERC20 contract with:", opts: { - upgradeable: 'uups' + upgradeable: 'uups', + mintable: true, + burnable: true }, - tagList: ["ERC1155", "Solidity"] + tagList: ["ERC20", "Solidity"] }, { value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", + displayName: "UUPS ERC20", + description: "UUSP ERC20 contract with:", opts: { upgradeable: 'uups', - mintable: true + mintable: true, + pausable: true }, tagList: ["ERC20", "Solidity"] }, { value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + displayName: "UUPS ERC721", + description: "A simple UUPS ERC721 contract", opts: { - upgradeable: 'uups', - mintable: true + upgradeable: 'uups' }, tagList: ["ERC721", "Solidity"] }, { - value: "ozerc1155", - displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", + value: "ozerc721", + displayName: "UUPS ERC721", + description: "UUPS ERC721 contract with:", opts: { upgradeable: 'uups', mintable: true }, - tagList: ["ERC1155", "Solidity"] + tagList: ["ERC721", "Solidity"] }, { - value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", + value: "ozerc721", + displayName: "UUPS ERC721 (NFT)", + description: "Non-fungible Token Standard", opts: { upgradeable: 'uups', mintable: true, burnable: true }, - tagList: ["ERC20", "Solidity"] + tagList: ["ERC721", "Solidity"] }, { value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + displayName: "UUPS ERC721 (NFT)", + description: "UUPS ERC721 with: ", opts: { upgradeable: 'uups', mintable: true, - burnable: true + pausable: true }, tagList: ["ERC721", "Solidity"] }, { value: "ozerc1155", - displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", + displayName: "UUPS ERC1155", + description: "A simple multi token contract using the UUPS pattern", opts: { - upgradeable: 'uups', - mintable: true, - burnable: true + upgradeable: 'uups' }, tagList: ["ERC1155", "Solidity"] }, { - value: "ozerc20", - displayName: "ERC20", - description: "A standard interface for fungible tokens", + value: "ozerc1155", + displayName: "UUPS ERC1155", + description: "UUPS ERC1155 with:", opts: { upgradeable: 'uups', - mintable: true, - pausable: true + mintable: true }, - tagList: ["ERC20", "Solidity"] + tagList: ["ERC1155", "Solidity"] }, { - value: "ozerc721", - displayName: "ERC721 (NFT)", - description: "Non-fungible Token Standard", + value: "ozerc1155", + displayName: "UUPS ERC1155", + description: "UUPS ERC1155 with:", opts: { upgradeable: 'uups', mintable: true, - pausable: true + burnable: true }, - tagList: ["ERC721", "Solidity"] + tagList: ["ERC1155", "Solidity"] }, { value: "ozerc1155", - displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", + displayName: "UUPS ERC1155", + description: "UUPS ERC1155 with:", opts: { upgradeable: 'uups', mintable: true, @@ -245,8 +245,8 @@ export const templates = (intl, plugin) => { }, { value: "ozerc1155", - displayName: "ERC1155", - description: "A standard interface for contracts that manage multiple token types", + displayName: "UUPS ERC1155", + description: "UUPS ERC1155 with:", opts: { upgradeable: 'uups', mintable: true, @@ -259,12 +259,12 @@ export const templates = (intl, plugin) => { }, { name: "Cookbook", - tooltip: "Cookbook is a smart contract search tool. Click here to open cookbook and browse contracts.", + tooltip: "Cookbook is a Smart Contract Search Tool. Click here to open Cookbook and browse Contracts.", onClick: async () => { await plugin.call('manager', 'activatePlugin', 'cookbookdev') plugin.call('menuicons', 'showContent', 'cookbookdev') }, - onClickLabel: 'Open cookbook plugin', + onClickLabel: 'Open Cookbook Plugin', items: [ { value: "token-sale", displayName: 'Token Sale' }, { value: "simple-nft-sale", displayName: 'Simple Nft Sale' }, @@ -274,27 +274,30 @@ export const templates = (intl, plugin) => { { value: "nft-staking-with-infinite-rewards", displayName: 'Nft Staking with infinite rewards' }, { value: "basic-dao", displayName: 'Basic DAO' }, { value: "soulbound-nft", displayName: 'Soulbound Nft' }, - { value: "multi-collection-nft-with-burnable-nfts-and-pausable-transfers", displayName: 'Multi collection nft with burnable nfts and pausable transfers' }, + { value: "multi-collection-nft-with-burnable-nfts-and-pausable-transfers", displayName: 'Multi collection NFT', description: "Multi collection NFT with:", opts: { + burnable: true, + pausable: true + }, }, ] }, { name: "OxProject", items: [ - { value: "zeroxErc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], description: "A standard interface for fungible tokens by 0xProject" } + { value: "zeroxErc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], description: "A fungible token contract by 0xProject" } ] }, { name: "Gnosis Safe", items: [ - { value: "gnosisSafeMultisig", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.multiSigWallet' }), description: 'Deploy or Customize the Gnosis Safe.' } + { value: "gnosisSafeMultisig", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.multiSigWallet' }), description: 'Deploy or customize the Gnosis Safe.' } ] }, { name: "Circom ZKP", items: [ - { value: "semaphore", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.semaphore' }), description: 'Run a ZK Semaphore circom circuit.' }, - { value: "hashchecker", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.hashchecker' }), description: 'Run a ZK Hash checker circom circuit.' }, - { value: "rln", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.rln' }), description: 'Run a Rate Limiting Nullifier circom circuit.' } + { value: "semaphore", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.semaphore' }), description: 'Semaphore protocol for casting a message as a provable group member' }, + { value: "hashchecker", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.hashchecker' }), description: 'Hash checker Circom circuit' }, + { value: "rln", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.rln' }), description: 'Rate Limiting Nullifier Circom circuit' } ] }, { @@ -304,7 +307,7 @@ export const templates = (intl, plugin) => { value: "sindriScripts", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.addscriptsindri' }), - description: 'Use the Sindri API to compile and generate proof.' + description: 'Use the Sindri API to compile and generate proofs' }, ], }, @@ -334,12 +337,12 @@ export const templates = (intl, plugin) => { value: "contractCreate2Factory", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.addcreate2solidityfactory' }), - description: 'Factory for deploying a Contract using the CREATE2 opcode.' + description: 'Factory for deploying a contract using the CREATE2 opcode' }, { value: "contractDeployerScripts", displayName: intl.formatMessage({ id: 'filePanel.addscriptdeployer' }), - description: 'Script for deploying a Contract using the CREATE2 opcode.' + description: 'Script for deploying a contract using the CREATE2 opcode' } ] }, @@ -358,19 +361,19 @@ export const templates = (intl, plugin) => { items: [ { value: "runJsTestAction", displayName: intl.formatMessage({ id: 'filePanel.tssoltestghaction' }), - description: 'A Mocha Chai Test Workflow in a GitHub CI.' + description: 'A Mocha Chai test workflow in a GitHub CI.' }, { value: "runSolidityUnittestingAction", displayName: intl.formatMessage({ id: 'filePanel.solghaction' }), - description: 'Run a Solidity Unittest Workflow in a GitHub CI.' + description: 'Run a Solidity unit test workflow in a GitHub CI.' }, { value: "runSlitherAction", displayName: intl.formatMessage({ id: 'filePanel.slitherghaction' }), - description: 'Run a Slither Security Analysis in a GitHub CI.' + description: 'Run a Slither security analysis in a GitHub CI.' } ], IsArtefact: true } ] -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index affee6c134..ae518d686f 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -2,6 +2,9 @@ "filePanel.displayName": "File explorer", "filePanel.workspace": "WORKSPACES", "filePanel.create": "Create", + + "filePanel.createLabel": "Create Using Template", + "filePanel.createBlank":"Create Blank", "filePanel.create.desktop": "Create Project", "filePanel.clone": "Clone", "filePanel.download": "Download", @@ -9,7 +12,8 @@ "filePanel.restore": "Restore", "filePanel.name": "Name", "filePanel.save": "Save", - "filePanel.workspace.create": "Create Workspace", + "filePanel.workspace.create": "Create Workspace using template", + "filePanel.workspace.createBlank": "Create Blank Workspace", "filePanel.workspace.create.desktop": "Create project in new folder", "filePanel.workspace.rename": "Rename Workspace", "filePanel.workspace.save_workspace": "Save Workspace", diff --git a/apps/remix-ide/src/app/tabs/locales/en/settings.json b/apps/remix-ide/src/app/tabs/locales/en/settings.json index 2ea6de0d4b..41240fe28c 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/settings.json +++ b/apps/remix-ide/src/app/tabs/locales/en/settings.json @@ -1,16 +1,18 @@ { "settings.displayName": "Settings", "settings.reset": "Reset to Default settings", - "settings.general": "General settings", - "settings.generateContractMetadataText": "Generate contract metadata. Generate a JSON file in the contract folder. Allows to specify library addresses the contract depends on. If nothing is specified, Remix deploys libraries automatically.", + "settings.general": "General", + "settings.generateContractMetadataText": "Generate contract metadata", + "settings.generateContractMetadataTooltip": "Generate a JSON file in the contract folder. Allows to specify library addresses the contract depends on. If nothing is specified, Remix deploys libraries automatically.", "settings.ethereunVMText": "Always use the Remix VM at load", "settings.wordWrapText": "Word wrap in editor", - "settings.useAutoCompleteText": "Enable code completion in editor.", - "settings.useShowGasInEditorText": "Display gas estimates in editor.", - "settings.displayErrorsText": "Display errors in editor while typing.", - "settings.matomoAnalytics": "Enable Matomo Analytics. We do not collect personally identifiable information (PII). The info is used to improve the site’s UX & UI. See more about ", - "settings.enablePersonalModeText": " Enable Personal Mode for web3 provider. Transaction sent over Web3 will use the web3.personal API.\n", - "settings.warnText": "Be sure the endpoint is opened before enabling it. This mode allows a user to provide a passphrase in the Remix interface without having to unlock the account. Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...). Remix never persists any passphrase", + "settings.useAutoCompleteText": "Enable code completion in editor", + "settings.useShowGasInEditorText": "Display gas estimates in editor", + "settings.displayErrorsText": "Display errors in editor while typing", + "settings.matomoAnalytics": "Enable Matomo Analytics. See", + "settings.matomoAnalyticsTooltip": "We do not collect personally identifiable information (PII). The info is used to improve the site’s UX & UI.", + "settings.enablePersonalModeText": " Enable Personal Mode for web3 provider", + "settings.enablePersonalModeTooltip": "Transaction sent over Web3 will use the web3.personal API. Be sure the endpoint is opened before enabling it. This mode allows a user to provide a passphrase in the Remix interface without having to unlock the account. Although this is very convenient, you should completely trust the backend you are connected to (Geth, Parity, ...). Remix never persists any passphrase", "settings.gitAccessTokenTitle": "Github Credentials", "settings.gitAccessTokenText": "The access token is used to publish a Gist and retrieve GitHub contents. You may need to input username/email.", "settings.gitAccessTokenText2":"Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only 'create gist' permission", diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.css b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.css index 5c79533a71..50588fc36b 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.css +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.css @@ -21,6 +21,6 @@ } * { - scrollbar-width: thin; + scrollbar-width: 0.5rem; scrollbar-color: var(--bg-dark) var(--bg-light); -} \ No newline at end of file +} diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx index d56fe1dff9..f77700b94e 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -249,6 +249,13 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { htmlFor="generatecontractmetadata" > + + +
@@ -296,11 +303,14 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
@@ -309,7 +319,7 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { - + {' '} {' '} @@ -317,6 +327,13 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { Matomo + + +
diff --git a/libs/remix-ui/workspace/src/lib/components/createModal.tsx b/libs/remix-ui/workspace/src/lib/components/createModal.tsx new file mode 100644 index 0000000000..81b9d24a08 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/components/createModal.tsx @@ -0,0 +1,51 @@ +import React from 'react' +import { FormattedMessage } from 'react-intl' + +export const createModalMessage = async ( + defaultName: string, + gitConfigNotSet: boolean, + onChangeTemplateName: (name: string) => void, + onChangeInitGit: (name: string) => void) => { + + return ( + <> + + onChangeTemplateName(e.target.value)} + onInput={(e) => onChangeTemplateName((e.target as any).value)} + /> +
+ onChangeInitGit(e.target.value)} + onInput={(e) => onChangeInitGit((e.target as any).value)} + /> + +
+ {gitConfigNotSet ? ( +
+ +
+ ) : ( + <> + )} + + ) +} diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx index 25622b3c9a..f5df61691a 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx @@ -32,7 +32,7 @@ export function HamburgerMenuItem(props: HamburgerMenuItemProps) { > - + {props.kind === 'create' ? :}
diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx index 95de007539..860ac4042e 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx @@ -7,6 +7,7 @@ import { WorkspaceMetadata } from '../types' export interface HamburgerMenuProps { selectedWorkspace: WorkspaceMetadata createWorkspace: () => void + createBlankWorkspace: () => Promise renameCurrentWorkspace: () => void downloadCurrentWorkspace: () => void deleteCurrentWorkspace: () => void @@ -26,6 +27,16 @@ export function HamburgerMenu(props: HamburgerMenuProps) { const { showIconsMenu, hideWorkspaceOptions, hideLocalhostOptions, hideFileOperations, selectedWorkspace } = props return ( <> + { + props.createBlankWorkspace() + props.hideIconsMenu(!showIconsMenu) + }} + platforms={[appPlatformTypes.web]} + > { + const username = await global.plugin.call('settings', 'get', 'settings/github-user-name') + const email = await global.plugin.call('settings', 'get', 'settings/github-email') + const gitNotSet = !username || !email + const defaultName = await global.plugin.call('filePanel', 'getAvailableWorkspaceName', 'blank') + let workspace = defaultName + let gitInit = false + setCounter((previous) => { + return previous + 1 + }) + global.modal( + intl.formatMessage({ id: 'filePanel.workspace.createBlank' }), + await createModalMessage(`blank - ${counter}`, gitNotSet, (value) => { workspace = value }, (value) => gitInit = false), + intl.formatMessage({ id: 'filePanel.ok' }), + () => global.dispatchCreateWorkspace(`blank - ${counter}`, 'blank', false), + intl.formatMessage({ id: 'filePanel.cancel' }) + ) + } + const saveSampleCodeWorkspace = () => { const workspaceName = global.plugin.getAvailableWorkspaceName('code-sample') global.modal( @@ -926,6 +947,7 @@ export function Workspace() {