Skip to content

Commit

Permalink
fix(code-editor): added button to switch editors
Browse files Browse the repository at this point in the history
  • Loading branch information
allardy committed Mar 5, 2020
1 parent 937404e commit 7adad33
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 31 deletions.
16 changes: 11 additions & 5 deletions modules/code-editor/src/views/full/Editor.tsx
Expand Up @@ -137,17 +137,22 @@ class Editor extends React.Component<Props> {
}

render() {
const hasRawPermissions = this.props.permissions?.['root.raw']?.read
const { currentFile, discardChanges, isAdvanced, setAdvanced, isOpenedFile } = this.props.editor

return (
<React.Fragment>
{!this.props.editor.isOpenedFile && <SplashScreen rawEditor={this.props.store.useRawEditor} />}
{!isOpenedFile && (
<SplashScreen hasRawPermissions={hasRawPermissions} isAdvanced={isAdvanced} setAdvanced={setAdvanced} />
)}
<div className={style.editorContainer}>
<div className={style.tabsContainer}>
<div className={style.tab}>
<span>{this.props.editor.currentFile && this.props.editor.currentFile.name}</span>
<span>{currentFile?.name}</span>

<div>
<Tooltip content="Discard" position={Position.RIGHT}>
<Icon icon="delete" iconSize={10} className={style.btn} onClick={this.props.editor.discardChanges} />
<Icon icon="delete" iconSize={10} className={style.btn} onClick={discardChanges} />
</Tooltip>
</div>
</div>
Expand All @@ -164,10 +169,11 @@ export default inject(({ store }: { store: RootStore }) => ({
createNewAction: store.createNewAction,
typings: store.typings,
fetchTypings: store.fetchTypings,
editor: store.editor
editor: store.editor,
permissions: store.permissions
}))(observer(Editor))

type Props = { store?: RootStore; editor?: EditorStore } & Pick<
StoreDef,
'typings' | 'fetchTypings' | 'createNewAction'
'typings' | 'fetchTypings' | 'createNewAction' | 'permissions'
>
2 changes: 1 addition & 1 deletion modules/code-editor/src/views/full/FileNavigator.tsx
Expand Up @@ -202,7 +202,7 @@ class FileNavigator extends React.Component<Props, State> {
}

const isDisabled = file.name.startsWith('.')
const canMove = this.props.store.useRawEditor && this.props.moveFile
const canMove = this.props.store.editor.isAdvanced && this.props.moveFile

ContextMenu.show(
<Menu>
Expand Down
5 changes: 3 additions & 2 deletions modules/code-editor/src/views/full/SidePanel.tsx
Expand Up @@ -278,14 +278,15 @@ class PanelContent extends React.Component<Props> {
}

render() {
const { isOpenedFile, isDirty, isAdvanced } = this.props.editor
return (
<SidePanel>
{this.props.editor.isOpenedFile && this.props.editor.isDirty ? (
{isOpenedFile && isDirty ? (
<FileStatus />
) : (
<React.Fragment>
<SearchBar icon="filter" placeholder="Filter files" onChange={this.props.setFilenameFilter} />
{this.props.store.useRawEditor ? (
{isAdvanced ? (
this.renderSectionRaw()
) : (
<React.Fragment>
Expand Down
22 changes: 18 additions & 4 deletions modules/code-editor/src/views/full/components/SplashScreen.tsx
@@ -1,17 +1,31 @@
import { Button } from '@blueprintjs/core'
import { KeyboardShortcut, SplashScreen } from 'botpress/ui'
import React from 'react'
import { MdCode } from 'react-icons/md'

import style from '../style.scss'

const description = `Code editor allows you to create and edit actions without leaving botpress studio. It features typings and
intelligent code completion. To edit global files and content generated by modules, you need to enable that by editing the code-editor.json configuration file.`

const rawEditorDesc = `WARNING: The raw file editor has no safeguards and you can easily mess important files. Handle with care !
You can edit any file contained in the data folder, create new files and move existing files around.`
const rawEditorDesc = (
<span>
<span className={style.warning}>WARNING</span>
<br /> The raw file editor has no safeguards and you can easily mess important files. Handle with care ! You can
edit any file contained in the data folder, create new files and move existing files around.
</span>
)

export default ({ rawEditor }) => (
<SplashScreen icon={<MdCode />} title={'Code Editor'} description={rawEditor ? rawEditorDesc : description}>
export default ({ hasRawPermissions, isAdvanced, setAdvanced }) => (
<SplashScreen icon={<MdCode />} title={'Code Editor'} description={isAdvanced ? rawEditorDesc : description}>
<KeyboardShortcut label="Save file" keys={['ACTION', 's']} />
<KeyboardShortcut label="New file" keys={['ACTION', 'alt', 'n']} />
<KeyboardShortcut label="Command Palette" keys={['ACTION', 'shift', 'p']} />
<br />
{hasRawPermissions && (
<div>
<Button text={isAdvanced ? 'Basic Editor' : 'Advanced Editor'} onClick={() => setAdvanced(!isAdvanced)} />
</div>
)}
</SplashScreen>
)
4 changes: 2 additions & 2 deletions modules/code-editor/src/views/full/index.tsx
Expand Up @@ -23,8 +23,8 @@ export default class CodeEditor extends React.Component<{ bp: any }> {
}

render() {
const keyMap = { newFile: 'ctrl+alt+n', rawFileMode: 'r a w t o o l' }
const keyHandlers = { newFile: this.store.createNewAction, rawFileMode: this.store.enableRawEditor }
const keyMap = { newFile: 'ctrl+alt+n' }
const keyHandlers = { newFile: this.store.createNewAction }

return (
<Provider store={this.store}>
Expand Down
13 changes: 13 additions & 0 deletions modules/code-editor/src/views/full/store/editor.ts
Expand Up @@ -28,6 +28,9 @@ class EditorStore {
@observable
private _isFileLoaded: boolean

@observable
public isAdvanced: boolean = false

@observable
private _originalHash: string

Expand Down Expand Up @@ -81,6 +84,16 @@ class EditorStore {
this.fileProblems = problems
}

@action.bound
async setAdvanced(isAdvanced) {
if (this.rootStore.permissions?.['root.raw']?.read) {
this.isAdvanced = isAdvanced
await this.rootStore.fetchFiles()
} else {
console.error(`Only Super Admins can use the raw file editor`)
}
}

@action.bound
async saveChanges() {
if (!this.fileContent || this.currentFile.readOnly || this.currentFile.isExample) {
Expand Down
19 changes: 3 additions & 16 deletions modules/code-editor/src/views/full/store/index.ts
Expand Up @@ -22,7 +22,9 @@ class RootStore {
public api: CodeEditorApi
public editor: EditorStore

@observable
public permissions: FilePermissions

public typings: { [fileName: string]: string } = {}

@observable
Expand All @@ -34,9 +36,6 @@ class RootStore {
@observable
public fileFilter: string

@observable
public useRawEditor: boolean = false

constructor({ bp }) {
this.api = new CodeEditorApi(bp.axios)
this.editor = new EditorStore(this)
Expand All @@ -46,18 +45,6 @@ class RootStore {
}
}

@action.bound
async enableRawEditor(e) {
e.preventDefault()

if (this.permissions['root.raw'].read) {
this.useRawEditor = !this.useRawEditor
await this.fetchFiles()
} else {
console.error(`Only Super Admins can use the raw file editor`)
}
}

@action.bound
async initialize(): Promise<void> {
try {
Expand All @@ -79,7 +66,7 @@ class RootStore {

@action.bound
async fetchFiles() {
const files = await this.api.fetchFiles(this.useRawEditor)
const files = await this.api.fetchFiles(this.editor.isAdvanced)
runInAction('-> setFiles', () => {
this.files = files
})
Expand Down
5 changes: 5 additions & 0 deletions modules/code-editor/src/views/full/style.scss
Expand Up @@ -50,3 +50,8 @@
.padding {
padding: 2px 10px;
}

.warning {
font-weight: bold;
color: red;
}
1 change: 1 addition & 0 deletions modules/code-editor/src/views/full/style.scss.d.ts
Expand Up @@ -9,6 +9,7 @@ interface CssExports {
'status': string;
'tab': string;
'tabsContainer': string;
'warning': string;
}
declare var cssExports: CssExports;
export = cssExports;
Expand Up @@ -63,7 +63,7 @@ export interface ContainerProps {

export interface SplashScreenProps {
title: string
description?: string
description?: string | JSX.Element
/** The name of the icon to use. Can also be a JSX element */
icon?: IconName | MaybeElement
readonly children?: React.ReactNode
Expand Down

0 comments on commit 7adad33

Please sign in to comment.