mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 00:48:25 +00:00
Merge branch 'release/v0.5.8' into main
This commit is contained in:
commit
d74b3022e9
27 changed files with 365 additions and 98 deletions
1
Gemfile
1
Gemfile
|
|
@ -39,6 +39,7 @@ gem "mongo", "~> 2"
|
|||
gem 'aws-sdk', '~> 3'
|
||||
gem 'kaminari'
|
||||
gem 'lockbox'
|
||||
gem 'tiny_tds'
|
||||
|
||||
group :development, :test do
|
||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||
|
|
|
|||
|
|
@ -1354,6 +1354,7 @@ GEM
|
|||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
thor (1.1.0)
|
||||
tiny_tds (2.1.5)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
|
|
@ -1394,6 +1395,7 @@ DEPENDENCIES
|
|||
rubocop-rails
|
||||
simple_command
|
||||
spring
|
||||
tiny_tds
|
||||
typhoeus
|
||||
tzinfo-data
|
||||
|
||||
|
|
|
|||
59
app/services/mssql_query_service.rb
Normal file
59
app/services/mssql_query_service.rb
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
class MssqlQueryService
|
||||
include DatasourceUtils
|
||||
attr_accessor :data_query, :data_source, :options, :source_options, :current_user
|
||||
|
||||
def initialize(data_query, data_source, options, source_options, current_user)
|
||||
@data_query = data_query
|
||||
@data_source = data_source
|
||||
@options = options
|
||||
@source_options = source_options
|
||||
@current_user = current_user
|
||||
end
|
||||
|
||||
def self.connection(options)
|
||||
TinyTds::Client.new(
|
||||
database: options.dig('database', 'value'),
|
||||
username: options.dig('username', 'value'),
|
||||
password: options.dig('password', 'value'),
|
||||
host: options.dig('host', 'value'),
|
||||
port: options.dig('port', 'value'),
|
||||
azure: ActiveModel::Type::Boolean.new.cast(
|
||||
options.dig('azure', 'value')
|
||||
) || false
|
||||
)
|
||||
end
|
||||
|
||||
def process
|
||||
connection = get_cached_connection(data_source)
|
||||
connection ||= create_connection
|
||||
query_text = options['query']
|
||||
results = connection.execute(query_text)
|
||||
|
||||
{ status: 'success', data: results.to_a }
|
||||
rescue StandardError => e
|
||||
if connection&.active?
|
||||
connection&.close
|
||||
reset_connection(data_source)
|
||||
end
|
||||
|
||||
error = { message: e.message, code: 400 }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_connection
|
||||
connection = TinyTds::Client.new(
|
||||
database: source_options['database'],
|
||||
username: source_options['username'],
|
||||
password: source_options['password'],
|
||||
host: source_options['host'],
|
||||
port: source_options['port'],
|
||||
azure: ActiveModel::Type::Boolean.new.cast(
|
||||
source_options['azure']
|
||||
) || false
|
||||
)
|
||||
|
||||
cache_connection(data_source, connection)
|
||||
connection
|
||||
end
|
||||
end
|
||||
|
|
@ -3,6 +3,7 @@ default: &default
|
|||
encoding: unicode
|
||||
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
||||
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
database: tooljet_development
|
||||
|
|
@ -13,6 +14,9 @@ development:
|
|||
test:
|
||||
<<: *default
|
||||
database: tooljet_test
|
||||
username: postgres
|
||||
password: <%= ENV.fetch("DB_PASSWORD", '') %>
|
||||
host: <%= ENV.fetch("DB_HOST", 'localhost') %>
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
|
|
@ -20,4 +24,4 @@ production:
|
|||
database: <%= ENV['PG_DB'] %>
|
||||
username: <%= ENV['PG_USER'] %>
|
||||
password: <%= ENV['PG_PASS'] %>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
org = Organization.create(name: 'My organization')
|
||||
user = User.create(first_name: 'The', last_name: 'Developer', email: 'dev@tooljet.io', password: 'password', organization: org)
|
||||
OrganizationUser.create(user: user, organization: org, role: 'admin')
|
||||
OrganizationUser.create(user: user, organization: org, role: 'admin', status: 'active')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ services:
|
|||
base: &base
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./docker/server.Dockerfile
|
||||
dockerfile: ./docker/server.Dockerfile.dev
|
||||
args:
|
||||
RAILS_ENV: 'development'
|
||||
tty: true
|
||||
|
|
@ -32,7 +32,7 @@ services:
|
|||
<<: *base
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./docker/server.Dockerfile
|
||||
dockerfile: ./docker/server.Dockerfile.dev
|
||||
image: tooljet-server:development
|
||||
volumes:
|
||||
- ./:/app:delegated
|
||||
|
|
@ -46,14 +46,12 @@ services:
|
|||
- RAILS_ENV=development
|
||||
- DB_PASSWORD=postgres
|
||||
- DB_HOST=postgres
|
||||
entrypoint: ["bash", "/app/docker/entrypoints/server.sh"]
|
||||
entrypoint: ["bash", "/app/docker/entrypoints/server.sh"]
|
||||
command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
|
||||
|
||||
postgres:
|
||||
image: postgres:12
|
||||
restart: always
|
||||
ports:
|
||||
- '5432:5432'
|
||||
volumes:
|
||||
- postgres:/data/postgres
|
||||
environment:
|
||||
|
|
@ -61,6 +59,7 @@ services:
|
|||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
|
||||
|
||||
volumes:
|
||||
postgres:
|
||||
node_modules:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
bundle check || bundle install
|
||||
rake db:create
|
||||
rake db:migrate
|
||||
|
||||
exec "$@"
|
||||
if [ -e tmp/pids/server.pid ]; then
|
||||
rm tmp/pids/server.pid
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ FROM ruby:2.7.3-buster
|
|||
|
||||
RUN apt update && apt install -y \
|
||||
build-essential \
|
||||
postgresql
|
||||
postgresql \
|
||||
freetds-dev
|
||||
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
|
|
|
|||
18
docker/server.Dockerfile.dev
Normal file
18
docker/server.Dockerfile.dev
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
FROM ruby:2.7.3-buster
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
build-essential \
|
||||
postgresql \
|
||||
freetds-dev
|
||||
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
|
||||
COPY Gemfile Gemfile.lock ./
|
||||
RUN gem install bundler && bundle install --jobs 20 --retry 5
|
||||
|
||||
ENV RAILS_ENV=development
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN ["chmod", "755", "docker/entrypoints/server.sh"]
|
||||
|
|
@ -22,11 +22,15 @@ Follow these steps to setup and run ToolJet on Mac OS. Open terminal and run the
|
|||
$ curl -L https://get.rvm.io | bash -s stable
|
||||
```
|
||||
|
||||
### Install Ruby using RVM
|
||||
### Install Ruby using RVM
|
||||
```bash
|
||||
$ rvm install ruby-2.7.3
|
||||
$ rvm use 2.7.3
|
||||
```
|
||||
### Install [Bundler](https://bundler.io/)
|
||||
```bash
|
||||
gem install bundler:2.1.4
|
||||
```
|
||||
|
||||
### Install Node.js
|
||||
```bash
|
||||
|
|
@ -42,41 +46,52 @@ Follow these steps to setup and run ToolJet on Mac OS. Open terminal and run the
|
|||
### Install MySQL ( optional )
|
||||
Skip this step if you do not want to connect to MySQL datasources.
|
||||
```bash
|
||||
$ brew install mysql
|
||||
$ brew install mysql
|
||||
```
|
||||
|
||||
2. ## Setup environment variables
|
||||
Create a `.env` file by copying `.env.example`. More information on the variables that can be set is given here: env variable reference
|
||||
```bash
|
||||
$ cp .env.example .env
|
||||
```
|
||||
```
|
||||
|
||||
3. ## Install Ruby on Rails dependencies
|
||||
3. ## Populate the keys in the env file.
|
||||
Run `openssl rand -hex 64` to create secure secrets and use them as the values for `LOCKBOX_MASTER_KEY` and `SECRET_KEY_BASE`.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
$ cat .env
|
||||
TOOLJET_HOST=http://localhost:8082
|
||||
LOCKBOX_MASTER_KEY=c92bcc7f112ffbdd131d1fb6c5005e372b8802f85f6c4586e5a88f57a541382841c8c99e5701b84862e448dd5db846f705321a41bd48a0fed1b58b9596a3877f
|
||||
SECRET_KEY_BASE=4229d5774cfe7f60e75d6b3bf3a1dbb054a696b6d21b6d5de7b73291899797a222265e12c0a8e8d844f83ebacdf9a67ec42584edf1c2b23e1e7813f8a3339041
|
||||
```
|
||||
|
||||
4. ## Install Ruby on Rails dependencies
|
||||
```bash
|
||||
$ bundle
|
||||
```
|
||||
|
||||
4. ## install React dependencies
|
||||
```bash
|
||||
5. ## install React dependencies
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
5. ## Setup Rails server
|
||||
```bash
|
||||
6. ## Setup Rails server
|
||||
```bash
|
||||
$ bundle exec rake db:create
|
||||
$ bundle exec rake db:reset
|
||||
$ bundle exec rails server
|
||||
```
|
||||
|
||||
6. ## Create login credentials
|
||||
7. ## Create login credentials
|
||||
|
||||
1. Open rails console using:
|
||||
1. Open rails console using:
|
||||
|
||||
```bash
|
||||
```bash
|
||||
$ bundle exec rails console
|
||||
```
|
||||
|
||||
2. Create a new organization
|
||||
2. Create a new organization
|
||||
```ruby
|
||||
Organization.create(name: 'Dev')
|
||||
```
|
||||
|
|
@ -88,12 +103,12 @@ Follow these steps to setup and run ToolJet on Mac OS. Open terminal and run the
|
|||
|
||||
4. Add user to the organization as admin
|
||||
```ruby
|
||||
OrganizationUser.create(user: User.first, organization: Organization.first, role: 'admin')
|
||||
OrganizationUser.create(user: User.first, organization: Organization.first, role: 'admin', status: 'active')
|
||||
```
|
||||
|
||||
7. ## Running the React frontend ( Client )
|
||||
```bash
|
||||
8. ## Running the React frontend ( Client )
|
||||
```bash
|
||||
$ cd ./frontend && npm start
|
||||
```
|
||||
|
||||
The client will start running on the port 8082, you can access the client by visiting: [https://localhost:8082](https://localhost:8082 )
|
||||
The client will start running on the port 8082, you can access the client by visiting: [https://localhost:8082](https://localhost:8082)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ Docker compose is the easiest way to setup ToolJet server and client locally.
|
|||
|
||||
## Prerequisites
|
||||
|
||||
Make sure you have the latest version of `docker` and `docker-compose` installed.
|
||||
Make sure you have the latest version of `docker` and `docker-compose` installed.
|
||||
|
||||
[Official docker installation guide](https://docs.docker.com/desktop/)
|
||||
[Official docker installation guide](https://docs.docker.com/desktop/)
|
||||
[Official docker-compose installation guide](https://docs.docker.com/compose/install/)
|
||||
|
||||
We recommend:
|
||||
We recommend:
|
||||
```bash
|
||||
$ docker --version
|
||||
Docker version 19.03.12, build 48a66213fe
|
||||
|
|
@ -20,11 +20,11 @@ $ docker-compose --version
|
|||
docker-compose version 1.26.2, build eefe0d31
|
||||
```
|
||||
|
||||
## Setting up
|
||||
## Setting up
|
||||
|
||||
1. Close the repository
|
||||
```bash
|
||||
$ git clone https://github.com/tooljet/tooljet.git
|
||||
$ git clone https://github.com/tooljet/tooljet.git
|
||||
```
|
||||
|
||||
2. Create a `.env` file by copying `.env.example`. More information on the variables that can be set is given here: env variable reference
|
||||
|
|
@ -32,9 +32,19 @@ $ git clone https://github.com/tooljet/tooljet.git
|
|||
$ cp .env.example .env
|
||||
```
|
||||
|
||||
3. Build docker images
|
||||
3. Populate the keys in the `.env` file. Run `openssl rand -hex 64` to create secure secrets and use them as the values for `LOCKBOX_MASTER_KEY` and `SECRET_KEY_BASE`.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
$ docker-compose build
|
||||
$ cat .env
|
||||
TOOLJET_HOST=http://localhost:8082
|
||||
LOCKBOX_MASTER_KEY=c92bcc7f112ffbdd131d1fb6c5005e372b8802f85f6c4586e5a88f57a541382841c8c99e5701b84862e448dd5db846f705321a41bd48a0fed1b58b9596a3877f
|
||||
SECRET_KEY_BASE=4229d5774cfe7f60e75d6b3bf3a1dbb054a696b6d21b6d5de7b73291899797a222265e12c0a8e8d844f83ebacdf9a67ec42584edf1c2b23e1e7813f8a3339041
|
||||
```
|
||||
|
||||
4. Build docker images
|
||||
```bash
|
||||
$ docker-compose build
|
||||
```
|
||||
|
||||
4. ToolJet server is built using Ruby on Rails. You have to reset the database if building for the first time.
|
||||
|
|
@ -47,51 +57,29 @@ $ docker-compose run server rails db:reset
|
|||
$ docker-compose up
|
||||
```
|
||||
|
||||
6. Creating login credentials
|
||||
|
||||
1. Open rails console using:
|
||||
|
||||
```bash
|
||||
$ docker-compose run server rails console
|
||||
```
|
||||
|
||||
2. Create a new organization
|
||||
```ruby
|
||||
Organization.create(name: 'Dev')
|
||||
```
|
||||
|
||||
3. Create a new user
|
||||
```ruby
|
||||
User.create(first_name: 'dev', email: 'dev@tooljet.io', password: 'password', organization: Organization.first)
|
||||
```
|
||||
|
||||
4. Add user to the organization as admin
|
||||
```ruby
|
||||
OrganizationUser.create(user: User.first, organization: Organization.first, role: 'admin')
|
||||
```
|
||||
6. The app should now be served locally at http://localhost:8082/. You can login using the default user created.
|
||||
[ email: dev@tooljet.io
|
||||
password: password
|
||||
]
|
||||
|
||||
7. To shut down the containers,
|
||||
```bash
|
||||
$ docker-compose down
|
||||
$ docker-compose stop
|
||||
```
|
||||
|
||||
## Running Rails tests
|
||||
## Running Rails tests
|
||||
|
||||
To run all the tests
|
||||
To run all the tests
|
||||
|
||||
```bash
|
||||
$ docker-compose run server rails test
|
||||
```bash
|
||||
$ docker-compose run server rails test
|
||||
```
|
||||
|
||||
To run a specific test
|
||||
```bash
|
||||
To run a specific test
|
||||
```bash
|
||||
$ docker-compose run server rails test <path-to-file>:<line:number>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If there is any change to dockerfiles, Gemfile or package.json, rebuild the images using:
|
||||
|
||||
```bash
|
||||
$ docker-compose up --build
|
||||
```
|
||||
Please open a new issue at https://github.com/ToolJet/ToolJet/issues or join our slack channel (https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg) if you encounter any issues when trying to run ToolJet locally.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Follow these steps to setup and run ToolJet on Ubuntu. Open terminal and run the
|
|||
$ sudo apt-get install rvm
|
||||
```
|
||||
|
||||
### Install Ruby using RVM
|
||||
### Install Ruby using RVM
|
||||
```bash
|
||||
$ rvm install ruby-2.7.3
|
||||
$ rvm use 2.7.3
|
||||
|
|
@ -38,34 +38,46 @@ Follow these steps to setup and run ToolJet on Ubuntu. Open terminal and run the
|
|||
Create a `.env` file by copying `.env.example`. More information on the variables that can be set is given here: env variable reference
|
||||
```bash
|
||||
$ cp .env.example .env
|
||||
```
|
||||
```
|
||||
|
||||
3. ## Install Ruby on Rails dependencies
|
||||
|
||||
3. ## Populate the keys in the env file.
|
||||
Run `openssl rand -hex 64` to create secure secrets and use them as the values for `LOCKBOX_MASTER_KEY` and `SECRET_KEY_BASE`.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
$ cat .env
|
||||
TOOLJET_HOST=http://localhost:8082
|
||||
LOCKBOX_MASTER_KEY=c92bcc7f112ffbdd131d1fb6c5005e372b8802f85f6c4586e5a88f57a541382841c8c99e5701b84862e448dd5db846f705321a41bd48a0fed1b58b9596a3877f
|
||||
SECRET_KEY_BASE=4229d5774cfe7f60e75d6b3bf3a1dbb054a696b6d21b6d5de7b73291899797a222265e12c0a8e8d844f83ebacdf9a67ec42584edf1c2b23e1e7813f8a3339041
|
||||
```
|
||||
|
||||
4. ## Install Ruby on Rails dependencies
|
||||
```bash
|
||||
$ bundle
|
||||
```
|
||||
|
||||
4. ## install React dependencies
|
||||
```bash
|
||||
5. ## install React dependencies
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
5. ## Setup Rails server
|
||||
```bash
|
||||
6. ## Setup Rails server
|
||||
```bash
|
||||
$ bundle exec rake db:create
|
||||
$ bundle exec rake db:reset
|
||||
$ bundle exec rails server
|
||||
```
|
||||
|
||||
6. ## Create login credentials
|
||||
7. ## Create login credentials
|
||||
|
||||
1. Open rails console using:
|
||||
1. Open rails console using:
|
||||
|
||||
```bash
|
||||
```bash
|
||||
$ bundle exec rails console
|
||||
```
|
||||
|
||||
2. Create a new organization
|
||||
2. Create a new organization
|
||||
```ruby
|
||||
Organization.create(name: 'Dev')
|
||||
```
|
||||
|
|
@ -77,12 +89,12 @@ Follow these steps to setup and run ToolJet on Ubuntu. Open terminal and run the
|
|||
|
||||
4. Add user to the organization as admin
|
||||
```ruby
|
||||
OrganizationUser.create(user: User.first, organization: Organization.first, role: 'admin')
|
||||
OrganizationUser.create(user: User.first, organization: Organization.first, role: 'admin', status: 'active')
|
||||
```
|
||||
|
||||
7. ## Running the React frontend ( Client )
|
||||
```bash
|
||||
8. ## Running the React frontend ( Client )
|
||||
```bash
|
||||
$ cd ./frontend && npm start
|
||||
```
|
||||
|
||||
The client will start running on the port 8082, you can access the client by visiting: [https://localhost:8082](https://localhost:8082 )
|
||||
The client will start running on the port 8082, you can access the client by visiting: [https://localhost:8082](https://localhost:8082)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 24 KiB |
|
|
@ -278,7 +278,7 @@ export function Table({
|
|||
onBlur={(e) => {
|
||||
handleCellValueChange(cell.row.index, column.key || column.name, e.target.value, cell.row.original);
|
||||
}}
|
||||
value={cellValue}
|
||||
defaultValue={cellValue}
|
||||
>
|
||||
</textarea>;
|
||||
} if (columnType === 'dropdown') {
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ class DataSourceManager extends React.Component {
|
|||
{selectedDataSource && (
|
||||
<div className="row">
|
||||
<img
|
||||
src={`/assets/images/icons/editor/datasources/${dataSourceMeta.name.toLowerCase()}.svg`}
|
||||
src={`/assets/images/icons/editor/datasources/${dataSourceMeta.kind.toLowerCase()}.svg`}
|
||||
style={{ objectFit: 'contain' }}
|
||||
height="25"
|
||||
width="25"
|
||||
|
|
@ -260,7 +260,7 @@ class DataSourceManager extends React.Component {
|
|||
<div className="col-auto">
|
||||
<Button className={`m-2 ${isSaving ? 'btn-loading' : ''}`} disabled={isSaving} variant="primary" onClick={this.createDataSource}>
|
||||
{'Save'}
|
||||
</Button>
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
</Modal.Footer>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,22 @@ export const dataBaseSources = [
|
|||
password: { type: 'string', encrypted: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'SQL Server',
|
||||
kind: 'mssql',
|
||||
exposedVariables: {
|
||||
isLoading: {},
|
||||
data: {},
|
||||
rawData: {}
|
||||
},
|
||||
options: {
|
||||
host: { type: 'string' },
|
||||
port: { type: 'string' },
|
||||
database: { type: 'string' },
|
||||
username: { type: 'string' },
|
||||
password: { type: 'string', encrypted: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'MongoDB',
|
||||
kind: 'mongodb',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ export const defaultOptions = {
|
|||
username: { value: '' },
|
||||
password: { value: '' }
|
||||
},
|
||||
mssql: {
|
||||
host: { value: 'localhost' },
|
||||
port: { value: 1433 },
|
||||
database: { value: '' },
|
||||
username: { value: '' },
|
||||
password: { value: '' }
|
||||
},
|
||||
redis: {
|
||||
host: { value: 'localhost' },
|
||||
port: { value: 6379 },
|
||||
|
|
@ -28,7 +35,7 @@ export const defaultOptions = {
|
|||
connection_type: { value: 'manual' },
|
||||
connection_string: { value: ''}
|
||||
},
|
||||
|
||||
|
||||
elasticsearch: {
|
||||
scheme: { value: 'https' },
|
||||
host: { value: 'localhost' },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
import React from 'react';
|
||||
|
||||
export const Mssql = ({
|
||||
optionchanged, options
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="row">
|
||||
<div className="col-md-9">
|
||||
<label className="form-label">Host</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
onChange={(e) => optionchanged('host', e.target.value)}
|
||||
value={options.host.value}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<label className="form-label">Port</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
onChange={(e) => optionchanged('port', e.target.value)}
|
||||
value={options.port.value}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mt-3">
|
||||
<div className="col-md-4">
|
||||
<label className="form-label">Database Name</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
onChange={(e) => optionchanged('database', e.target.value)}
|
||||
value={options.database.value}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
onChange={(e) => optionchanged('username', e.target.value)}
|
||||
value={options.username.value}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label">
|
||||
Password
|
||||
<small className="text-green mx-2">
|
||||
<img className="mx-2 encrypted-icon encrypted-icon" src="/assets/images/icons/padlock.svg" width="12" height="12" />
|
||||
<span className="pt-2">Encrypted</span>
|
||||
</small>
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
className="form-control"
|
||||
onChange={(e) => optionchanged('password', e.target.value)}
|
||||
value={options.password.value}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row mt-3">
|
||||
<div className="col-md-3">
|
||||
<div className="field mb-3">
|
||||
<label className="form-check my-2">
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
defaultChecked={false}
|
||||
onClick={(e) => { optionchanged('azure', e.target.checked) } }
|
||||
/>
|
||||
Azure
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -10,6 +10,7 @@ import { Slack } from './Slack';
|
|||
import { Mongodb } from './Mongodb';
|
||||
import { Dynamodb } from './Dynamodb';
|
||||
import { Airtable } from './Airtable';
|
||||
import { Mssql } from './Mssql';
|
||||
|
||||
export const SourceComponents = {
|
||||
Elasticsearch,
|
||||
|
|
@ -23,5 +24,6 @@ export const SourceComponents = {
|
|||
Slack,
|
||||
Mongodb,
|
||||
Dynamodb,
|
||||
Airtable
|
||||
Airtable,
|
||||
Mssql
|
||||
};
|
||||
|
|
|
|||
|
|
@ -230,6 +230,16 @@ class Editor extends React.Component {
|
|||
this.computeComponentState(newDefinition.components);
|
||||
};
|
||||
|
||||
handleInspectorView = (component) => {
|
||||
if (this.state.selectedComponent.hasOwnProperty('component')) {
|
||||
const { id: selectedComponentId } = this.state.selectedComponent;
|
||||
if (selectedComponentId === component.id) {
|
||||
this.setState({selectedComponent: null})
|
||||
this.switchSidebarTab(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeComponent = (component) => {
|
||||
let newDefinition = this.state.appDefinition;
|
||||
|
||||
|
|
@ -241,7 +251,7 @@ class Editor extends React.Component {
|
|||
|
||||
delete newDefinition.components[component.id];
|
||||
this.appDefinitionChanged(newDefinition);
|
||||
this.switchSidebarTab(2);
|
||||
this.handleInspectorView(component);
|
||||
};
|
||||
|
||||
componentDefinitionChanged = (newDefinition) => {
|
||||
|
|
|
|||
|
|
@ -93,13 +93,11 @@ export const EventSelector = ({
|
|||
{definition.actionId === 'show-alert' && (
|
||||
<div className="p-1">
|
||||
<label className="form-label mt-1">Message</label>
|
||||
<input
|
||||
onBlur={(e) => eventOptionUpdated(param, 'message', e.target.value, extraData)}
|
||||
value={message}
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="Text goes here"
|
||||
<CodeHinter
|
||||
currentState={currentState}
|
||||
onChange={(value) => eventOptionUpdated(param, 'message', value, extraData)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
|
|||
import Popover from 'react-bootstrap/Popover';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import { toast } from 'react-toastify';
|
||||
import { validateQueryName } from '@/_helpers/utils';
|
||||
import { validateQueryName, convertToKebabCase } from '@/_helpers/utils';
|
||||
|
||||
export const Inspector = ({
|
||||
selectedComponentId,
|
||||
|
|
@ -244,7 +244,7 @@ export const Inspector = ({
|
|||
</div>
|
||||
|
||||
<div className="widget-documentation-link p-2">
|
||||
<a href={`https://docs.tooljet.io/docs/widgets/${componentMeta.name.toLowerCase()}`} target="_blank">
|
||||
<a href={`https://docs.tooljet.io/docs/widgets/${convertToKebabCase(componentMeta?.name ?? '')}`} target="_blank">
|
||||
<small>
|
||||
{componentMeta.name} documentation
|
||||
</small>
|
||||
|
|
|
|||
41
frontend/src/Editor/QueryManager/QueryEditors/Mssql.jsx
Normal file
41
frontend/src/Editor/QueryManager/QueryEditors/Mssql.jsx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react';
|
||||
import { CodeHinter } from '../../CodeBuilder/CodeHinter';
|
||||
import { changeOption } from './utils';
|
||||
|
||||
class Mssql extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
options: this.props.options
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { options } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{options && (
|
||||
<div className="mb-3 mt-2">
|
||||
<CodeHinter
|
||||
currentState={this.props.currentState}
|
||||
initialValue={options.query}
|
||||
mode="sql"
|
||||
theme="duotone-light"
|
||||
lineNumbers={true}
|
||||
className="query-hinter"
|
||||
onChange={(value) => changeOption(this, 'query', value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { Mssql };
|
||||
|
|
@ -10,6 +10,7 @@ import { Slack } from './Slack';
|
|||
import { Mongodb } from './Mongodb';
|
||||
import { Dynamodb } from './Dynamodb';
|
||||
import { Airtable } from './Airtable';
|
||||
import { Mssql } from './Mssql';
|
||||
|
||||
export const allSources = {
|
||||
Restapi,
|
||||
|
|
@ -23,5 +24,6 @@ export const allSources = {
|
|||
Slack,
|
||||
Mongodb,
|
||||
Dynamodb,
|
||||
Airtable
|
||||
Airtable,
|
||||
Mssql
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,5 +32,8 @@ export const defaultOptions = {
|
|||
},
|
||||
airtable: {
|
||||
|
||||
},
|
||||
mssql: {
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ async function copyToClipboard(text) {
|
|||
function executeAction(_ref, event) {
|
||||
if (event) {
|
||||
if (event.actionId === 'show-alert') {
|
||||
toast(event.options.message, { hideProgressBar: true });
|
||||
const message = resolveReferences(event.options.message, _ref.state.currentState);
|
||||
toast(message, { hideProgressBar: true });
|
||||
}
|
||||
|
||||
if (event.actionId === 'open-webpage') {
|
||||
|
|
|
|||
|
|
@ -129,3 +129,6 @@ export function validateQueryName(name){
|
|||
const nameRegex = new RegExp('^[A-Za-z0-9_-]*$');
|
||||
return nameRegex.test(name);
|
||||
};
|
||||
|
||||
|
||||
export const convertToKebabCase = string => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase()
|
||||
|
|
|
|||
Loading…
Reference in a new issue