Closed PedroCDLoureiro closed 2 years ago
Hi @PedroCDLoureiro
Thanks!!
editor.start()
before impor data?
Yes, before the import
Mmmmm... Load css before import?
Other issue with same problem https://github.com/jerosoler/Drawflow/issues/2
The #drawflow css is height property?
Yes, css is correctly, loaded before import and the height of drawflow too.
The coordenates of connections are null after the import:
The height is "px" or "%"?
Can you try 800px?
Try with fixesd value. To discart.
The height it's 100%, with 800px not showing too.
Try adding to css text-align: initial; and the css before draflow div.
<style>
#drawflow {
text-align:initial;
width: 100%;
height: 98vw;
border: 1px solid red;
}
</style>
<div id="drawflow"></div>
Yes, css is correctly, loaded before import and the height of drawflow too.
The coordenates of connections are null after the import:
I tried to put this css, but it did not work either. Would not the problem be that the coordinates of the connection are zero?
Show errors in console?
Try with data:
editor.import( {"drawflow":{"Home":{"data":{"3":{"id":3,"name":"reply_message","data":{"reply":"[[name]], your query for outstanding [[find.text]] is [[amount]]"},"class":"reply_message","html":"\n <div>\n <div class=\"title-box\"><svg class=\"icon\">\n <use xlink:href=\"#arroba\"></use></svg> Reply message</div>\n <div class=\"content-box\">\n <textarea class=\"resize-vertical form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Enter reply message\" placeholder=\"Enter reply message\" df-reply ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[]}},"pos_x":910,"pos_y":52},"4":{"id":4,"name":"WhatsApp","data":{},"class":"WhatsApp","html":"<div class=\"blockelem noselect block\">\n <input type=\"hidden\" name=\"blockelemtype\" class=\"blockelemtype\" value=\"5\">\n <input type=\"hidden\" name=\"blockid\" class=\"blockid\" value=\"0\">\n <div class=\"blockyleft\"><img src=\"/images/workflow/WhatsApp.png\" class=\"blockyname\"><label class=\"blockyname\">WhatsApp</label></div> \n <div class=\"blockydiv\"></div><div class=\"blockyinfo\">Triggers the start of the work flow</div></div>","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"5","output":"input_1"}]}},"pos_x":18,"pos_y":55},"5":{"id":5,"name":"find","data":{"find":"balance"},"class":"find","html":"\n <div>\n <div class=\"title-box\"><svg class=\"icon\">\n <use xlink:href=\"#magnifying-glass\"></use></svg> Find</div>\n <div class=\"content-box\">\n <input type=\"text\" class=\"form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled placeholder=\"Enter search text\" df-find>\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"4","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"6","output":"input_1"}]},"output_2":{"connections":[]}},"pos_x":295,"pos_y":60},"6":{"id":6,"name":"db_connection","data":{"connection":"","query":"select [[amount]] from pending_payment"},"class":"db_connection","html":"\n <div>\n <div class=\"title-box\"><svg class=\"icon\">\n <use xlink:href=\"#database\"></use></svg> Database query</div>\n <div class=\"content-box\">\n <div class=\"input-group\">\n <select class=\"form-control\" name=\"connections\" id=\"connections\" required data-parsley-trigger=\"change blur\" placeholder=\"Select connection\" data-parsley-errors-messages-disabled df-connection>\n </select>\n </div>\n <div class=\"input-group\">\n <textarea class=\"form-control resize-vertical\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Type query here\" df-query ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n </div>\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"5","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"3","output":"input_1"}]},"output_2":{"connections":[{"node":"7","output":"input_1"}]}},"pos_x":573,"pos_y":55},"7":{"id":7,"name":"reply_message","data":{"reply":"Sorry, I didn't find find anything"},"class":"reply_message","html":"\n <div>\n <div class=\"title-box\"><svg class=\"icon\">\n <use xlink:href=\"#arroba\"></use></svg> Reply message</div>\n <div class=\"content-box\">\n <textarea class=\"resize-vertical form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Enter reply message\" placeholder=\"Enter reply message\" df-reply ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_2"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[]}},"pos_x":911,"pos_y":216}}}}} );
Can you pass you export data?
Your data:
My data: {"drawflow":{"Home":{"data":{"6":{"id":6,"data":{},"html":"\n <div>\n <div class=\"title-box inicio\"><i class=\"fas fa-play\"></i> Início</div>\n </div>\n ","name":"inicio","class":"inicio","pos_x":-55.42857142857143,"pos_y":388,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"7","output":"input_1"}]}},"typenode":false},"7":{"id":7,"data":{"nome_menu1":"Suporte 2","text_inferior":"Mens Inferior","text_superior":"Mens Superior","quantidade_menus":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comment-alt\"></i> Menu </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem superior:</p>\n <textarea df-text_superior> </textarea><input type=\"text\" df-nome_menu1 placeholder=\"Nome do menu 1\"><p>Mensagem inferior:</p>\n <textarea df-text_inferior> </textarea>\n </div>\n </div>\n ","name":"multiple","class":"multiple","pos_x":145.57142857142858,"pos_y":207,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"8","output":"input_1"},{"node":"9","output":"input_1"},{"node":"10","output":"input_1"}]}},"typenode":false},"8":{"id":8,"data":{"text_bot":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-robot\"></i> BOT </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nomes} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_bot> </textarea>\n </div>\n </div>\n ","name":"bot","class":"bot","pos_x":517.5714285714286,"pos_y":26,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"9":{"id":9,"data":{"chat_usuario":"67","text_usuario":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Usuário </div>\n <div class=\"box\"> \n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o usuário</option><option value=\"67\">Giovanni Pucci</option><option value=\"265\">Sony</option><option value=\"279\">Sony 1</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_usuario> </textarea>\n </div>\n </div>\n ","name":"chat_usuario","class":"chat_usuario","pos_x":550.5714285714286,"pos_y":280,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"10":{"id":10,"data":{"chat_setor":"","text_setor":"Msg despedida {nome}","chat_usuario":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Setor </div>\n <div class=\"box\">\n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o setor</option><option value=\"1\">Suporte 2</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_setor> </textarea>\n </div>\n </div>\n ","name":"chat_setor","class":"chat_setor","pos_x":551.8571428571429,"pos_y":574.5714285714286,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false}}}}}
Your data is correct:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css">
<script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
</head>
<body>
<style>
#drawflow {
width: 800px;
height: 800px;
border: 1px solid red;
}
</style>
<div id="drawflow"></div>
<script>
var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();
editor.import( {"drawflow":{"Home":{"data":{"6":{"id":6,"data":{},"html":"\n <div>\n <div class=\"title-box inicio\"><i class=\"fas fa-play\"></i> Início</div>\n </div>\n ","name":"inicio","class":"inicio","pos_x":-55.42857142857143,"pos_y":388,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"7","output":"input_1"}]}},"typenode":false},"7":{"id":7,"data":{"nome_menu1":"Suporte 2","text_inferior":"Mens Inferior","text_superior":"Mens Superior","quantidade_menus":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comment-alt\"></i> Menu </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem superior:</p>\n <textarea df-text_superior> </textarea><input type=\"text\" df-nome_menu1 placeholder=\"Nome do menu 1\"><p>Mensagem inferior:</p>\n <textarea df-text_inferior> </textarea>\n </div>\n </div>\n ","name":"multiple","class":"multiple","pos_x":145.57142857142858,"pos_y":207,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"8","output":"input_1"},{"node":"9","output":"input_1"},{"node":"10","output":"input_1"}]}},"typenode":false},"8":{"id":8,"data":{"text_bot":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-robot\"></i> BOT </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nomes} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_bot> </textarea>\n </div>\n </div>\n ","name":"bot","class":"bot","pos_x":517.5714285714286,"pos_y":26,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"9":{"id":9,"data":{"chat_usuario":"67","text_usuario":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Usuário </div>\n <div class=\"box\"> \n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o usuário</option><option value=\"67\">Giovanni Pucci</option><option value=\"265\">Sony</option><option value=\"279\">Sony 1</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_usuario> </textarea>\n </div>\n </div>\n ","name":"chat_usuario","class":"chat_usuario","pos_x":550.5714285714286,"pos_y":280,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"10":{"id":10,"data":{"chat_setor":"","text_setor":"Msg despedida {nome}","chat_usuario":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Setor </div>\n <div class=\"box\">\n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o setor</option><option value=\"1\">Suporte 2</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_setor> </textarea>\n </div>\n </div>\n ","name":"chat_setor","class":"chat_setor","pos_x":551.8571428571429,"pos_y":574.5714285714286,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false}}}}} );
</script>
</body>
</html>
And works.
Are you using a CSS library?
Can you remove the css that is not necessary?
Can you pass an example of your code to find the error?
I used your theme generator with some alterations.I believe it might be some function that is not calculating the coordinates
<template>
<div id="app">
<div class="wrapper">
<v-card>
<v-card-title>
<span v-if="dados.id" class="headline">
<i class="fas fa-robot"></i>
Editar {{dados.name}}
</span>
<span v-else class="headline">
<i class="fas fa-robot"></i>
Novo Bot
</span>
</v-card-title>
<v-card-text>
<v-stepper v-model="step">
<v-stepper-header>
<v-stepper-step
:editable="dados.id ? true : false"
:complete="step > 1"
step="1"
>
Dados Bot
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step
:editable="dados.id ? true : false"
step="2"
>
Flow
</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<v-form ref="form_bot">
<div class="row">
<div class="col-12">
<div class="row">
<div class="col-6">
<v-text-field
:rules="[v => !!v || 'Campo Nome obrigatório']"
v-model="dados.name"
label="Nome *"
placeholder="Nome *"
hide-details
outlined
/>
</div>
<div class="col-6">
<v-select
:rules="[v => v !== '' || 'Campo Homologação obrigatório']"
:items="boolean"
item-text="text"
item-value="value"
v-model="dados.settings.homologation"
label="Homologação? *"
placeholder="Homologação? *"
background-color="white"
hide-details
outlined
/>
</div>
<div class="col-6">
<v-select
:rules="[v => v !== '' || 'Campo Perguntar Nome obrigatório']"
:items="boolean"
item-text="text"
item-value="value"
v-model="dados.settings.ask_name"
label="Perguntar Nome? *"
placeholder="Perguntar Nome? *"
background-color="white"
hide-details
outlined
@change="confirmName()"
/>
</div>
<div class="col-6">
<v-select
:rules="[v => v !== '' || 'Campo Confirmar Nome obrigatório']"
:items="boolean"
item-text="text"
item-value="value"
:disabled="dados.settings.ask_name == false"
v-model="dados.settings.confirm_name"
label="Confirmar Nome? *"
placeholder="Confirmar Nome? *"
background-color="white"
hide-details
outlined
/>
</div>
<div class="col-6" v-if="dados.settings.homologation">
<v-textarea
:rules="[v => !!v || 'Campo Números de homologação obrigatório']"
v-model="dados.settings.numbers_homologation"
label="Números de homologação *"
placeholder="Números de homologação *"
background-color="white"
readonly
hide-details
outlined
@click="openModalNumbers"
></v-textarea>
</div>
<div class="col-6" v-if="dados.settings.ask_name">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem Perguntar Nome obrigatório']"
v-model="dados.settings.message_ask_name"
label="Mensagem Perguntar Nome *"
placeholder="Mensagem Perguntar Nome *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6" v-if="dados.settings.confirm_name && dados.settings.ask_name">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem Superior de Confirmar Nome obrigatório']"
v-if="dados.settings.confirm_name && dados.settings.ask_name"
v-model="dados.settings.message_upper_confirm_name"
label="Mensagem Superior de Confirmar Nome *"
placeholder="Mensagem Superior de Confirmar Nome *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem Superior do Menu obrigatório']"
v-model="dados.settings.message_upper_menu"
label="Mensagem Superior do Menu - Nome Informado *"
placeholder="Mensagem Superior do Menu *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem Inferior do Menu obrigatório']"
v-model="dados.settings.message_down_menu"
label="Mensagem Inferior do Menu - Nome Informado *"
placeholder="Mensagem Inferior do Menu *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6" v-if="dados.settings.confirm_name && dados.settings.ask_name">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem Inferior de Confirmar Nome obrigatório']"
v-model="dados.settings.message_down_confirm_name"
label="Mensagem Inferior de Confirmar Nome *"
placeholder="Mensagem Inferior de Confirmar Nome *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Texto Padrão de Despedida obrigatório']"
v-model="dados.settings.goodbye_text_template"
label="Texto Padrão de Despedida *"
placeholder="Texto Padrão de Despedida *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem de Horário de Atendimento Indisponível obrigatório']"
v-model="dados.settings.message_offtime"
label="Mensagem de Horário de Atendimento Indisponível *"
placeholder="Mensagem de Horário de Atendimento Indisponível *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem de Transfêrencia de Usuário obrigatório']"
v-model="dados.settings.message_transfer"
label="Mensagem de Transfêrencia de Usuário * - Nome Informado"
placeholder="Mensagem de Transfêrencia de Usuário * - Nome Informado"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
<div class="col-6">
<v-textarea
:rules="[v => !!v || 'Campo Mensagem de Transfêrencia de departamento obrigatório']"
v-model="dados.settings.message_transfer_all_user_unavailable"
label="Mensagem de Transfêrencia de Departamento *"
placeholder="Mensagem de Transfêrencia de Departamento *"
background-color="white"
hide-details
outlined
></v-textarea>
</div>
</div>
</div>
<div class="col-12 div-btns">
<div class="row row-btns">
<div class="col-6 btn-cancelar">
<v-btn @click="closeStepper">
Cancelar
</v-btn>
</div>
<div class="col-6">
<div class="row justify-end">
<div class="col-12 col-md-3 btn-avancar">
<v-btn
color="primary"
@click="nextPage"
>
Próximo
</v-btn>
</div>
</div>
</div>
</div>
</div>
</div>
</v-form>
</v-stepper-content>
<v-stepper-content step="2">
<div class="col">
<div class="div-logo">
<Logo />
</div>
<div class="divisao-flow">
<span>Entradas</span>
</div>
<div class="drag-drawflow box-start" draggable="true" @dragstart="drag($event)" data-node="inicio">
<i class="fas fa-play"></i><span> Início </span>
</div>
<div class="divisao-flow">
<span>Saídas</span>
</div>
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="multiple">
<i class="fas fa-comment-alt"></i><span> Menu </span>
</div>
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="agendamento">
<i class="fas fa-clipboard-list"></i><span> API Agendamento </span>
</div>
<!-- <div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="delivery">
<i class="fas fa-motorcycle"></i><span> Delivery </span>
</div>
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="lgpd">
<i class="fas fa-gavel"></i><span> LGPD </span>
</div> -->
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="bot">
<i class="fas fa-robot"></i><span> BOT </span>
</div>
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="chat_usuario">
<i class="fas fa-comments"></i><span> Chat Usuário </span>
</div>
<div class="drag-drawflow" draggable="true" @dragstart="drag($event)" data-node="chat_setor">
<i class="fas fa-comments"></i><span> Chat Setor </span>
</div>
</div>
<div class="col-right">
<div id="drawflow" @drop="drop($event)" @dragover="allowDrop($event)">
<div class="btn-option" @click="editor.clearModuleSelected()">
Limpar
</div>
<div class="bar-zoom">
<button @click="zoomOut()">
<i class="fas fa-search-minus"></i>
</button>
<button @click="zoomReset()">
<i class="fas fa-search"></i>
</button>
<button @click="zoomIn()">
<i class="fas fa-search-plus"></i>
</button>
</div>
</div>
</div>
<v-card>
<div class="col-12 div-btns">
<div class="row row-btns">
<div class="col-6 btn-cancelar">
<v-btn @click="closeStepper" style="margin-right: 10px">
Cancelar
</v-btn>
<v-btn @click="step = 1">
Voltar
</v-btn>
</div>
<div class="col-6">
<div class="row justify-end">
<div class="col-12 col-md-3 btn-avancar">
<v-btn
color="primary"
@click="nextPage"
>
Salvar
</v-btn>
</div>
</div>
</div>
</div>
</div>
</v-card>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-card-text>
</v-card>
<v-dialog v-model="dialog_numbers_homologation" persistent max-width="800px">
<v-card>
<v-card-title>
<span class="headline"> <i class="fas fa-phone"></i> Números de Homologação </span>
</v-card-title>
<v-card-text>
<v-container>
<v-form ref="form_telefones">
<div class="row">
<div class="col-12">
<div class="div-menu" v-for="(numbers, i) in dados.settings.numbers_homologation" :key="i">
<div class="div-inputs">
<div class="row">
<div class="col-md-12 col-12">
<v-text-field
:rules="[v => !!v || 'Campo Número obrigatório', v => v.length > 19 || 'Campo Número Incompleto']"
v-model="dados.settings.numbers_homologation[i]"
label="Número"
placeholder="Número"
v-mask="dados.settings.numbers_homologation[i] < 19 ? '+## (##) ####-####' : '+## (##) # ####-####'"
hide-details
outlined
/>
</div>
</div>
</div>
<v-btn type="button" @click="removeItemNumber(i)" color="primary" raised class="remover-menu">
<i class="fas fa-minus"></i>
</v-btn>
</div>
</div>
<div class="col-12">
<div class="row justify-end">
<v-btn class="primary" style="margin-right: 12px" raised @click="addItemNumber">
<i style="margin-right: 10px" class="fas fa-plus"></i> Adicionar Número
</v-btn>
</div>
</div>
</div>
</v-form>
</v-container>
</v-card-text>
<v-card-actions>
<v-btn class="primary-button" small @click="dialog_numbers_homologation = false">
Fechar
</v-btn>
<v-spacer></v-spacer>
<v-btn class="primary-button" small @click="numbersHomologationSave()">
Salvar
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</div>
</template>
<script>
import store from '@/store'
import Drawflow from 'drawflow'
import Logo from "@/components/Logo.vue"
import Swal from 'sweetalert2'
export default {
name: 'App',
components: {
Logo,
},
data() {
return {
editor: null,
mobile_item_selec: '',
mobile_last_move: null,
transform: '',
data_nodes:[],
setores: [],
usuarios: [],
bot_id: this.$route.params.id,
boolean: [
{
text: 'Sim',
value: true
},
{
text: 'Não',
value: false
}
],
step: 1,
empresas: [],
// variável para mostrar a modal para editar/criar um menu
dialog: false,
dialog_numbers_homologation: false,
// variável para a mensagem de resposta
resposta: {},
// variável para o loading
loading: false,
// variável para criar/editar menu
dados: {
id: '',
name: '',
settings: {
goodbye_text_template: '',
ask_name: '',
confirm_name: '',
homologation: '',
message_ask_name: '',
message_down_confirm_name: '',
message_upper_confirm_name: '',
numbers_homologation: [],
message_down_menu: '',
message_upper_menu: '',
message_down_option_invalidates_menu: '',
message_upper_option_invalidates_menu: '',
message_down_company: '',
message_upper_company: '',
message_down_option_invalidates_company: '',
message_upper_option_invalidates_company: '',
message_down_date: '',
message_upper_date: '',
message_down_option_invalidates_date: '',
message_upper_option_invalidates_date: '',
message_down_time: '',
message_upper_time: '',
message_down_option_invalidates_time: '',
message_upper_option_invalidates_time: '',
message_transfer: '',
message_transfer_all_user_unavailable: '',
message_offtime: '',
},
menus: [{
department_id: '',
bot_menu_type_id: '',
text: '',
goodbye_text: '',
key: '',
status: '',
settings: {}
}],
flow: ''
},
bot_menu_types: [],
departments: [],
bots:[]
}
},
mounted() {
this.init()
},
methods: {
async init(){
await this.getSetores()
await this.getUsuarios()
await this.getSelectMenutype()
await this.getSelectDepartment()
var resp = await store.dispatch('getBot', this.bot_id)
const id = document.getElementById("drawflow");
this.editor = new Drawflow(id);
this.editor.start();
if(resp){
this.dados = resp.data
if(this.dados.flow != ''){
var exportdata = JSON.stringify(this.dados.flow)
exportdata = JSON.parse(exportdata)
this.editor.import(exportdata)
}
}
},
async getSetores(){
var resp = await store.dispatch('getSetoresSelect')
this.setores = resp.status == '200' ? resp.data.departments : []
},
async getUsuarios(){
var resp = await store.dispatch('getUsuarioSelect')
this.usuarios = resp.status == '200' ? resp.data.users : []
},
async getSelectMenutype(){
const resp = await store.dispatch('getMenutypeSelect')
if(resp.status == 200){
this.bot_menu_types = resp.data.bot_menu_types
}
},
async getSelectDepartment(){
// faz a requisição para o back para coletar os setores
const resp = await store.dispatch('getSetoresSelect')
// caso o status da resposta seja 200 (deu certo)
if(resp.status == 200){
// atribui a resposta na variavel departments
this.departments = resp.data.departments
}
},
positionMobile(ev) {
this.mobile_last_move = ev;
},
allowDrop(ev) {
ev.preventDefault();
},
zoomIn(){
this.editor.zoom_in();
},
zoomOut(){
this.editor.zoom_out();
},
zoomReset(){
this.editor.zoom_reset();
},
drag(ev) {
if (ev.type === "touchstart") {
this.mobile_item_selec = ev.target.closest(".drag-drawflow").getAttribute('data-node');
}
else {
ev.dataTransfer.setData("node", ev.target.getAttribute('data-node'));
}
},
drop(ev) {
if (ev.type === "touchend") {
var parentdrawflow = document.elementFromPoint( this.mobile_last_move.touches[0].clientX, this.mobile_last_move.touches[0].clientY).closest("#drawflow");
if(parentdrawflow != null) {
this.addNodeToDrawFlow(this.mobile_item_selec, this.mobile_last_move.touches[0].clientX, this.mobile_last_move.touches[0].clientY);
}
this.mobile_item_selec = '';
}
else {
ev.preventDefault();
var data = ev.dataTransfer.getData("node");
this.addNodeToDrawFlow(data, ev.clientX, ev.clientY);
}
},
async addNodeToDrawFlow(name, pos_x, pos_y) {
if(this.editor.editor_mode === 'fixed') {
return false;
}
pos_x = pos_x * ( this.editor.precanvas.clientWidth / (this.editor.precanvas.clientWidth * this.editor.zoom)) - (this.editor.precanvas.getBoundingClientRect().x * ( this.editor.precanvas.clientWidth / (this.editor.precanvas.clientWidth * this.editor.zoom)));
pos_y = pos_y * ( this.editor.precanvas.clientHeight / (this.editor.precanvas.clientHeight * this.editor.zoom)) - (this.editor.precanvas.getBoundingClientRect().y * ( this.editor.precanvas.clientHeight / (this.editor.precanvas.clientHeight * this.editor.zoom)));
switch (name) {
case 'inicio':
if(document.getElementsByClassName("inicio").length == 0){
var inicio = `
<div>
<div class="title-box inicio"><i class="fas fa-play"></i> Início</div>
</div>
`;
this.editor.addNode('inicio', 0, 1, pos_x, pos_y, 'inicio', {} , inicio);
}
else{
Swal.fire({
icon: 'warning',
title: 'Ops...',
text: 'É permitido apenas um item Início!',
})
}
break;
// case 'menu':
// var menu = `
// <div>
// <div class="title-box"><i class="fas fa-comment-alt"></i> Menu </div>
// <div class="box">
// <p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
// <p>Nome:</p>
// <input type="text" name="nome_setor">
// <p>Mensagem de despedida:</p>
// <textarea> </textarea>
// </div>
// </div>
// `;
// this.editor.addNode('menu', 1, 1, pos_x, pos_y, 'aws', { "db": { "dbname": '', "key": '' }}, menu);
// break;
case 'multiple':
var { value: qnt_outputs } = await Swal.fire({
input: 'number',
inputLabel: 'Digite a quantidade de menus que deseja:',
showCancelButton: true,
confirmButtonText: 'Confirmar',
cancelButtonText: 'Cancelar',
inputAttributes: {
min: 0,
},
inputValidator: (value) => {
return new Promise((resolve) => {
if (value <= 0) {
resolve('Digite um valor válido!')
}
else{
resolve()
}
})
}
})
var campos = '';
var variaveis = {"text_superior": this.dados.settings.message_upper_menu, "text_inferior": this.dados.settings.message_down_menu, quantidade_menus:0};
if(qnt_outputs){
variaveis.quantidade_menus = qnt_outputs;
for(let i = 0; i < qnt_outputs; i++){
campos +=
`<input type="text" df-nome_menu`+ (i+1) + ` placeholder="Nome do menu `+ (i+1) + `">`;
if(i < this.departments.length){
variaveis['nome_menu' + (i+1)] = this.departments[i].name
}
else{
variaveis['nome_menu' + (i+1)] = ''
}
}
var multiple = `
<div>
<div class="title-box"><i class="fas fa-comment-alt"></i> Menu </div>
<div class="box">
<p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
<p>Mensagem superior:</p>
<textarea df-text_superior> </textarea>`
+ campos +
`<p>Mensagem inferior:</p>
<textarea df-text_inferior> </textarea>
</div>
</div>
`;
this.editor.addNode('multiple', 1, qnt_outputs, pos_x, pos_y, 'multiple', variaveis, multiple);
}
break;
case 'agendamento':
var agendamento = `
<div>
<div class="title-box"><i class="fas fa-clipboard-list"></i> API Agendamento </div>
<div class="box">
<p>Tipo:</p>
<input type="text" df-text_tipo placeholder="Tipo">
<p>Token:</p>
<input type="text" df-text_token placeholder="Token">
<p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
<p>Mensagem de despedida:</p>
<textarea df-text_agendamento> </textarea>
</div>
</div>
`
this.editor.addNode('agendamento', 1, 0, pos_x, pos_y, 'agendamento', { "text_tipo": '', "text_token": "", "text_agendamento": this.dados.settings.goodbye_text_template }, agendamento);
break;
// case 'delivery':
// var delivery = `
// <div>
// <div class="title-box"><i class="fas fa-motorcycle"></i></i> Delivery </div>
// <div class="box">
// <p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
// <p>Mensagem de despedida:</p>
// <textarea df-text_delivery> </textarea>
// </div>
// </div>
// `
// this.editor.addNode('delivery', 1, 0, pos_x, pos_y, 'delivery', { "text_delivery": this.dados.settings.goodbye_text_template }, delivery);
// break;
// case 'lgpd':
// var lgpd = `
// <div>
// <div class="title-box"><i class="fas fa-gavel"></i> LGPD </div>
// <div class="box">
// <p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
// <p>Mensagem de despedida:</p>
// <textarea df-text_lgpd> </textarea>
// </div>
// </div>
// `
// this.editor.addNode('lgpd', 1, 0, pos_x, pos_y, 'lgpd', { "text_lgpd": this.dados.settings.goodbye_text_template }, lgpd);
// break;
case 'bot':
var bot = `
<div>
<div class="title-box"><i class="fas fa-robot"></i> BOT </div>
<div class="box">
<p style="font-weight: 600;">Tag's disponíveis: {nomes} {telefone}</p>
<p>Mensagem de despedida:</p>
<textarea df-text_bot> </textarea>
</div>
</div>
`
this.editor.addNode('bot', 1, 0, pos_x, pos_y, 'bot', { "text_bot": this.dados.settings.goodbye_text_template }, bot);
break;
case 'chat_usuario':
var optionsUsuario = `<option value="">Selecione o usuário</option>`
for(let i = 0; i < this.usuarios.length; i++){
optionsUsuario += `<option value="`+ this.usuarios[i].id + `">`+ this.usuarios[i].name + `</option>`
}
var chat_usuario = `
<div>
<div class="title-box"><i class="fas fa-comments"></i> Chat Usuário </div>
<div class="box">
<div class="div-select">
<select df-chat_usuario>`
+ optionsUsuario +
`</select>
</div>
<p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
<p>Mensagem de despedida:</p>
<textarea df-text_usuario> </textarea>
</div>
</div>
`
this.editor.addNode('chat_usuario', 1, 0, pos_x, pos_y, 'chat_usuario', { "chat_usuario": '', "text_usuario": this.dados.settings.goodbye_text_template }, chat_usuario);
break;
case 'chat_setor':
var optionsSetores = `<option value="">Selecione o setor</option>`
for(let i = 0; i < this.setores.length; i++){
optionsSetores += `<option value="`+ this.setores[i].id + `">`+ this.setores[i].name + `</option>`
}
var chat_setor = `
<div>
<div class="title-box"><i class="fas fa-comments"></i> Chat Setor </div>
<div class="box">
<div class="div-select">
<select df-chat_usuario>`
+ optionsSetores +
`</select>
</div>
<p style="font-weight: 600;">Tag's disponíveis: {nome} {telefone}</p>
<p>Mensagem de despedida:</p>
<textarea df-text_setor> </textarea>
</div>
</div>
`
this.editor.addNode('chat_setor', 1, 0, pos_x, pos_y, 'chat_setor', { "chat_setor": '', "text_setor": this.dados.settings.goodbye_text_template}, chat_setor);
break;
default:
}
},
showpopup(e) {
e.target.closest(".drawflow-node").style.zIndex = "9999";
e.target.children[0].style.display = "block";
//document.getElementById("modalfix").style.display = "block";
//e.target.children[0].style.transform = 'translate('+translate.x+'px, '+translate.y+'px)';
this.transform = this.editor.precanvas.style.transform;
this.editor.precanvas.style.transform = '';
this.editor.precanvas.style.left = this.editor.canvas_x +'px';
this.editor.precanvas.style.top = this.editor.canvas_y +'px';
//e.target.children[0].style.top = -this.editor.canvas_y - this.editor.container.offsetTop +'px';
//e.target.children[0].style.left = -this.editor.canvas_x - this.editor.container.offsetLeft +'px';
this.editor.editor_mode = "fixed";
},
closemodal(e) {
e.target.closest(".drawflow-node").style.zIndex = "2";
e.target.parentElement.parentElement.style.display ="none";
//document.getElementById("modalfix").style.display = "none";
this.editor.precanvas.style.transform = this.transform;
this.editor.precanvas.style.left = '0px';
this.editor.precanvas.style.top = '0px';
this.editor.editor_mode = "edit";
},
changeModule(event) {
var all = document.querySelectorAll(".menu ul li");
for (var i = 0; i < all.length; i++) {
all[i].classList.remove('selected');
}
event.target.classList.add('selected');
},
numbersHomologationSave(){
// for(let i = 0; i < this.dados.settings.numbers_homologation.length; i++){
// this.dados.settings.numbers_homologation[i] = this.dados.settings.numbers_homologation[i].replace(/\D/g, '')
// }
if (this.$refs.form_telefones.validate()){
this.dialog_numbers_homologation = false
}
},
openModalNumbers(){
if(this.dados.settings.numbers_homologation == ''){
this.dados.settings.numbers_homologation = []
}
this.dialog_numbers_homologation = true
},
addItem(){
this.dados.menus.unshift({
department_id: '',
bot_menu_type_id: '',
text: '',
goodbye_text: '',
key: '',
settings: {}
})
},
removeItem(index){
if (index > -1) {
this.dados.menus.splice(index, 1);
}
},
addItemNumber(){
this.dados.settings.numbers_homologation.push('')
},
removeItemNumber(index){
if (index > -1) {
this.dados.settings.numbers_homologation.splice(index, 1);
}
},
confirmName(){
if(this.dados.settings.ask_name == false){
this.dados.settings.confirm_name = false
}
},
async nextPage(){
if(this.step == 1){
if (this.$refs.form_bot.validate()){
this.step = 2
}
}else if(this.step == 2){
this.enviar()
}
},
// função para enviar um menu
async enviar(){
let resp = {}
let date_update
// coloca o componente como loading
this.loading = await true
let flow = await document.getElementsByClassName("inicio").length == 0 ? false : true
if(this.dados.settings.numbers_homologation.length > 0 && typeof this.dados.settings.numbers_homologation[0] != 'number'){
for(let i = 0; i < this.dados.settings.numbers_homologation.length; i++){
this.dados.settings.numbers_homologation[i] = Number(this.dados.settings.numbers_homologation[i].replace(/\D/g, ''))
}
}
if(flow){
this.dados.flow = JSON.stringify(this.editor.export())
if(this.dados.id){
// coleta o status do setor
date_update = await {
dados: this.dados,
id: this.dados.id,
}
resp = await store.dispatch('putBot', date_update)
}else{
// faz a requisição para o back para coletar os menus
resp = await store.dispatch('postBot', this.dados)
}
}
else{
Swal.fire({
icon: 'warning',
title: 'Ops...',
text: 'O Flow está sem a entrada Início!',
})
return false
}
// caso o status da resposta seja 200 (deu certo)
if(resp.status != 200 && resp.status != 201){
Swal.fire({
icon: 'warning',
title: 'Ops...',
text: 'Algo deu errado!',
})
// caso tenha dado algum erro
}else{
Swal.fire({
icon: 'success',
text: 'Salvo com sucesso!',
})
// mostra a mensagem
// this.closeStepper()
}
// retira o loading do componente
this.loading = false
// atualiza a tabela
this.$refs.tabela.init()
},
closeStepper(){
this.dados = {
id: '',
name: '',
settings: {
goodbye_text_template: '',
ask_name: '',
confirm_name: '',
homologation: '',
message_ask_name: '',
message_down_confirm_name: '',
message_upper_confirm_name: '',
numbers_homologation: [],
message_down_menu: '',
message_upper_menu: '',
message_down_option_invalidates_menu: '',
message_upper_option_invalidates_menu: '',
message_down_company: '',
message_upper_company: '',
message_down_option_invalidates_company: '',
message_upper_option_invalidates_company: '',
message_down_date: '',
message_upper_date: '',
message_down_option_invalidates_date: '',
message_upper_option_invalidates_date: '',
message_down_time: '',
message_upper_time: '',
message_down_option_invalidates_time: '',
message_upper_option_invalidates_time: '',
message_transfer: '',
message_transfer_all_user_unavailable: '',
message_offtime: '',
},
menus: [{
department_id: '',
bot_menu_type_id: '',
text: '',
goodbye_text: '',
key: '',
status: '',
settings: {}
}],
flow: ''
}
this.$router.push('/bot')
},
}
}
</script>
<style lang="scss">
.v-card {
width: 100%;
.v-card__title{
background-color: #f0f8ff;
.headline {
font-weight: 600 !important;
width: 100%;
svg{
margin-right: 5px;
}
}
}
.v-card__text{
background-color: #f0f8ff;
}
&.theme--light{
background-color: #f0f8ff;
}
}
.v-form{
width: 100%;
}
.v-stepper__step__step, .v-stepper__label{
font-weight: 600;
}
.v-stepper__wrapper{
display: flex;
flex-wrap: wrap;
}
.div-btns{
padding: 0;
.row-btns{
background-color: #fff;
align-items: center;
}
}
.btn-cancelar{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
button{
margin-left: 12px;
}
}
.btn-avancar{
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
button{
margin-right: 12px;
}
}
.div-menu{
display: flex;
flex: 1 1 auto;
.div-inputs{
display: flex;
flex-wrap: wrap;
flex: 1 1 auto;
}
.remover-menu{
min-width: inherit;
margin-top: 20px;
margin-left: 24px;
}
}
button{
font-weight: 600 !important;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
min-height: 100%;
}
#drawflow {
position: relative;
background: var(--background-color);
background-size: 25px 25px;
width: 100%;
height: 100%;
text-align: initial;
background-size: 25px 25px;
background-image: linear-gradient(to right, #f1f1f1 1px, transparent 1px), linear-gradient(to bottom, #f1f1f1 1px, transparent 1px);
}
.inputs{
width: 0;
}
.drawflow {
position: relative;
width: 100%;
height: 100%;
user-select: none;
.parent-node {
position: relative;
}
.drawflow-node {
display: flex;
align-items: center;
position: absolute;
background: #0ff;
min-height: 40px;
border-radius: 4px;
border: 1px solid #000;
color: #000;
z-index: 2;
padding: 0px;
width: 200px;
&:hover {
cursor: move;
}
.outputs {
width: 0;
}
.drawflow_content_node {
width: 100%;
display: block;
}
.input {
position: relative;
width: 20px;
height: 20px;
background: #fff;
border-radius: 50%;
border: 2px solid #000;
cursor: crosshair;
z-index: 1;
margin-bottom: 5px;
left: -27px;
top: 2px;
background: #ff0;
}
.output {
position: relative;
width: 20px;
height: 20px;
background: #fff;
border-radius: 50%;
border: 2px solid #000;
cursor: crosshair;
z-index: 1;
margin-bottom: 5px;
right: -3px;
top: 2px;
}
}
svg {
z-index: 0;
position: absolute;
overflow: visible !important;
}
.connection {
position: absolute;
pointer-events: none;
.main-path {
fill: none;
stroke-width: 5px;
stroke: #4682b4;
pointer-events: all;
&:hover {
stroke: #1266ab;
cursor: pointer;
}
}
.main-path.selected {
stroke: #43b993;
}
.point {
cursor: move;
stroke: #000;
stroke-width: 2;
fill: #fff;
pointer-events: all;
&:hover {
fill: #1266ab;
}
}
.point.selected {
fill: #1266ab;
}
}
.main-path {
fill: none;
stroke-width: 5px;
stroke: #4682b4;
}
>.drawflow-delete {
margin-left: -15px;
margin-top: 15px;
}
.title-box {
svg {
position: initial;
margin-right: 5px;
filter: drop-shadow(2px 4px 6px #969696);
}
}
}
.parent-drawflow {
display: flex;
overflow: hidden;
touch-action: none;
outline: 0;
}
.drawflow-delete {
position: absolute;
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 30px;
height: 30px;
background: #000;
color: #fff;
z-index: 4;
border: 2px solid #fff;
line-height: 30px;
font-weight: 700;
text-align: center;
border-radius: 50%;
font-family: monospace;
cursor: pointer;
}
.parent-node {
.drawflow-delete {
right: -15px;
top: -15px;
}
}
.drawflow-node {
.title-box {
height: 50px;
line-height: 50px;
background: #F4D728;
color: #fff;
font-weight: 600;
text-shadow: 1px 2px 5px #969696;
border-bottom: 1px solid #e9e9e9;
border-radius: 4px 4px 0px 0px;
padding-left: 10px;
&.inicio{
border-radius: 4px;
}
}
.box {
padding: 10px;
font-size: 14px;
color: #555555;
p {
margin-top: 5px;
margin-bottom: 5px;
}
}
input {
display: flex;
margin-bottom: 10px;
border-radius: 4px;
border: 1px solid #cacaca;
line-height: 20px;
width: 100%;
color: #555555;
padding: 5px;
font-size: 15px;
&:nth-last-child(1) {
margin-bottom: 0;
}
}
select {
display: flex;
margin-bottom: 10px;
border-radius: 4px;
border: 1px solid #cacaca;
line-height: 20px;
width: 100%;
color: #555555;
padding: 5px;
font-size: 15px;
}
textarea {
display: flex;
margin-bottom: 10px;
border-radius: 4px;
border: 1px solid #cacaca;
line-height: 20px;
width: 100%;
color: #555555;
padding: 5px;
font-size: 15px;
height: 100px;
}
.div-select {
position: relative;
&:before {
content: '\f078';
font-family: 'Font Awesome 5 Free';
position: absolute;
color: #555555;
font-weight: 900;
top: 50%;
transform: translateY(-50%);
right: 5px;
}
}
}
.drawflow-node.welcome {
width: 250px;
}
.drawflow-node.slack {
.title-box {
border-radius: 4px;
}
}
.them-edit-link {
position: absolute;
top: 10px;
right: 100px;
color: black;
font-size: 40px;
a {
text-decoration: none;
}
}
.github-link {
position: absolute;
top: 10px;
right: 20px;
color: black;
}
.wrapper {
width: 100%;
display: flex;
}
.col {
background: #fff;
overflow: auto;
width: 250px;
height: 100%;
border-right: 2px solid #F4D728;
padding: 0;
}
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px #969696;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #F4D728;
border-radius: 10px;
&:hover {
background: #969696;
}
}
.col-right {
width: calc(100% - 250px);
overflow: hidden;
background: #fff;
background-size: 25px 25px;
background-image: linear-gradient(to right, #f1f1f1 1px, transparent 1px), linear-gradient(to bottom, #f1f1f1 1px, transparent 1px);
}
.divisao-flow {
span {
color: #555555;
font-weight: 600;
}
}
.drag-drawflow {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
line-height: 50px;
cursor: move;
user-select: none;
transition: all ease .3s;
background-color: #F4D728;
border-radius: 10px;
padding: 0px 10px;
margin: 10px 15px;
&:hover {
background-color: #969696;
}
span {
color: #fff;
font-weight: 600;
text-shadow: 1px 2px 5px #969696;
margin-left: 10px;
}
svg {
filter: drop-shadow(2px 4px 6px #969696);
path {
fill: #fff;
}
}
}
.menu {
position: absolute;
height: 40px;
display: block;
background: white;
width: 100%;
ul {
padding: 0px;
margin: 0px;
line-height: 40px;
}
}
/* Modal */
/* The Close Button */
.menu {
ul {
li {
display: inline-block;
margin-left: 10px;
border-right: 1px solid var #404040;
padding-right: 10px;
line-height: 40px;
cursor: pointer;
}
li.selected {
font-weight: bold;
}
}
}
.btn-export {
float: right;
position: absolute;
top: 10px;
right: 10px;
color: white;
font-weight: bold;
border: 1px solid #0e5ba3;
background: #4ea9ff;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
z-index: 5;
}
.btn-option {
float: right;
position: absolute;
top: 10px;
right: 15px;
color: #fff;
font-weight: bold;
border: 2px solid #ffd900;
background: #F4D728;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
z-index: 5;
box-shadow: 0px 2px 7px #969696;
text-shadow: 1px 2px 5px #969696;
transition: all ease .3s;
&:hover {
color: #fff;
border: 2px solid #555555;
background: #555555;
}
}
.btn-save {
&:hover {
color: #fff;
border: 2px solid #555555;
background: #555555;
}
}
.swal-wide {
width: 80% !important;
}
.bar-zoom {
float: right;
position: absolute;
bottom: 10px;
right: 10px;
display: flex;
font-size: 24px;
color: white;
padding: 5px 10px;
background: #555555;
border-radius: 4px;
border-right: 1px solid var #404040;
z-index: 5;
button {
padding: 0 7px;
}
}
.modal {
display: none;
position: fixed;
z-index: 7;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
overflow: auto;
background-color: rgba(0,0,0,0.7);
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
}
.modal-content {
position: relative;
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
}
.swal2-container {
font-family: 'Arial';
}
.swal2-input-label {
font-weight: 600;
}
.swal2-confirm {
background-color: #F4D728 !important;
box-shadow: 0px 2px 7px #969696;
text-shadow: 1px 2px 5px #969696;
}
.swal2-actions {
button {
font-weight: 600;
transition: all ease .3s;
}
}
@media only screen and (max-width: 768px) {
.col {
width: 50px;
.drag-drawflow {
span {
display: none;
}
}
}
#drawflow {
width: calc(100vw - 51px);
}
.modal-content {
width: 80%;
}
}
</style>
<style>
:root {
--dfBackgroundColor: rgba(255, 255, 255, 1);
--dfBackgroundSize: 0px;
--dfBackgroundImage: none;
--dfNodeType: flex;
--dfNodeTypeFloat: none;
--dfNodeBackgroundColor: rgba(255, 255, 255, 1);
--dfNodeTextColor: rgba(64, 64, 64, 1);
--dfNodeBorderSize: 2px;
--dfNodeBorderColor: rgba(238, 238, 238, 1);
--dfNodeBorderRadius: 5px;
--dfNodeMinHeight: 40px;
--dfNodeMinWidth: 160px;
--dfNodePaddingTop: 15px;
--dfNodePaddingBottom: 15px;
--dfNodeBoxShadowHL: 0px;
--dfNodeBoxShadowVL: 2px;
--dfNodeBoxShadowBR: 15px;
--dfNodeBoxShadowS: 1px;
--dfNodeBoxShadowColor: rgba(208, 208, 208, 1);
--dfNodeHoverBackgroundColor: #ffffff;
--dfNodeHoverTextColor: rgba(64, 64, 64, 1);
--dfNodeHoverBorderSize: 2px;
--dfNodeHoverBorderColor: rgba(202, 202, 202, 1);
--dfNodeHoverBorderRadius: 5px;
--dfNodeHoverBoxShadowHL: 0px;
--dfNodeHoverBoxShadowVL: 2px;
--dfNodeHoverBoxShadowBR: 15px;
--dfNodeHoverBoxShadowS: 2px;
--dfNodeHoverBoxShadowColor: rgba(244, 215, 40, 0.6);
--dfNodeSelectedBackgroundColor: rgb(255, 255, 255);
--dfNodeSelectedTextColor: rgba(64, 64, 64, 1);
--dfNodeSelectedBorderSize: 2px;
--dfNodeSelectedBorderColor: rgba(202, 202, 202, 1);
--dfNodeSelectedBorderRadius: 4px;
--dfNodeSelectedBoxShadowHL: 0px;
--dfNodeSelectedBoxShadowVL: 2px;
--dfNodeSelectedBoxShadowBR: 15px;
--dfNodeSelectedBoxShadowS: 2px;
--dfNodeSelectedBoxShadowColor: rgba(244, 215, 40, 1);
--dfInputBackgroundColor: #ffffff;
--dfInputBorderSize: 2px;
--dfInputBorderColor: rgba(202, 202, 202, 1);
--dfInputBorderRadius: 50px;
--dfInputLeft: -8px;
--dfInputHeight: 15px;
--dfInputWidth: 15px;
--dfInputHoverBackgroundColor: #ffffff;
--dfInputHoverBorderSize: 2px;
--dfInputHoverBorderColor: #000000;
--dfInputHoverBorderRadius: 50px;
--dfOutputBackgroundColor: rgba(255, 255, 255, 1);
--dfOutputBorderSize: 2px;
--dfOutputBorderColor: rgba(202, 202, 202, 1);
--dfOutputBorderRadius: 50px;
--dfOutputRight: 7px;
--dfOutputHeight: 15px;
--dfOutputWidth: 15px;
--dfOutputHoverBackgroundColor: #ffffff;
--dfOutputHoverBorderSize: 2px;
--dfOutputHoverBorderColor: #000000;
--dfOutputHoverBorderRadius: 50px;
--dfLineWidth: 5px;
--dfLineColor: rgba(244, 215, 40, 1);
--dfLineHoverColor: rgba(0, 0, 0, 1);
--dfLineSelectedColor: rgba(78, 169, 255, 1);
--dfRerouteBorderWidth: 2px;
--dfRerouteBorderColor: rgba(202, 202, 202, 1);
--dfRerouteBackgroundColor: #ffffff;
--dfRerouteHoverBorderWidth: 2px;
--dfRerouteHoverBorderColor: #000000;
--dfRerouteHoverBackgroundColor: #ffffff;
--dfDeleteDisplay: block;
--dfDeleteColor: rgba(255, 255, 255, 1);
--dfDeleteBackgroundColor: rgba(64, 64, 64, 1);
--dfDeleteBorderSize: 2px;
--dfDeleteBorderColor: rgba(64, 64, 64, 1);
--dfDeleteBorderRadius: 50px;
--dfDeleteTop: -23px;
--dfDeleteHoverColor: rgba(64, 64, 64, 1);
--dfDeleteHoverBackgroundColor: #ffffff;
--dfDeleteHoverBorderSize: 2px;
--dfDeleteHoverBorderColor: rgba(64, 64, 64, 1);
--dfDeleteHoverBorderRadius: 50px;
}
.drawflow .drawflow-node {
display: var(--dfNodeType);
background: var(--dfNodeBackgroundColor);
color: var(--dfNodeTextColor);
border: var(--dfNodeBorderSize) solid var(--dfNodeBorderColor);
border-radius: var(--dfNodeBorderRadius);
min-height: var(--dfNodeMinHeight);
width: max-content;
min-width: var(--dfNodeMinWidth);
/* padding-top: var(--dfNodePaddingTop); */
/* padding-bottom: var(--dfNodePaddingBottom); */
-webkit-box-shadow: var(--dfNodeBoxShadowHL) var(--dfNodeBoxShadowVL) var(--dfNodeBoxShadowBR) var(--dfNodeBoxShadowS) var(--dfNodeBoxShadowColor);
box-shadow: var(--dfNodeBoxShadowHL) var(--dfNodeBoxShadowVL) var(--dfNodeBoxShadowBR) var(--dfNodeBoxShadowS) var(--dfNodeBoxShadowColor);
}
.drawflow .drawflow-node:hover {
background: var(--dfNodeHoverBackgroundColor);
color: var(--dfNodeHoverTextColor);
border: var(--dfNodeHoverBorderSize) solid var(--dfNodeHoverBorderColor);
border-radius: var(--dfNodeHoverBorderRadius);
-webkit-box-shadow: var(--dfNodeHoverBoxShadowHL) var(--dfNodeHoverBoxShadowVL) var(--dfNodeHoverBoxShadowBR) var(--dfNodeHoverBoxShadowS) var(--dfNodeHoverBoxShadowColor);
box-shadow: var(--dfNodeHoverBoxShadowHL) var(--dfNodeHoverBoxShadowVL) var(--dfNodeHoverBoxShadowBR) var(--dfNodeHoverBoxShadowS) var(--dfNodeHoverBoxShadowColor);
}
.drawflow .drawflow-node.selected {
background: var(--dfNodeSelectedBackgroundColor);
color: var(--dfNodeSelectedTextColor);
border: var(--dfNodeSelectedBorderSize) solid var(--dfNodeSelectedBorderColor);
border-radius: var(--dfNodeSelectedBorderRadius);
-webkit-box-shadow: var(--dfNodeSelectedBoxShadowHL) var(--dfNodeSelectedBoxShadowVL) var(--dfNodeSelectedBoxShadowBR) var(--dfNodeSelectedBoxShadowS) var(--dfNodeSelectedBoxShadowColor);
box-shadow: var(--dfNodeSelectedBoxShadowHL) var(--dfNodeSelectedBoxShadowVL) var(--dfNodeSelectedBoxShadowBR) var(--dfNodeSelectedBoxShadowS) var(--dfNodeSelectedBoxShadowColor);
}
.drawflow .drawflow-node .input {
left: var(--dfInputLeft);
background: var(--dfInputBackgroundColor);
border: var(--dfInputBorderSize) solid var(--dfInputBorderColor);
border-radius: var(--dfInputBorderRadius);
height: var(--dfInputHeight);
width: var(--dfInputWidth);
}
.drawflow .drawflow-node .input:hover {
background: var(--dfInputHoverBackgroundColor);
border: var(--dfInputHoverBorderSize) solid var(--dfInputHoverBorderColor);
border-radius: var(--dfInputHoverBorderRadius);
}
.drawflow .drawflow-node .outputs {
float: var(--dfNodeTypeFloat);
}
.drawflow .drawflow-node .output {
right: var(--dfOutputRight);
background: var(--dfOutputBackgroundColor);
border: var(--dfOutputBorderSize) solid var(--dfOutputBorderColor);
border-radius: var(--dfOutputBorderRadius);
height: var(--dfOutputHeight);
width: var(--dfOutputWidth);
}
.drawflow .drawflow-node .output:hover {
background: var(--dfOutputHoverBackgroundColor);
border: var(--dfOutputHoverBorderSize) solid var(--dfOutputHoverBorderColor);
border-radius: var(--dfOutputHoverBorderRadius);
}
.drawflow .connection .main-path {
stroke-width: var(--dfLineWidth);
stroke: var(--dfLineColor);
}
.drawflow .connection .main-path:hover {
stroke: var(--dfLineHoverColor);
}
.drawflow .connection .main-path.selected {
stroke: var(--dfLineSelectedColor);
}
.drawflow .connection .point {
stroke: var(--dfRerouteBorderColor);
stroke-width: var(--dfRerouteBorderWidth);
fill: var(--dfRerouteBackgroundColor);
}
.drawflow .connection .point:hover {
stroke: var(--dfRerouteHoverBorderColor);
stroke-width: var(--dfRerouteHoverBorderWidth);
fill: var(--dfRerouteHoverBackgroundColor);
}
.drawflow-delete {
display: var(--dfDeleteDisplay);
color: var(--dfDeleteColor);
background: var(--dfDeleteBackgroundColor);
border: var(--dfDeleteBorderSize) solid var(--dfDeleteBorderColor);
border-radius: var(--dfDeleteBorderRadius);
}
.parent-node .drawflow-delete {
top: var(--dfDeleteTop);
}
.drawflow-delete:hover {
color: var(--dfDeleteHoverColor);
background: var(--dfDeleteHoverBackgroundColor);
border: var(--dfDeleteHoverBorderSize) solid var(--dfDeleteHoverBorderColor);
border-radius: var(--dfDeleteHoverBorderRadius);
}
</style>
You can delay the import of the json 250 ms.
Or change mounted with nextTick:
mounted() {
this.$nextTick(() => {
this.init()
});
},
I tried it both ways, but neither worked
This problem occurs when javascript is loaded before css.
Correct example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"
/>
<script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
</head>
<body>
<style>
#drawflow {
position: relative;
width: 600px;
height: 600px;
border: 1px solid red;
}
</style>
<div id="drawflow"></div>
<script>
var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();
editor.import( {"drawflow":{"Home":{"data":{"6":{"id":6,"data":{},"html":"\n <div>\n <div class=\"title-box inicio\"><i class=\"fas fa-play\"></i> Início</div>\n </div>\n ","name":"inicio","class":"inicio","pos_x":-55.42857142857143,"pos_y":388,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"7","output":"input_1"}]}},"typenode":false},"7":{"id":7,"data":{"nome_menu1":"Suporte 2","text_inferior":"Mens Inferior","text_superior":"Mens Superior","quantidade_menus":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comment-alt\"></i> Menu </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem superior:</p>\n <textarea df-text_superior> </textarea><input type=\"text\" df-nome_menu1 placeholder=\"Nome do menu 1\"><p>Mensagem inferior:</p>\n <textarea df-text_inferior> </textarea>\n </div>\n </div>\n ","name":"multiple","class":"multiple","pos_x":145.57142857142858,"pos_y":207,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"8","output":"input_1"},{"node":"9","output":"input_1"},{"node":"10","output":"input_1"}]}},"typenode":false},"8":{"id":8,"data":{"text_bot":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-robot\"></i> BOT </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nomes} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_bot> </textarea>\n </div>\n </div>\n ","name":"bot","class":"bot","pos_x":517.5714285714286,"pos_y":26,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"9":{"id":9,"data":{"chat_usuario":"67","text_usuario":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Usuário </div>\n <div class=\"box\"> \n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o usuário</option><option value=\"67\">Giovanni Pucci</option><option value=\"265\">Sony</option><option value=\"279\">Sony 1</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_usuario> </textarea>\n </div>\n </div>\n ","name":"chat_usuario","class":"chat_usuario","pos_x":550.5714285714286,"pos_y":280,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"10":{"id":10,"data":{"chat_setor":"","text_setor":"Msg despedida {nome}","chat_usuario":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Setor </div>\n <div class=\"box\">\n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o setor</option><option value=\"1\">Suporte 2</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_setor> </textarea>\n </div>\n </div>\n ","name":"chat_setor","class":"chat_setor","pos_x":551.8571428571429,"pos_y":574.5714285714286,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false}}}}} );
</script>
</body>
</html>
Incorrect example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"
/>
<script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
</head>
<body>
<div id="drawflow"></div>
<script>
var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();
editor.import( {"drawflow":{"Home":{"data":{"6":{"id":6,"data":{},"html":"\n <div>\n <div class=\"title-box inicio\"><i class=\"fas fa-play\"></i> Início</div>\n </div>\n ","name":"inicio","class":"inicio","pos_x":-55.42857142857143,"pos_y":388,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"7","output":"input_1"}]}},"typenode":false},"7":{"id":7,"data":{"nome_menu1":"Suporte 2","text_inferior":"Mens Inferior","text_superior":"Mens Superior","quantidade_menus":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comment-alt\"></i> Menu </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem superior:</p>\n <textarea df-text_superior> </textarea><input type=\"text\" df-nome_menu1 placeholder=\"Nome do menu 1\"><p>Mensagem inferior:</p>\n <textarea df-text_inferior> </textarea>\n </div>\n </div>\n ","name":"multiple","class":"multiple","pos_x":145.57142857142858,"pos_y":207,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"8","output":"input_1"},{"node":"9","output":"input_1"},{"node":"10","output":"input_1"}]}},"typenode":false},"8":{"id":8,"data":{"text_bot":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-robot\"></i> BOT </div>\n <div class=\"box\">\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nomes} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_bot> </textarea>\n </div>\n </div>\n ","name":"bot","class":"bot","pos_x":517.5714285714286,"pos_y":26,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"9":{"id":9,"data":{"chat_usuario":"67","text_usuario":"Msg despedida"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Usuário </div>\n <div class=\"box\"> \n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o usuário</option><option value=\"67\">Giovanni Pucci</option><option value=\"265\">Sony</option><option value=\"279\">Sony 1</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_usuario> </textarea>\n </div>\n </div>\n ","name":"chat_usuario","class":"chat_usuario","pos_x":550.5714285714286,"pos_y":280,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false},"10":{"id":10,"data":{"chat_setor":"","text_setor":"Msg despedida {nome}","chat_usuario":"1"},"html":"\n <div>\n <div class=\"title-box\"><i class=\"fas fa-comments\"></i> Chat Setor </div>\n <div class=\"box\">\n <div class=\"div-select\">\n <select df-chat_usuario><option value=\"\">Selecione o setor</option><option value=\"1\">Suporte 2</option></select>\n </div>\n <p style=\"font-weight: 600;\">Tag's disponíveis: {nome} {telefone}</p>\n <p>Mensagem de despedida:</p>\n <textarea df-text_setor> </textarea>\n </div>\n </div>\n ","name":"chat_setor","class":"chat_setor","pos_x":551.8571428571429,"pos_y":574.5714285714286,"inputs":{"input_1":{"connections":[{"node":"7","input":"output_1"}]}},"outputs":{},"typenode":false}}}}} );
</script>
<style>
#drawflow {
position: relative;
width: 600px;
height: 600px;
border: 1px solid red;
}
</style>
</body>
</html>
Try adding the css in the head of html.
The problem was a Vue stepper, that's right now.
thks
Hi @jerosoler , primally thanks for your library.
My problem happens after the import the data, only after moving the node the lines showing.
Before:
After:
I took a test with the function updateConnectionNodes, but not resolve the problem
My code:
You can help me please?