moving file states

editorcontextDummy
filip mertens 2 years ago
parent 1509c87519
commit a863e37dd6
  1. 6
      apps/remix-ide/src/app.js
  2. 1
      apps/remix-ide/src/app/components/hidden-panel.tsx
  3. 6
      apps/remix-ide/src/app/panels/file-panel.js
  4. 7
      apps/remix-ide/src/app/panels/tab-proxy.js
  5. 1
      libs/remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  6. 1
      libs/remix-core-plugin/src/index.ts
  7. 52
      libs/remix-core-plugin/src/lib/code-parser.tsx
  8. 57
      libs/remix-core-plugin/src/lib/file-states.ts
  9. 1
      libs/remix-core-plugin/tsconfig.lib.json
  10. 1
      libs/remix-debug/src/index.ts
  11. 4
      libs/remix-ui/file-states/.babelrc
  12. 19
      libs/remix-ui/file-states/.eslintrc
  13. 3
      libs/remix-ui/file-states/src/index.ts
  14. 48
      libs/remix-ui/file-states/src/lib/components/file-state-icon.tsx
  15. 4
      libs/remix-ui/file-states/src/lib/components/filestates/file-state-custom-icon.tsx
  16. 6
      libs/remix-ui/file-states/src/lib/components/filestates/file-state-error-icon.tsx
  17. 6
      libs/remix-ui/file-states/src/lib/components/filestates/file-state-warning-icon.tsx
  18. 37
      libs/remix-ui/file-states/src/lib/types/index.ts
  19. 16
      libs/remix-ui/file-states/tsconfig.json
  20. 13
      libs/remix-ui/file-states/tsconfig.lib.json
  21. 88
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  22. 2
      libs/remix-ui/workspace/src/index.ts
  23. 2
      libs/remix-ui/workspace/src/lib/actions/events.ts
  24. 6
      libs/remix-ui/workspace/src/lib/components/file-label.tsx
  25. 7
      libs/remix-ui/workspace/src/lib/components/file-render.tsx
  26. 56
      libs/remix-ui/workspace/src/lib/components/file-state.tsx
  27. 0
      libs/remix-ui/workspace/src/lib/components/filestates/file-state-icon-properties.tsx
  28. 28
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  29. 30
      libs/remix-ui/workspace/src/lib/types/index.ts
  30. 3
      nx.json
  31. 2
      package.json
  32. 1
      tsconfig.base.json
  33. 15
      workspace.json

@ -13,7 +13,7 @@ import { LandingPage } from './app/ui/landing-page/landing-page'
import { MainPanel } from './app/components/main-panel'
import { PermissionHandlerPlugin } from './app/plugins/permission-handler-plugin'
import { AstWalker } from '@remix-project/remix-astwalker'
import { LinkLibraries, DeployLibraries, OpenZeppelinProxy, CodeParser } from '@remix-project/core-plugin'
import { LinkLibraries, DeployLibraries, OpenZeppelinProxy, CodeParser, FileStates } from '@remix-project/core-plugin'
import { WalkthroughService } from './walkthroughService'
@ -204,6 +204,7 @@ class AppComponent {
)
const contextualListener = new EditorContextListener(new AstWalker())
const codeParser = new CodeParser(new AstWalker())
const fileStates = new FileStates()
this.notification = new NotificationPlugin()
@ -229,6 +230,7 @@ class AppComponent {
offsetToLineColumnConverter,
contextualListener,
codeParser,
fileStates,
terminal,
web3Provider,
compileAndRun,
@ -355,7 +357,7 @@ class AppComponent {
await this.appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await this.appManager.activatePlugin(['home'])
await this.appManager.activatePlugin(['settings', 'config'])
await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'contextualListener', 'codeParser', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler'])
await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'contextualListener', 'codeParser', 'fileStates', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler'])
await this.appManager.activatePlugin(['settings'])
await this.appManager.activatePlugin(['walkthrough','storage', 'search','compileAndRun'])

@ -5,6 +5,7 @@ import * as packageJson from '../../../../../package.json'
import { RemixPluginPanel } from '@remix-ui/panel'
import { PluginViewWrapper } from '@remix-ui/helper'
const profile = {
name: 'hiddenPanel',
displayName: 'Hidden Panel',

@ -85,9 +85,9 @@ module.exports = class Filepanel extends ViewPlugin {
})
}
async setFileState (items) {
console.log(items)
this.emit('setFileState', items)
async setFileState (fileState) {
console.log(fileState)
this.emit('setFileState', fileState)
}
getCurrentWorkspace () {

@ -169,6 +169,10 @@ export class TabProxy extends Plugin {
this.on('manager', 'pluginDeactivated', (profile) => {
this.removeTab(profile.name)
})
this.on('fileStates', 'fileStateChanged', async (items) => {
this.tabsApi.setFileStates(items)
})
try {
this.themeQuality = (await this.call('theme', 'currentTheme') ).quality
@ -306,6 +310,7 @@ export class TabProxy extends Plugin {
updateComponent(state) {
return <TabsUI
plugin={state.plugin}
tabs={state.loadedTabs}
onSelect={state.onSelect}
onClose={state.onClose}
@ -317,6 +322,7 @@ export class TabProxy extends Plugin {
}
renderComponent () {
console.log('rendering tabs')
const onSelect = (index) => {
if (this.loadedTabs[index]) {
const name = this.loadedTabs[index].name
@ -339,6 +345,7 @@ export class TabProxy extends Plugin {
const onReady = (api) => { this.tabsApi = api }
this.dispatch({
plugin: this,
loadedTabs: this.loadedTabs,
onSelect,
onClose,

@ -9,6 +9,7 @@ import {
FunctionHLAst, ReportObj, ReportFunction, VisitFunction, ModifierHLAst, CompilationResult
} from '../../types'
type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean, version: string) => ReportObj[])
export default class abstractAstView {

@ -9,3 +9,4 @@ export * from './types/contract'
export { LinkLibraries, DeployLibraries } from './lib/link-libraries'
export { OpenZeppelinProxy } from './lib/openzeppelin-proxy'
export { CodeParser } from './lib/code-parser'
export { FileStates } from './lib/file-states'

@ -8,8 +8,10 @@ import { AstNode, CompilationError, CompilationResult, CompilationSource } from
import { helper } from '@remix-project/remix-solidity'
import React from 'react'
import { fileState, fileStateType } from '@remix-ui/file-states'
// eslint-disable-next-line
import { fileState, fileStateType } from '@remix-ui/workspace'
const SolidityParser = (window as any).SolidityParser = (window as any).SolidityParser || []
const profile = {
@ -111,12 +113,18 @@ export class CodeParser extends Plugin {
}
console.log('allErrors', allErrors)
await this.call('editor', 'addErrorMarker', allErrors)
for(const error of allErrors){
}
try {
let fileState:fileState = {
path: this.currentFile,
isDirectory: false,
fileStateType: [fileStateType.Custom],
fileStateType: fileStateType.Custom,
fileStateLabelClass: 'text-success',
fileStateIconClass: '',
fileStateIcon: <i className="text-success fas fa-smile"></i>,
@ -124,27 +132,53 @@ export class CodeParser extends Plugin {
owner: 'code-parser',
bubble: true
}
await this.call('filePanel', 'setFileState', [fileState])
await this.call('fileStates', 'setFileState', fileState)
fileState = {
...fileState,
path: 'contracts/1_Storage.sol',
fileStateLabelClass: 'text-danger',
fileStateIcon: <i className="text-danger fas fa-spinner fa-spin"></i>,
}
await this.call('filePanel', 'setFileState', [fileState])
fileState = {
...fileState,
path: 'scripts/ethers-lib.ts',
fileStateLabelClass: 'text-danger',
fileStateIcon: <div className='btn btn-danger btn-sm'><li className='fa fa-phone'></li>call rob now!</div>,
fileStateIcon: <div className='btn btn-danger btn-sm'>call rob now!</div>,
}
await this.call('filePanel', 'setFileState', [fileState])
await this.call('fileStates', 'setFileState', fileState)
const states:fileState[] = [
{
path: 'contracts/2_Owner.sol',
isDirectory: false,
fileStateType: fileStateType.Custom,
fileStateLabelClass: 'text-success',
fileStateIconClass: '',
fileStateIcon: <i className="text-success fas fa-smile"></i>,
comment: '',
owner: 'code-parser',
bubble: true
},
{
path: 'contracts/2_Owner.sol',
isDirectory: false,
fileStateType: fileStateType.Custom,
fileStateLabelClass: 'text-danger',
fileStateIconClass: '',
fileStateIcon: <i className="text-danger fas fa-smile"></i>,
comment: '',
owner: 'code-parser',
bubble: true
}
]
await this.call('fileStates', 'setFileState', states)
} catch (e) {
} catch (e) {
console.log('error calling filePanel', e)
}
} else {
await this.call('filePanel', 'setFileState', [{
await this.call('fileStates', 'setFileState', [{
path: this.currentFile,
isDirectory: false,
fileStateType: [],

@ -0,0 +1,57 @@
'use strict'
import { default as deepequal } from 'deep-equal' // eslint-disable-line
import { Plugin } from '@remixproject/engine'
import { fileState } from '@remix-ui/file-states'
const profile = {
name: 'fileStates',
desciption: 'Keeps state of the files',
methods: ['setFileState'],
events: ['fileStateChanged'],
version: '0.0.1'
}
export class FileStates extends Plugin {
private _fileStates: fileState[] = []
constructor() {
super(profile)
}
/**
*
* @param fileStates Array of file states
*/
async setFileState(fileStates: fileState[] | fileState) {
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
function sortByPath( a, b ) {
if ( a.path < b.path ){
return -1;
}
if ( a.path > b.path ){
return 1;
}
return 0;
}
const fileStatesPayload = Array.isArray(fileStates) ? fileStates : [fileStates]
// clear all file states in the previous state of this owner on the files called
fileStatesPayload.forEach((state) => {
state.workspace = workspace
})
const filteredState = this._fileStates.filter((state) => {
const index = fileStatesPayload.findIndex((payloadFileState: fileState) => {
return payloadFileState.owner == state.owner && payloadFileState.path == state.path
})
return index == -1
})
const newState = [...filteredState, ...fileStatesPayload].sort(sortByPath)
if (!deepequal(newState, this._fileStates)) {
this._fileStates = newState
console.log('fileStates', this._fileStates)
this.emit('fileStateChanged', this._fileStates)
}
}
}

@ -6,7 +6,6 @@
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"declaration": true,
"rootDir": "./src",
"types": ["node"]
},
"exclude": [

@ -10,6 +10,7 @@ import { BreakpointManager } from './code/breakpointManager'
import * as sourceMappingDecoder from './source/sourceMappingDecoder'
import * as traceHelper from './trace/traceHelper'
/*
Use of breakPointManager :

@ -0,0 +1,4 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}

@ -0,0 +1,19 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": "../../../.eslintrc.json",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}

@ -0,0 +1,3 @@
export { fileState, fileStateType } from './lib/types/index'
export { FileStateIcons } from './lib/components/file-state-icon'

@ -0,0 +1,48 @@
// eslint-disable-next-line no-use-before-define
import React, { useEffect, useState } from 'react'
import { fileState, fileStateType, FileType } from '../types'
import FileStateCustomIcon from './filestates/file-state-custom-icon'
import FileStateErrorIcon from './filestates/file-state-error-icon'
import FileStateWarningIcon from './filestates/file-state-warning-icon'
export type fileStateProps = {
file: FileType,
fileState: fileState[]
}
export const FileStateIcons = (props: fileStateProps) => {
const [states, setStates] = useState<fileState[]>([])
useEffect(() => {
//console.log(props.file)
//console.log(props.fileState)
setStates(props.fileState.filter((st) => st.path === props.file.path))
}, [props.fileState])
const getTags = function () {
if (states && states.length) {
const elements: JSX.Element[] = []
for (const [index, state] of states.entries()) {
switch (state.fileStateType) {
case fileStateType.Error:
elements.push(<FileStateErrorIcon fileState={state} key={index} />)
break
case fileStateType.Warning:
elements.push(<FileStateWarningIcon fileState={state} key={index}/>)
break
case fileStateType.Custom:
elements.push(<FileStateCustomIcon fileState={state} key={index} />)
break
}
}
return elements
}
}
return <>
{getTags()}
</>
}
export default FileStateIcons

@ -2,7 +2,7 @@
import React from 'react'
import { fileState } from '../../types'
const FileStateError = (props: {
const FileStateCustomIcon = (props: {
fileState: fileState
}) => {
return <><span className={`${props.fileState.fileStateIconClass}pr-2`}>
@ -10,4 +10,4 @@ const FileStateError = (props: {
</span></>
}
export default FileStateError
export default FileStateCustomIcon

@ -2,10 +2,10 @@
import React from 'react'
import { fileState } from '../../types'
const FileStateWarning = (props: {
const FileStateErrorIcon = (props: {
fileState: fileState
}) => {
return <><span className={`${props.fileState.fileStateIconClass} text-warning pr-2`}>&#11044;</span></>
return <><span className={`${props.fileState.fileStateIconClass} text-danger pr-2`}>{props.fileState.comment}</span></>
}
export default FileStateWarning
export default FileStateErrorIcon

@ -2,10 +2,10 @@
import React from 'react'
import { fileState } from '../../types'
const FileStateError = (props: {
const FileStateWarningIcon = (props: {
fileState: fileState
}) => {
return <><span className={`${props.fileState.fileStateIconClass} text-danger pr-2`}>&#11044;</span></>
return <><span className={`${props.fileState.fileStateIconClass} text-warning pr-2`}>{props.fileState.comment}</span></>
}
export default FileStateError
export default FileStateWarningIcon

@ -0,0 +1,37 @@
export enum fileStateType {
Error = 'ERROR',
Warning = 'WARNING',
Success = 'SUCCESS',
Loading = 'LOADING',
Unsaved = 'UNSAVED',
Untracked = 'UNTRACKED',
Modified = 'MODIFIED',
Staged = 'STAGED',
Committed = 'COMMITTED',
Deleted = 'DELETED',
Added = 'ADDED',
New = 'NEW',
Compiled = 'COMPILED',
Custom = 'CUSTOM',
}
export type fileState = {
path: string,
isDirectory: boolean,
fileStateType: fileStateType,
fileStateLabelClass: string,
fileStateIconClass: string,
fileStateIcon: string | HTMLDivElement | JSX.Element,
bubble: boolean,
comment: string,
owner: string,
workspace?: string
}
export interface FileType {
path: string,
name: string,
isDirectory: boolean,
type: 'folder' | 'file' | 'gist',
child?: File[]
}

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./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"]
}

@ -1,25 +1,61 @@
import { fileState } from '@remix-ui/workspace'
import { Plugin } from '@remixproject/engine'
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
import './remix-ui-tabs.css'
/* eslint-disable-next-line */
export interface TabsUIProps {
tabs: Array<any>
onSelect: (index: number) => void
onClose: (index: number) => void
onZoomOut: () => void
onZoomIn: () => void
onReady: (api: any) => void
themeQuality: string
tabs: Array<any>
plugin: Plugin,
onSelect: (index: number) => void
onClose: (index: number) => void
onZoomOut: () => void
onZoomIn: () => void
onReady: (api: any) => void
themeQuality: string
}
export interface TabsUIApi {
activateTab: (namee: string) => void
active: () => string
activateTab: (namee: string) => void
active: () => string
}
interface ITabsState {
selectedIndex: number,
fileStates: fileState[],
}
interface ITabsAction {
type: string,
payload: any,
}
const initialTabsState: ITabsState = {
selectedIndex: -1,
fileStates: [],
}
const tabsReducer = (state: ITabsState, action: ITabsAction) => {
switch (action.type) {
case 'SELECT_INDEX':
return {
...state,
selectedIndex: action.payload,
}
case 'SET_FILE_STATES':
return {
...state,
fileStates: action.payload,
}
default:
return state
}
}
export const TabsUI = (props: TabsUIProps) => {
const [selectedIndex, setSelectedIndex] = useState(-1)
const [tabsState, dispatch] = useReducer(tabsReducer, initialTabsState);
const currentIndexRef = useRef(-1)
const tabsRef = useRef({})
const tabsElement = useRef(null)
@ -28,20 +64,26 @@ export const TabsUI = (props: TabsUIProps) => {
tabs.current = props.tabs // we do this to pass the tabs list to the onReady callbacks
useEffect(() => {
if (props.tabs[selectedIndex]) {
tabsRef.current[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' })
console.log('TabsUI useEffect')
if (props.tabs[tabsState.selectedIndex]) {
tabsRef.current[tabsState.selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' })
}
}, [selectedIndex])
}, [tabsState.selectedIndex])
const getFileState = (tab: any) => {
console.log('TAB', tab, tabsState.fileStates)
}
const renderTab = (tab, index) => {
console.log('rendertab')
const classNameImg = 'my-1 mr-1 text-dark ' + tab.iconClass
const classNameTab = 'nav-item nav-link d-flex justify-content-center align-items-center px-2 py-1 tab' + (index === currentIndexRef.current ? ' active' : '')
const invert = props.themeQuality === 'dark' ? 'invert(1)' : 'invert(0)'
return (
<div ref={el => { tabsRef.current[index] = el }} className={classNameTab} data-id={index === currentIndexRef.current ? 'tab-active' : ''} title={tab.tooltip}>
{tab.icon ? (<img className="my-1 mr-1 iconImage" style={{filter: invert}} src={tab.icon} />) : (<i className={classNameImg}></i>)}
<span className="title-tabs">{tab.title}</span>
{tab.icon ? (<img className="my-1 mr-1 iconImage" style={{ filter: invert }} src={tab.icon} />) : (<i className={classNameImg}></i>)}
<span className={`title-tabs ${getFileState(tab)}`}>{tab.title}</span>
<span className="close-tabs" onClick={(event) => { props.onClose(index); event.stopPropagation() }}>
<i className="text-dark fas fa-times"></i>
</span>
@ -56,7 +98,11 @@ export const TabsUI = (props: TabsUIProps) => {
const activateTab = (name: string) => {
const index = tabs.current.findIndex((tab) => tab.name === name)
currentIndexRef.current = index
setSelectedIndex(index)
dispatch({ type: 'SELECT_INDEX', payload: index })
}
const setFileStates = (fileStates: fileState[]) => {
dispatch({ type: 'SET_FILE_STATES', payload: fileStates })
}
const transformScroll = (event) => {
@ -71,21 +117,23 @@ export const TabsUI = (props: TabsUIProps) => {
useEffect(() => {
props.onReady({
activateTab,
active
active,
setFileStates
})
return () => { tabsElement.current.removeEventListener('wheel', transformScroll) }
}, [])
return (
<div className="remix-ui-tabs d-flex justify-content-between border-0 header nav-tabs" data-id="tabs-component">
<div className="d-flex flex-row" style={ { maxWidth: 'fit-content', width: '97%' } }>
<div className="d-flex flex-row" style={{ maxWidth: 'fit-content', width: '97%' }}>
<div className="d-flex flex-row justify-content-center align-items-center m-1 mt-2">
<span data-id="tabProxyZoomOut" className="btn btn-sm px-2 fas fa-search-minus text-dark" title="Zoom out" onClick={() => props.onZoomOut()}></span>
<span data-id="tabProxyZoomIn" className="btn btn-sm px-2 fas fa-search-plus text-dark" title="Zoom in" onClick={() => props.onZoomIn()}></span>
</div>
<Tabs
className="tab-scroll"
selectedIndex={selectedIndex}
selectedIndex={tabsState.selectedIndex}
domRef={(domEl) => {
if (tabsElement.current) return
tabsElement.current = domEl
@ -94,7 +142,7 @@ export const TabsUI = (props: TabsUIProps) => {
onSelect={(index) => {
props.onSelect(index)
currentIndexRef.current = index
setSelectedIndex(index)
dispatch({ type: 'SELECT_INDEX', payload: index })
}}
>
<TabList className="d-flex flex-row align-items-center">

@ -1,3 +1,3 @@
export * from './lib/providers/FileSystemProvider'
export * from './lib/contexts'
export { fileState, fileStateType } from './lib/types/index'
export { FileType } from './lib/types/index'

@ -38,7 +38,7 @@ export const listenOnPluginEvents = (filePanelPlugin) => {
uploadFile(target, dir, cb)
})
plugin.on('filePanel', 'setFileState', async (items: fileState[]) => {
plugin.on('fileStates', 'fileStateChanged', async (items: fileState[]) => {
setFileState(items)
})

@ -1,6 +1,7 @@
// eslint-disable-next-line no-use-before-define
import { fileState } from '@remix-ui/file-states'
import React, { useEffect, useRef, useState } from 'react'
import { fileState, FileType } from '../types'
import { FileType } from '../types'
export interface FileLabelProps {
file: FileType,
@ -27,11 +28,12 @@ export const FileLabel = (props: FileLabelProps) => {
}, [file.path, focusEdit])
useEffect(() => {
console.log('fileState', fileState, file.name)
const state = props.fileState.find((state: fileState) => {
console.log('FOUND STATE', state)
if(state.path === props.file.path) return true
if(state.bubble && props.file.isDirectory && state.path.startsWith(props.file.path)) return true
})
console.log(props)
if (state && state.fileStateLabelClass) {
setFileStateClasses(state.fileStateLabelClass)
}

@ -1,12 +1,13 @@
// eslint-disable-next-line no-use-before-define
import React, { SyntheticEvent, useEffect, useState } from 'react'
import { fileState, FileType } from '../types'
import { FileType } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import { getPathIcon } from '@remix-ui/helper'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileLabel } from './file-label'
import FileState from './file-state'
import { fileState, FileStateIcons } from '@remix-ui/file-states'
export interface RenderFileProps {
file: FileType,
@ -118,7 +119,7 @@ export const FileRender = (props: RenderFileProps) => {
<>
<div className="d-flex flex-row">
<FileLabel file={file} fileState={props.fileState} focusEdit={props.focusEdit} editModeOff={props.editModeOff} />
<FileState file={file} fileState={props.fileState}/>
<FileStateIcons file={file} fileState={props.fileState}/>
</div>
</>
}

@ -1,56 +0,0 @@
// eslint-disable-next-line no-use-before-define
import React, { useEffect, useState } from 'react'
import { FileType, fileState, fileStateType } from '../types'
import FileStateCustom from './filestates/file-state-custom'
import FileStateError from './filestates/file-state-error'
import FileStateWarning from './filestates/file-state-warning'
// import FileStateModified from './filestates/file-state-modified'
// import FileStateUntracked from './filestates/file-state-untracked'
export type fileStateProps = {
file: FileType,
fileState: fileState[]
}
export const FileState = (props: fileStateProps) => {
const [state, setState] = useState<fileState>(undefined)
useEffect(() => {
console.log(props.file)
console.log(props.fileState)
setState(props.fileState.find((st) => st.path === props.file.path))
}, [props.fileState])
const getTags = function () {
if (state) {
const types = state.fileStateType
const elements: any[] = []
for (const type of types) {
switch (type) {
case fileStateType.Modified:
//elements.push(<FileStateModified key={type}/>)
break
case fileStateType.Untracked:
//elements.push(<FileStateUntracked key={type}/>)
break
case fileStateType.Error:
elements.push(<FileStateError fileState={state} key={type} />)
break
case fileStateType.Warning:
elements.push(<FileStateWarning fileState={state} key={type} />)
break
case fileStateType.Custom:
elements.push(<FileStateCustom fileState={state} key={type} />)
break
}
}
return elements
}
}
return <>
{getTags()}
</>
}
export default FileState

@ -2,8 +2,8 @@ import { extractNameFromKey } from '@remix-ui/helper'
import { action, fileState, FileType } from '../types'
import * as _ from 'lodash'
interface Action {
type: string
payload: any
type: string
payload: any
}
export interface BrowserState {
browser: {
@ -93,8 +93,8 @@ export const browserInitialState: BrowserState = {
notification: {
title: '',
message: '',
actionOk: () => {},
actionCancel: () => {},
actionOk: () => { },
actionCancel: () => { },
labelOk: '',
labelCancel: ''
},
@ -604,29 +604,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
case 'SET_FILE_STATE_SUCCESS': {
const payload = action.payload as fileState[]
console.log('SET_FILE_STATE_SUCCESS', payload)
const a = state.browser.fileState
const b = payload
const merge = _.merge({}, _.keyBy(a, 'path'), _.keyBy(b, 'path'))
const vals = _.values(merge)
console.log(a)
console.log(vals)
vals.map(function (x) {
const c = a.find(function (el) {
return el.path === x.path
})
if (c && c.fileStateType) {
x.fileStateType = _.uniq([...c.fileStateType, ...x.fileStateType])
}
return x
})
console.log(vals)
return {
...state,
browser: {
...state.browser,
fileState: vals
fileState: action.payload
}
}
}

@ -1,5 +1,6 @@
import React from 'react'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
import { fileState } from '@remix-ui/file-states';
export type action = { name: string, type?: Array<'folder' | 'gist' | 'file'>, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string, sticky?: boolean }
export interface JSONStandardInput {
@ -66,35 +67,6 @@ export interface FileType {
child?: File[]
}
export enum fileStateType {
Error = 'ERROR',
Warning = 'WARNING',
Success = 'SUCCESS',
Loading = 'LOADING',
Unsaved = 'UNSAVED',
Untracked = 'UNTRACKED',
Modified = 'MODIFIED',
Staged = 'STAGED',
Committed = 'COMMITTED',
Deleted = 'DELETED',
Added = 'ADDED',
New = 'NEW',
Compiled = 'COMPILED',
Custom = 'CUSTOM',
}
export type fileState = {
path: string,
isDirectory: boolean,
fileStateType: fileStateType[],
fileStateLabelClass: string,
fileStateIconClass: string,
fileStateIcon: string | HTMLDivElement | JSX.Element,
bubble: boolean,
comment: string,
owner: string,
}
/* eslint-disable-next-line */
export interface FileExplorerProps {
name: string,

@ -169,6 +169,9 @@
},
"remix-ui-permission-handler": {
"tags": []
},
"remix-ui-file-states": {
"tags": []
}
},
"targetDependencies": {

@ -45,7 +45,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,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search",
"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,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search,remix-ui-file-states",
"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,remix-ws-templates,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": "yarn run build:libs && lerna publish --skip-git && yarn run bumpVersion:libs",

@ -52,6 +52,7 @@
"@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"],
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],
"@remix-ui/file-states": ["libs/remix-ui/file-states/src/index.ts"],
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"],
"@remix-ui/static-analyser": [
"libs/remix-ui/static-analyser/src/index.ts"

@ -1125,6 +1125,21 @@
}
}
},
"remix-ui-file-states": {
"root": "libs/remix-ui/file-states",
"sourceRoot": "libs/remix-ui/file-states/src",
"projectType": "library",
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/file-states/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "!libs/remix-ui/file-states/**/*"]
}
}
}
},
"remix-ui-panel": {
"root": "libs/remix-ui/panel",
"sourceRoot": "libs/remix-ui/panel/src",

Loading…
Cancel
Save