parent
360c8a5e62
commit
5ad402fc41
@ -0,0 +1,60 @@ |
||||
'use strict' |
||||
|
||||
import { default as deepequal } from 'deep-equal' // eslint-disable-line
|
||||
|
||||
import { Plugin } from '@remixproject/engine' |
||||
import { fileDecoration } from '@remix-ui/file-decorators' |
||||
|
||||
const profile = { |
||||
name: 'fileDecorator', |
||||
desciption: 'Keeps decorators of the files', |
||||
methods: ['setFileDecorators', 'clearFileDecorators'], |
||||
events: ['fileDecoratorsChanged'], |
||||
version: '0.0.1' |
||||
} |
||||
|
||||
export class FileDecorator extends Plugin { |
||||
private _fileStates: fileDecoration[] = [] |
||||
constructor() { |
||||
super(profile) |
||||
} |
||||
/** |
||||
*
|
||||
* @param fileStates Array of file states |
||||
*/ |
||||
async setFileDecorators(fileStates: fileDecoration[] | fileDecoration) { |
||||
const workspace = await this.call('filePanel', 'getCurrentWorkspace') |
||||
function sortByPath( a: fileDecoration, b: fileDecoration ) { |
||||
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: fileDecoration) => { |
||||
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 |
||||
this.emit('fileDecoratorsChanged', this._fileStates) |
||||
} |
||||
} |
||||
|
||||
async clearFileDecorators() { |
||||
this._fileStates = [] |
||||
this.emit('fileDecoratorsChanged', []) |
||||
} |
||||
} |
@ -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 { fileDecoration, fileDecorationType, FileType } from './lib/types/index' |
||||
export { FileDecorationIcons } from './lib/components/file-decoration-icon' |
||||
|
@ -0,0 +1,51 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React, { useEffect, useState } from 'react' |
||||
|
||||
import { fileDecoration, fileDecorationType, FileType } from '../types' |
||||
import FileDecorationCustomIcon from './filedecorationicons/file-decoration-custom-icon' |
||||
import FileDecorationErrorIcon from './filedecorationicons/file-decoration-error-icon' |
||||
import FileDecorationTooltip from './filedecorationicons/file-decoration-tooltip' |
||||
import FileDecorationWarningIcon from './filedecorationicons/file-decoration-warning-icon' |
||||
|
||||
export type fileDecorationProps = { |
||||
file: FileType, |
||||
fileDecorations: fileDecoration[] |
||||
} |
||||
|
||||
export const FileDecorationIcons = (props: fileDecorationProps) => { |
||||
const [states, setStates] = useState<fileDecoration[]>([]) |
||||
useEffect(() => { |
||||
//console.log(props.file)
|
||||
//console.log(props.fileState)
|
||||
setStates(props.fileDecorations.filter((fileDecoration) => fileDecoration.path === props.file.path || `${fileDecoration.workspace.name}/${fileDecoration.path}` === props.file.path)) |
||||
}, [props.fileDecorations]) |
||||
|
||||
|
||||
const getTags = function () { |
||||
if (states && states.length) { |
||||
const elements: JSX.Element[] = [] |
||||
|
||||
for (const [index, state] of states.entries()) { |
||||
switch (state.fileStateType) { |
||||
case fileDecorationType.Error: |
||||
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationErrorIcon fileDecoration={state} key={index}/>}/>) |
||||
break |
||||
case fileDecorationType.Warning: |
||||
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationWarningIcon fileDecoration={state} key={index}/>}/>) |
||||
break |
||||
case fileDecorationType.Custom: |
||||
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationCustomIcon fileDecoration={state} key={index}/>}/>) |
||||
break |
||||
} |
||||
} |
||||
|
||||
return elements |
||||
} |
||||
} |
||||
|
||||
return <> |
||||
{getTags()} |
||||
</> |
||||
} |
||||
|
||||
export default FileDecorationIcons |
@ -0,0 +1,13 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import { fileDecoration } from '../../types' |
||||
|
||||
const FileDecorationCustomIcon = (props: { |
||||
fileDecoration: fileDecoration |
||||
}) => { |
||||
return <><span className={`${props.fileDecoration.fileStateIconClass}pr-2`}> |
||||
{props.fileDecoration.fileStateIcon} |
||||
</span></> |
||||
} |
||||
|
||||
export default FileDecorationCustomIcon |
@ -0,0 +1,14 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
|
||||
import { fileDecoration } from '../../types' |
||||
|
||||
const FileDecorationErrorIcon = (props: { |
||||
fileDecoration: fileDecoration |
||||
}) => { |
||||
return <> |
||||
<span className={`${props.fileDecoration.fileStateIconClass} text-danger pr-2`}>{props.fileDecoration.text}</span> |
||||
</> |
||||
} |
||||
|
||||
export default FileDecorationErrorIcon |
@ -0,0 +1,33 @@ |
||||
import React from "react"; |
||||
import { OverlayTrigger, Tooltip } from "react-bootstrap"; |
||||
import { fileDecoration } from "../../types"; |
||||
|
||||
const FileDecorationTooltip = (props: { |
||||
fileDecoration: fileDecoration, |
||||
icon: JSX.Element |
||||
index: number |
||||
}, |
||||
) => { |
||||
const getComments = function (fileDecoration: fileDecoration) { |
||||
if (fileDecoration.commment) { |
||||
const commments = Array.isArray(fileDecoration.commment) ? fileDecoration.commment : [fileDecoration.commment] |
||||
return commments.map((comment, index) => { |
||||
return <div key={index}>{comment}<br></br></div> |
||||
}) |
||||
} |
||||
} |
||||
|
||||
return <OverlayTrigger |
||||
key={`overlaytrigger-${props.fileDecoration.path}-${props.index}`} |
||||
placement='auto' |
||||
overlay={ |
||||
<Tooltip id={`error-tooltip-${props.fileDecoration.path}`}> |
||||
<>{getComments(props.fileDecoration)}</> |
||||
</Tooltip> |
||||
} |
||||
><div>{props.icon}</div></OverlayTrigger> |
||||
|
||||
} |
||||
|
||||
|
||||
export default FileDecorationTooltip; |
@ -0,0 +1,11 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import { fileDecoration } from '../../types' |
||||
|
||||
const FileDecorationWarningIcon = (props: { |
||||
fileDecoration: fileDecoration |
||||
}) => { |
||||
return <><span className={`${props.fileDecoration.fileStateIconClass} text-warning pr-2`}>{props.fileDecoration.text}</span></> |
||||
} |
||||
|
||||
export default FileDecorationWarningIcon |
@ -0,0 +1,11 @@ |
||||
import React from "react" |
||||
import { fileDecoration } from "../types" |
||||
|
||||
export const getComments = function (fileDecoration: fileDecoration) { |
||||
if(fileDecoration.commment){ |
||||
const commments = Array.isArray(fileDecoration.commment) ? fileDecoration.commment : [fileDecoration.commment] |
||||
return commments.map((comment, index) => { |
||||
return <div key={index}>{comment}<br></br></div> |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
export enum fileDecorationType { |
||||
Error = 'ERROR', |
||||
Warning = 'WARNING', |
||||
Custom = 'CUSTOM', |
||||
None = 'NONE' |
||||
} |
||||
|
||||
export type fileDecoration = { |
||||
path: string, |
||||
isDirectory: boolean, |
||||
fileStateType: fileDecorationType, |
||||
fileStateLabelClass: string, |
||||
fileStateIconClass: string, |
||||
fileStateIcon: string | HTMLDivElement | JSX.Element, |
||||
bubble: boolean, |
||||
text?: string, |
||||
owner: string, |
||||
workspace?: any |
||||
tooltip?: string |
||||
commment?: string[] | 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,2 +1,3 @@ |
||||
export * from './lib/providers/FileSystemProvider' |
||||
export * from './lib/contexts' |
||||
export { FileType } from './lib/types/index' |
Loading…
Reference in new issue