import * as React from 'react'; import { MessageType } from '@theia/core'; import { Flex, Box } from '@rebass/grid'; import CatalogoSearchHeader from './main/catalogo-search-header'; import CatalogoConnectors from './main/catalogo-connectors'; import ConnectorRenderer from './connectors/connectors-renderer'; import CatalogoFilters from './main/catalogo-filters'; import * as RecursiveIterator from 'recursive-iterator'; import setNested from '../../common/utils/set-nested-key'; import { ContainerContext } from './catalogo-context'; import { IConnectorConfig, IStepConnectorForm, IConnectorData } from '../../common/catalogo-protocol'; import { icon as iconDefault } from '../../common/mock/mock-connectors'; import { Empty, Typography, Button } from 'antd'; const { Title } = Typography; interface CatalogoLayoutProps { } interface CatalogoLayoutState { connectors: IConnectorConfig[]; // lista de conectores steps: IStepConnectorForm[]; // lista de passos do formulário para instalação do conector selectedConnector: number; // Connector selecionado. Pode ser por seleção do usuario ou por que ele já tem dado registrado module_installed: any; loadingConnectors: boolean; //true quando estiver carregando a lista de conectores filterName: string; // Palavra chave para busca filterCategories: string[]; // Categorias para filtrar conectores editingConnectorData: IConnectorData; // Foi encontrado dados referente ao connector e entra no modo edição error: string; // error do componente contendo a mensagem } class CatalogoLayout extends React.Component { static contextType = ContainerContext; context!: React.ContextType; constructor(props: any) { super(props); this.state = { connectors: [], steps: [], selectedConnector: -1, module_installed: '', filterName: '', loadingConnectors: false, filterCategories: [], editingConnectorData: {version: null, type: null, image: null}, error: null } } async componentDidMount() { if(this.context.service) { const connectors = this.context.service.getConnectors(); this.setState({connectors}, async () => { try { const json = await this.context.resource.readContents(); const content: Object = JSON.parse(json === '' ? '{}' : json); const type: string = content['type']; if(type) { const selectedConnector = connectors.reduce((prev, curr, index) =>{ return curr.type === type ? index : prev; }, -1); if(selectedConnector > -1) { // Força seleção do connector this._handlerSelect(selectedConnector, content); } else { this.context.service.logMessage({type: MessageType.Error, text: 'Connector Type not Found!'}); } } } catch (err) { console.error(err); this.context.service.logMessage({type: MessageType.Error, text: 'Error when trying read content .connector file'}); } }); } } componentDidUpdate() { } // Handle do botão de reload dos connectores private reloadConnectors = async () => { this.setState({ loadingConnectors: true }); const connectors = await this.context.service.reloadConnectors(); this.setState({ connectors, loadingConnectors: false }); } /** * Verifica se o connector possui imagem. Caso não possua utiliza uma imagem default * para exibição no overview */ private verifyConnectorImage = (connector: IConnectorConfig) => { const hasImageConnector = connector.image && (connector.image !== null || connector.image !== ''); return hasImageConnector ? connector.image : iconDefault; } /** * Verifica se existe um usuário criador ou uma organização que fez o connector. * Caso exista monta o overview para exibir essa informação */ private verifyAuthors = (connector: IConnectorConfig) => { const hasUserCreator = connector.userCreator && (connector.userCreator !== null || connector.userCreator !== ''); const hasOrganizationCreator = connector.organizationCreator && (connector.organizationCreator !== null || connector.organizationCreator !== ''); return hasUserCreator ? connector.userCreator : hasOrganizationCreator ? connector.organizationCreator : '' } private defaultValues = (steps: IStepConnectorForm[], content: Object) => { const withValues = steps.slice(1); return withValues.map(step => { const withDefaults = Object.assign({}, step.content.metadata.data); for(let {key, path} of new RecursiveIterator(step.content.metadata.data)) { if(key === 'default') { setNested(path.join('.'), content[path[path.length - 2]], withDefaults); } } return { ...step, content: { ...step.content, metadata: { ...step.content.metadata, data: withDefaults } } } }); } private enrichSteps = (connector: IConnectorConfig, steps: IStepConnectorForm[], connectorContent: Object) => { return [ { ...steps[0], version: connector.version, image: this.verifyConnectorImage(connector), author: this.verifyAuthors(connector) }, ...(connectorContent ? this.defaultValues(steps, connectorContent) : steps.splice(1)) ]; } // Seleçaõ de um connector private _handlerSelect = (connIndex: number, content?: Object) => { const steps = this.context.service.getConnectorForm(this.state.connectors[connIndex].type); if(steps) { const enriched = this.enrichSteps(this.state.connectors[connIndex], steps, content); this.setState( { selectedConnector: connIndex, steps: enriched, editingConnectorData: {version: null, type: null, image: null, ...content} } ); } else { this.context.service.logMessage({type: MessageType.Error, text: 'Connector Form not Found'}); } } private _handlerBack = () => this.setState({selectedConnector: -1, editingConnectorData: {version: null, type: null, image: null}}); // Mudando a busca por texto private _handlerChange = (value: string) => this.setState({filterName: value}); // Ao selecionar uma categoria para filtro private _handleChangeCategories = (categories: string[]) => this.setState({filterCategories: categories}); // private _installModule = () => {} render() { const { connectors, selectedConnector, filterName, filterCategories, error, loadingConnectors, editingConnectorData } = this.state; if(error) return {error} return ( { selectedConnector === -1 ? this._handlerChange(value)}/>