diff --git a/apps/remix-ide-e2e/src/tests/generalSettings.test.ts b/apps/remix-ide-e2e/src/tests/generalSettings.test.ts index 9c605afec0..b79d2e5054 100644 --- a/apps/remix-ide-e2e/src/tests/generalSettings.test.ts +++ b/apps/remix-ide-e2e/src/tests/generalSettings.test.ts @@ -18,6 +18,7 @@ module.exports = { 'Should activate `generate contract metadata`': function (browser) { browser.waitForElementVisible('*[data-id="remixIdeSidePanel"]', 5000) .waitForElementVisible('*[data-id="settingsTabGenerateContractMetadataLabel"]', 5000) + .verify.elementPresent('[data-id="settingsTabGenerateContractMetadata"]:checked') .click('*[data-id="verticalIconsFileExplorerIcons"]') .click('[data-id="treeViewLitreeViewItemcontracts"]') .openFile('contracts/3_Ballot.sol') @@ -39,22 +40,26 @@ module.exports = { .click('*[data-id="verticalIconsKindsettings"]') .setValue('*[data-id="settingsTabGistAccessToken"]', '**********') .click('*[data-id="settingsTabSaveGistToken"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Access token has been saved') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + .assert.containsText('*[data-shared="tooltipPopup"]', 'Access token has been saved') + .pause(3000) }, 'Should copy github access token to clipboard': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindsettings"]', 5000) .click('*[data-id="copyToClipboardCopyIcon"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Copied value to clipboard.') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + // .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1) , 5000) + // .assert.containsText('*[data-shared="tooltipPopup"]', 'Copied value to clipboard.') + // .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Copied value to clipboard.') }, 'Should remove github access token': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindsettings"]', 5000) + .pause(1000) .click('*[data-id="settingsTabRemoveGistToken"]') - .waitForElementVisible('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 5000) - .assert.containsText('*[data-shared="tooltipPopup"]:nth-last-of-type(1)', 'Access token removed') + .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) + .assert.containsText('*[data-shared="tooltipPopup"]', 'Access token removed') .assert.containsText('*[data-id="settingsTabGistAccessToken"]', '') }, diff --git a/apps/remix-ide-e2e/src/tests/runAndDeploy.ts b/apps/remix-ide-e2e/src/tests/runAndDeploy.ts index 20455df8b3..a138bc77d1 100644 --- a/apps/remix-ide-e2e/src/tests/runAndDeploy.ts +++ b/apps/remix-ide-e2e/src/tests/runAndDeploy.ts @@ -32,6 +32,8 @@ module.exports = { 'Should sign message using account key': function (browser: NightwatchBrowser) { browser.waitForElementPresent('*[data-id="settingsRemixRunSignMsg"]') + .click('select[id="selectExEnvOptions"] option[value="vm-berlin"]') + .pause(2000) .click('*[data-id="settingsRemixRunSignMsg"]') .pause(2000) .waitForElementPresent('*[data-id="modalDialogCustomPromptText"]') diff --git a/apps/remix-ide/src/app/tabs/settings-tab.js b/apps/remix-ide/src/app/tabs/settings-tab.js index 3ef4d2953d..8c3889a02b 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.js +++ b/apps/remix-ide/src/app/tabs/settings-tab.js @@ -1,12 +1,10 @@ +import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' +import ReactDOM from 'react-dom' import * as packageJson from '../../../../../package.json' -const yo = require('yo-yo') +import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line const globalRegistry = require('../../global/registry') -const tooltip = require('../ui/tooltip') -const copyToClipboard = require('../ui/copy-to-clipboard') const EventManager = require('../../lib/events') -const css = require('./styles/settings-tab-styles') -const _paq = window._paq = window._paq || [] const profile = { name: 'settings', @@ -51,210 +49,27 @@ module.exports = class SettingsTab extends ViewPlugin { textWrapLabel: null } /* eslint-enable */ this.event = new EventManager() + this.element = document.createElement('div') + this.element.setAttribute('id', 'settingsTab') } - createThemeCheckies () { - const themes = this._deps.themeModule.getThemes() - const onswitchTheme = (event, name) => { - this._deps.themeModule.switchTheme(name) - } - if (themes) { - return yo`
- ${themes.map((aTheme) => { - const el = yo`
- { onswitchTheme(event, aTheme.name) }} class="align-middle custom-control-input" name="theme" id="${aTheme.name}" data-id="settingsTabTheme${aTheme.name}"> - -
` - if (this._deps.themeModule.active === aTheme.name) el.querySelector('input').setAttribute('checked', 'checked') - return el - })} -
` - } + onActivation () { + this.renderComponent() } render () { - const self = this - if (self._view.el) return self._view.el - - // Gist settings - const token = this.config.get('settings/gist-access-token') - const gistAccessToken = yo`` - if (token) gistAccessToken.value = token - const removeToken = () => { self.config.set('settings/gist-access-token', ''); gistAccessToken.value = ''; tooltip('Access token removed') } - const saveToken = () => { - this.config.set('settings/gist-access-token', gistAccessToken.value) - tooltip('Access token has been saved. RELOAD the page to apply it.') - } - const gistAddToken = yo` saveToken()} value="Save" type="button">` - const gistRemoveToken = yo`` - this._view.gistToken = yo` -
- ${gistAccessToken} -
- ${copyToClipboard(() => gistAccessToken.value)}${gistAddToken}${gistRemoveToken} -
-

- - Please reload Remix after having saved the token. -

-
- ` - this._view.optionVM = yo`` - this._view.optionVMLabel = yo`` - if (this.config.get('settings/always-use-vm') === undefined) this.config.set('settings/always-use-vm', true) - if (this.config.get('settings/always-use-vm')) this._view.optionVM.setAttribute('checked', '') - elementStateChanged(self._view.optionVMLabel, !this.config.get('settings/always-use-vm')) - - this._view.textWrap = yo`` - this._view.textWrapLabel = yo`` - if (this.config.get('settings/text-wrap')) this._view.textWrap.setAttribute('checked', '') - elementStateChanged(self._view.textWrapLabel, !this.config.get('settings/text-wrap')) - - const warnText = `Transaction sent over Web3 will use the web3.personal API - be sure the endpoint is opened before enabling it. - This mode allows to provide the 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 persist any passphrase.`.split('\n').map(s => s.trim()).join(' ') - - this._view.personal = yo`` - this._view.warnPersonalMode = yo`` - this._view.personalLabel = yo`` - if (this.config.get('settings/personal-mode')) this._view.personal.setAttribute('checked', '') - elementStateChanged(self._view.personalLabel, !this.config.get('settings/personal-mode')) - - this._view.useMatomoAnalytics = yo`` - this._view.useMatomoAnalyticsLabel = yo` - - ` - if (this.config.get('settings/matomo-analytics')) { - this._view.useMatomoAnalytics.setAttribute('checked', '') - _paq.push(['forgetUserOptOut']) - // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used - document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' - } else { - _paq.push(['optUserOut']) - } - elementStateChanged(self._view.useMatomoAnalyticsLabel, !this.config.get('settings/matomo-analytics')) - - this._view.generateContractMetadata = yo`` - this._view.generateContractMetadataLabel = yo`` - if (this.config.get('settings/generate-contract-metadata') === undefined) this.config.set('settings/generate-contract-metadata', true) - if (this.config.get('settings/generate-contract-metadata')) this._view.generateContractMetadata.setAttribute('checked', '') - elementStateChanged(self._view.generateContractMetadataLabel, !this.config.get('settings/generate-contract-metadata')) - - this._view.pluginInput = yo`` - - this._view.themes = this._deps.themeModule.getThemes() - this._view.themesCheckBoxes = this.createThemeCheckies() - - this._view.config.general = yo` -
-
-
General settings
-
- ${this._view.generateContractMetadata} - ${this._view.generateContractMetadataLabel} -
-
- ${this._view.optionVM} - ${this._view.optionVMLabel} -
-
- ${this._view.textWrap} - ${this._view.textWrapLabel} -
-
- ${this._view.personal} - ${this._view.personalLabel} -
-
- ${this._view.useMatomoAnalytics} - ${this._view.useMatomoAnalyticsLabel} -
-
-
- ` - this._view.gistToken = yo` -
-
-
Github Access Token
-

Manage the access token used to publish to Gist and retrieve Github contents.

-

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.

-

https://github.com/settings/tokens

-
${this._view.gistToken}
-
-
` - this._view.config.themes = yo` -
-
-
Themes
- ${this._view.themesCheckBoxes} -
-
` - this._view.el = yo` -
- ${this._view.config.general} - ${this._view.gistToken} - ${this._view.config.themes} -
` - - function onchangeGenerateContractMetadata (event) { - const isChecked = self.config.get('settings/generate-contract-metadata') - - self.config.set('settings/generate-contract-metadata', !isChecked) - elementStateChanged(self._view.generateContractMetadataLabel, isChecked) - } - - function onchangeOption (event) { - const isChecked = self.config.get('settings/always-use-vm') - - self.config.set('settings/always-use-vm', !isChecked) - elementStateChanged(self._view.optionVMLabel, isChecked) - } - - function textWrapEvent (event) { - const isChecked = self.config.get('settings/text-wrap') - - self.config.set('settings/text-wrap', !isChecked) - elementStateChanged(self._view.textWrapLabel, isChecked) - self.editor.resize(!isChecked) - } - - function onchangePersonal (event) { - const isChecked = self.config.get('settings/personal-mode') - - self.config.set('settings/personal-mode', !isChecked) - elementStateChanged(self._view.personalLabel, isChecked) - } - - function onchangeMatomoAnalytics (event) { - const isChecked = self.config.get('settings/matomo-analytics') - - self.config.set('settings/matomo-analytics', !isChecked) - elementStateChanged(self._view.useMatomoAnalyticsLabel, isChecked) - if (event.target.checked) { - _paq.push(['forgetUserOptOut']) - // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used - document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' - } else { - _paq.push(['optUserOut']) - } - } - - function elementStateChanged (el, isChanged) { - if (isChanged) { - el.classList.remove('text-dark') - el.classList.add('text-secondary') - } else { - el.classList.add('text-dark') - el.classList.remove('text-secondary') - } - } + return this.element + } - this._deps.themeModule.switchTheme() - return this._view.el + renderComponent () { + ReactDOM.render( + , + this.element + ) } getGithubAccessToken () { diff --git a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx index 2bea5aed07..fbfdc6dfba 100644 --- a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx +++ b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx @@ -6,6 +6,7 @@ import './copy-to-clipboard.css' export const CopyToClipboard = ({ content, tip='Copy', icon='fa-copy', ...otherProps }) => { const [message, setMessage] = useState(tip) + const handleClick = (event) => { if (content && content !== '') { // module `copy` keeps last copied thing in the memory, so don't show tooltip if nothing is copied, because nothing was added to memory try { diff --git a/libs/remix-ui/settings/.babelrc b/libs/remix-ui/settings/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/settings/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/settings/.eslintrc b/libs/remix-ui/settings/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/settings/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/settings/README.md b/libs/remix-ui/settings/README.md new file mode 100644 index 0000000000..d4a8337744 --- /dev/null +++ b/libs/remix-ui/settings/README.md @@ -0,0 +1,7 @@ +# remix-ui-settings + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-settings` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/settings/src/index.ts b/libs/remix-ui/settings/src/index.ts new file mode 100644 index 0000000000..432ac58185 --- /dev/null +++ b/libs/remix-ui/settings/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-settings' diff --git a/libs/remix-ui/settings/src/lib/constants.ts b/libs/remix-ui/settings/src/lib/constants.ts new file mode 100644 index 0000000000..4d6d2a06de --- /dev/null +++ b/libs/remix-ui/settings/src/lib/constants.ts @@ -0,0 +1,12 @@ +export const 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.' +export const textSecondary = 'text-secondary' +export const textDark = 'text-dark' +export const warnText = 'Be sure the endpoint is opened before enabling it. \nThis 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'.split('\n').map(s => s.trim()).join(' ') +export const gitAccessTokenTitle = 'Github Access Token' +export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve Github contents.' +export const 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.' +export const gitAccessTokenLink = 'https://github.com/settings/tokens' +export const ethereunVMText = 'Always use Ethereum VM at load' +export const wordWrapText = 'Word wrap in editor' +export const enablePersonalModeText = ' Enable Personal Mode for web3 provider. Transaction sent over Web3 will use the web3.personal API.\n' +export const 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 ' diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.css b/libs/remix-ui/settings/src/lib/remix-ui-settings.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx new file mode 100644 index 0000000000..ef8c3ed6c5 --- /dev/null +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -0,0 +1,166 @@ +import React, { useState, useReducer, useEffect, useCallback } from 'react' // eslint-disable-line +import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line + +import { enablePersonalModeText, ethereunVMText, generateContractMetadataText, gitAccessTokenLink, gitAccessTokenText, gitAccessTokenText2, gitAccessTokenTitle, matomoAnalytics, textDark, textSecondary, warnText, wordWrapText } from './constants' + +import './remix-ui-settings.css' +import { etherumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast } from './settingsAction' +import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer' +import { Toaster } from '@remix-ui/toaster'// eslint-disable-line + +/* eslint-disable-next-line */ +export interface RemixUiSettingsProps { + config: any, + editor: any, + _deps: any +} + +export const RemixUiSettings = (props: RemixUiSettingsProps) => { + const [, dispatch] = useReducer(settingReducer, initialState) + const [state, dispatchToast] = useReducer(toastReducer, toastInitialState) + const [tokenValue, setTokenValue] = useState('') + const [themeName, setThemeName] = useState('') + + useEffect(() => { + const token = props.config.get('settings/gist-access-token') + if (token === undefined) { + props.config.set('settings/generate-contract-metadata', true) + dispatch({ type: 'contractMetadata', payload: { name: 'contractMetadata', isChecked: true, textClass: textDark } }) + } + if (token) { + setTokenValue(token) + } + }, [themeName, state.message]) + + const onchangeGenerateContractMetadata = (event) => { + generateContractMetadat(props, event, dispatch) + } + + const onchangeOption = (event) => { + etherumVM(props, event, dispatch) + } + + const textWrapEvent = (event) => { + textWrapEventAction(props, event, dispatch) + } + + const onchangePersonal = event => { + personal(props, event, dispatch) + } + + const onchangeMatomoAnalytics = event => { + useMatomoAnalytics(props, event, dispatch) + } + + const onswitchTheme = (event, name) => { + props._deps.themeModule.switchTheme(name) + setThemeName(name) + } + + const getTextClass = (key) => { + if (props.config.get(key)) { + return textDark + } else { + return textSecondary + } + } + + const generalConfig = () => ( +
+
+
General settings
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ) + + const saveToken = () => { + saveTokenToast(props, dispatchToast, tokenValue) + } + + const removeToken = () => { + setTokenValue('') + removeTokenToast(props, dispatchToast) + } + + const handleSaveTokenState = useCallback( + (event) => { + setTokenValue(event.target.value) + }, + [tokenValue] + ) + + const gistToken = () => ( +
+
+
{ gitAccessTokenTitle }
+

{ gitAccessTokenText }

+

{ gitAccessTokenText2 }

+

{ gitAccessTokenLink }

+
+
+ +
+ + saveToken()} value="Save" type="button" disabled={tokenValue === ''}> + +
+
+
+
+ ) + + const themes = () => { + const themes = props._deps.themeModule.getThemes() + if (themes) { + return themes.map((aTheme, index) => ( +
+ { onswitchTheme(event, aTheme.name) }} className="align-middle custom-control-input" name='theme' id={aTheme.name} data-id={`settingsTabTheme${aTheme.name}`} checked = {props._deps.themeModule.active === aTheme.name ? true : null}/> + +
+ ) + ) + } + } + + return ( +
+ {state.message ? : null} + {generalConfig()} + {gistToken()} +
+
+
Themes
+
+ {themes()} +
+
+
+
+ ) +} diff --git a/libs/remix-ui/settings/src/lib/settingsAction.ts b/libs/remix-ui/settings/src/lib/settingsAction.ts new file mode 100644 index 0000000000..055c84449b --- /dev/null +++ b/libs/remix-ui/settings/src/lib/settingsAction.ts @@ -0,0 +1,52 @@ +import { textDark, textSecondary } from './constants' + +declare global { + interface Window { + _paq: any + } +} + +const _paq = window._paq = window._paq || [] //eslint-disable-line + +export const generateContractMetadat = (element, event, dispatch) => { + element.config.set('settings/generate-contract-metadata', event.target.checked) + dispatch({ type: 'contractMetadata', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const etherumVM = (element, event, dispatch) => { + element.config.set('settings/always-use-vm', event.target.checked) + dispatch({ type: 'ethereumVM', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const textWrapEventAction = (element, event, dispatch) => { + element.config.set('settings/text-wrap', event.target.checked) + element.editor.resize(event.target.checked) + dispatch({ type: 'textWrap', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const personal = (element, event, dispatch) => { + element.config.set('settings/personal-mode', event.target.checked) + dispatch({ type: 'personal', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) +} + +export const useMatomoAnalytics = (element, event, dispatch) => { + element.config.set('settings/matomo-analytics', event.target.checked) + dispatch({ type: 'useMatomoAnalytics', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) + if (event.target.checked) { + _paq.push(['forgetUserOptOut']) + // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used + document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' + } else { + _paq.push(['optUserOut']) + } +} + +export const saveTokenToast = (props, dispatch, tokenValue) => { + props.config.set('settings/gist-access-token', tokenValue) + dispatch({ type: 'save', payload: { message: 'Access token has been saved' } }) +} + +export const removeTokenToast = (props, dispatch) => { + props.config.set('settings/gist-access-token', '') + dispatch({ type: 'removed', payload: { message: 'Access token removed' } }) +} diff --git a/libs/remix-ui/settings/src/lib/settingsReducer.ts b/libs/remix-ui/settings/src/lib/settingsReducer.ts new file mode 100644 index 0000000000..daf6453959 --- /dev/null +++ b/libs/remix-ui/settings/src/lib/settingsReducer.ts @@ -0,0 +1,103 @@ +import { textSecondary } from './constants' + +export const initialState = { + elementState: [ + { + name: 'contractMetadata', + isChecked: false, + textClass: textSecondary + }, + { + name: 'ethereumVM', + isChecked: false, + textClass: textSecondary + }, + { + name: 'textWrap', + isChecked: false, + textClass: textSecondary + }, + { + name: 'personal', + isChecked: false, + textClass: textSecondary + }, + { + name: 'useMatomoAnalytics', + isChecked: false, + textClass: textSecondary + } + ] +} + +export const settingReducer = (state, action) => { + switch (action.type) { + case 'contractMetadata': + state.elementState.map(element => { + if (element.name === 'contractMetadata') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'ethereumVM': + state.elementState.map(element => { + if (element.name === 'ethereumVM') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'textWrap': + state.elementState.map(element => { + if (element.name === 'textWrap') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'personal': + state.elementState.map(element => { + if (element.name === 'personal') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + case 'useMatomoAnalytics': + state.elementState.map(element => { + if (element.name === 'useMatomoAnalytics') { + element.isChecked = action.payload.isChecked + element.textClass = action.payload.textClass + } + }) + return { + ...state + } + default: + return initialState + } +} + +export const toastInitialState = { + message: '' +} + +export const toastReducer = (state, action) => { + switch (action.type) { + case 'save' : + return { ...state, message: action.payload.message } + case 'removed' : + return { ...state, message: action.payload.message } + default : + return { ...state, message: '' } + } +} diff --git a/libs/remix-ui/settings/tsconfig.json b/libs/remix-ui/settings/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/settings/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/settings/tsconfig.lib.json b/libs/remix-ui/settings/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/settings/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index a63c015d64..64d8dcaeaf 100644 --- a/nx.json +++ b/nx.json @@ -96,11 +96,17 @@ "remix-ui-workspace": { "tags": [] }, + "remix-ui-settings": { + "tags": [] + }, "remix-ui-static-analyser": { "tags": [] }, "remix-ui-checkbox": { "tags": [] + }, + "remix-ui-settings": { + "tags": [] } } } diff --git a/package.json b/package.json index 07ab9d39e1..e238787d68 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", diff --git a/tsconfig.json b/tsconfig.json index 75db5bc6ff..573a63975e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,8 +39,10 @@ "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"], "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], - "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], + "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 5d2bf912c0..04da7184e5 100644 --- a/workspace.json +++ b/workspace.json @@ -726,6 +726,22 @@ } } }, + "remix-ui-settings": { + "root": "libs/remix-ui/settings", + "sourceRoot": "libs/remix-ui/settings/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/settings/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/settings/**/*"] + } + } + } + }, "remix-ui-static-analyser": { "root": "libs/remix-ui/static-analyser", "sourceRoot": "libs/remix-ui/static-analyser/src", @@ -828,4 +844,4 @@ } }, "defaultProject": "remix-ide" -} +} \ No newline at end of file