这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 73 additions & 47 deletions console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Feel free to open pull requests to address these issues or to add/fix console f
- [Hasura GraphQL Engine](https://docs.hasura.io/1.0/graphql/manual/getting-started/index.html)
- [Hasura CLI](https://docs.hasura.io/1.0/graphql/manual/hasura-cli/install-hasura-cli.html) (for working with migrations)

### Setup and Install Dependencies
### Set up and install dependencies

- Fork the repo on GitHub.
- Clone your forked repo: `git clone https://github.com/<your-username>/graphql-engine`
Expand All @@ -40,88 +40,114 @@ cd console
npm install
```

Hasura console can be developed in two modes (`server` or `cli` mode). Both modes require a running instance of GraphQL Engine. The easiest way to get Hasura GraphQL engine instance is by Heroku. You can get it by following the steps given in [this](https://docs.hasura.io/1.0/graphql/manual/getting-started/heroku-simple.html) link. Other methods to install Hasura GraphQL engine are documented [here](https://docs.hasura.io/1.0/graphql/manual/getting-started/index.html).
### Run console development server

### Development with Hasura GraphQL Engine (`server` mode)
Hasura console can be developed in two modes, `server` or `cli` mode. If you are looking to add/tweak functionality related to migrations, check out [Development with Hasura CLI](#development-with-hasura-cli-cli-mode), otherwise check out [Development with Hasura GraphQL engine](#development-with-hasura-graphql-engine-server-mode).

Hasura GraphQL engine should be running to develop console in this mode. If you have set it up on Heroku, your url will look like `<app-name>.herokuapp.com`, if it's on your local machine, it's probably `http://localhost:8080`.
Both modes require a running instance of GraphQL Engine. The easiest way to get Hasura GraphQL engine instance is by Heroku. You can get it by following the steps given in [this](https://docs.hasura.io/1.0/graphql/manual/getting-started/heroku-simple.html) link. Other methods to install Hasura GraphQL engine are documented [here](https://docs.hasura.io/1.0/graphql/manual/getting-started/index.html).

[Dotenv](https://github.com/motdotla/dotenv) is used for setting environment variables for development. Create a `.env` file in the root directory for console (wherever package.json is). Here's a `.env` file with some environment variable examples :
[Dotenv](https://github.com/motdotla/dotenv) is used for setting environment variables for development. In production, these environment variables are templated by the server or CLI.

#### Develop with Hasura GraphQL engine (`server` mode)

In server mode, **migrations** will be disabled and the corresponding functionality on the console will be hidden.

##### Set up `.env` file
Environment variables accepted in `server` mode:

- `NODE_ENV`: Console build environment (`development`/`production`)
- `PORT`: The port where Hasura console will run locally
- `CDN_ASSETS`: Should assets be loaded from CDN (`true`/`false`)
- `ASSETS_PATH`: Path to console assets
- `ASSETS_VERSION`: Version of console assets being served
- `ENABLE_TELEMETRY`: Whether to enable telemetry (`true`/`false`)
- `URL_PREFIX`: Path at which the console is running
- `DATA_API_URL`: The Hasura GraphQL engine url. (If you are running it on Heroku, it will look like <app-name>.herokuapp.com, if you are running locally, it will look like http://localhost:<port>)
- `SERVER_VERSION`: Hasura GraphQL Engine server version
- `CONSOLE_MODE`: In server mode, it should be `server`
- `IS_ADMIN_SECRET_SET`: Is GraphQl engine configured with an admin secret (`true`/`false`)

Here's an example `.env` file for `server` mode:

```bash
PORT=3000
NODE_ENV=development
DATA_API_URL=http://localhost:8080
ADMIN_SECRET=xyz
IS_ADMIN_SECRET_SET=true
CONSOLE_MODE=server
URL_PREFIX=/
PORT=3000
CDN_ASSETS=true
ASSETS_PATH=https://graphql-engine-cdn.hasura.io/console/assets
ASSETS_VERSION=channel/beta/v1.0
CDN_ASSETS=true
ENABLE_TELEMETRY=true
URL_PREFIX=/
DATA_API_URL=http://localhost:8080
SERVER_VERSION=v1.0.0-beta.6
CONSOLE_MODE=server
IS_ADMIN_SECRET_SET=true
```

Note that `CONSOLE_MODE` is set to `server`. In this mode, **migrations** will be disabled and the corresponding functionality on the console will be hidden. If you are looking to add/tweak functionality related to migrations, check out [Development with Hasura CLI](#development-with-hasura-cli-cli-mode).
> The server also templates `consolePath` in `window.__env` which is the relative path of the current page (something like `/console/data/schema/public`). Using this path, the console determines the DATA_API_URL in production. You do not need to worry about this in development since you are hardcoding the value of DATA_API_URL in `.env`.

Environment variables accepted in `server` mode:

1. `PORT`: Configure the port where Hasura console will run locally.
2. `NODE_ENV`: `development`
3. `DATA_API_URL`: Configure it with the Hasura GraphQL Engine url. If you are running it on Heroku, your url will look like `<app-name>.herokuapp.com`
4. `ADMIN_SECRET`: Set admin secret if Hasura GraphQL engine is configured to run with ADMIN_SECRET.
5. `CONSOLE_MODE`: `server`
6. `URL_PREFIX`: `/` (forward slash)

> The server also templates `consolePath` in `window.__env` which is the relative path of the current page (something like `/console/data/schema/public`). Using this path, the console determines the DATA_API_URL. You do not need to worry about this in development since you are hardcoding the value of DATA_API_URL in `.env`.

#### Run Development Server:
##### Run console development server:

```bash
npm run dev
```

### Development with Hasura CLI (`cli` mode)
#### Develop with Hasura CLI (`cli` mode)

Configure .env file with appropriate values for the required environment variables, such as the examples below:
##### Set up `.env` file

Environment variables accepted in `cli` mode:

- `NODE_ENV`: Console build environment (`development`/`production`)
- `PORT`: The port where Hasura console will run locally
- `API_HOST`: Hasura CLI host. Hasura CLI runs on `http://localhost` by default.
- `API_PORT`: Hasura CLI port. Hasura CLI exposes the API at `9693` by default
- `CDN_ASSETS`: Should assets be loaded from CDN (`true`/`false`)
- `ASSETS_PATH`: Path to console assets
- `ASSETS_VERSION`: Version of console assets being served
- `ENABLE_TELEMETRY`: Whether to enable telemetry (`true`/`false`)
- `URL_PREFIX`: Path at which the console is running
- `DATA_API_URL`: The Hasura GraphQL engine url. (If you are running it on Heroku, it will look like <app-name>.herokuapp.com, if you are running locally, it will look like http://localhost:<port>)
- `SERVER_VERSION`: Hasura GraphQL Engine server version
- `CONSOLE_MODE`: In cli mode, it should be `cli`
- `ADMIN_SECRET`: the admin secret passed via the CLI

Here's an example `.env` file for `cli` mode:

```bash
PORT=3000
NODE_ENV=development
DATA_API_URL=http://localhost:8080
PORT=3000
API_HOST=http://localhost
API_PORT=9693
ADMIN_SECRET=xyz
CONSOLE_MODE=cli
CDN_ASSETS=true
ASSETS_PATH=https://graphql-engine-cdn.hasura.io/console/assets
ASSETS_VERSION=channel/beta/v1.0
ENABLE_TELEMETRY=true
URL_PREFIX=/
DATA_API_URL=http://localhost:8080
SERVER_VERSION=v1.0.0-beta.6
CONSOLE_MODE=cli
ADMIN_SECRET=my-admin-secret
```
Environment variables accepted in `cli` mode:

1. `PORT`: Configure the port where Hasura console will run locally.
2. `NODE_ENV`: `development`
3. `DATA_API_URL`: Configure it with the Hasura GraphQL Engine url. If you are running it on Heroku. Your url will look like <app-name>.herokuapp.com
4. `API_HOST`: Hasura CLI host. Hasura CLI runs on `http://localhost` by default.
5. `API_PORT`: Hasura CLI port. Hasura CLI exposes the API at `9693` by default
6. `ADMIN_SECRET`: Set admin secret if Hasura GraphQL engine is configured to run with ADMIN_SECRET
7. `CONSOLE_MODE`: `cli`
8. `URL_PREFIX`: ‘/’ (forward slash)
##### Run console development server:

#### Run Development Server:
This setup requires a Hasura CLI console server to be running.

This setup requires hasura cli to be running in a different window. Start hasura cli with the same Hasura GraphQL engine url as configured for `DATA_API_URL`.
###### Start Hasura CLI console server

##### Start Hasura CLI server
Start Hasura CLI console with the same Hasura GraphQL engine url as configured for `DATA_API_URL`.

```bash
hasura console
hasura console --endpoint <DATA_API_URL> --admin-secret <your-admin-secret> (optional)
```

##### Start development server
###### Start development console server

```bash
npm run dev
```

### Checkout the console
### Check out the console

Visit [http://localhost:3000](http://localhost:3000) to confirm the setup.

Expand All @@ -140,7 +166,7 @@ It should automatically connect to the Redux store when started in development m
By default [redux-logger](https://www.npmjs.com/package/redux-logger) is enabled to assist in development.
You can disable it if you wish by commenting out the `createLogger` line in `src/client.js`

### Run Tests
### Run tests

- Run tests: `npm run cypress`
- Write your tests in the `cypress` directory, integration.
Expand Down
27 changes: 15 additions & 12 deletions console/src/Globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SERVER_CONSOLE_MODE } from './constants';
import { getFeaturesCompatibility } from './helpers/versionUtils';
import { stripTrailingSlash } from './components/Common/utils/urlUtils';

// TODO: move this section to a more appropriate location
/* set helper tools into window */

import sqlFormatter from './helpers/sql-formatter.min';
Expand All @@ -19,19 +20,19 @@ if (

/* initialize globals */

const isProduction = window.__env.nodeEnv === 'production';

const globals = {
apiHost: window.__env.apiHost,
apiPort: window.__env.apiPort,
dataApiUrl: stripTrailingSlash(window.__env.dataApiUrl),
devDataApiUrl: window.__env.devDataApiUrl,
nodeEnv: window.__env.nodeEnv,
adminSecret: window.__env.adminSecret || null, // will be updated after login/logout
isAdminSecretSet: window.__env.isAdminSecretSet || false,
dataApiUrl: stripTrailingSlash(window.__env.dataApiUrl), // overridden below if server mode
urlPrefix: stripTrailingSlash(window.__env.urlPrefix || '/'), // overridden below if server mode in production
adminSecret: window.__env.adminSecret || null, // gets updated after login/logout in server mode
isAdminSecretSet:
window.__env.isAdminSecretSet || window.__env.adminSecret || false,
consoleMode: window.__env.consoleMode || SERVER_CONSOLE_MODE,
urlPrefix: stripTrailingSlash(window.__env.urlPrefix) || '',
enableTelemetry: window.__env.enableTelemetry,
telemetryTopic:
window.__env.nodeEnv !== 'development' ? 'console' : 'console_test',
telemetryTopic: isProduction ? 'console' : 'console_test',
assetsPath: window.__env.assetsPath,
serverVersion: window.__env.serverVersion,
consoleAssetVersion: CONSOLE_ASSET_VERSION, // set during console build
Expand All @@ -41,22 +42,24 @@ const globals = {
};

if (globals.consoleMode === SERVER_CONSOLE_MODE) {
if (globals.nodeEnv !== 'development') {
if (isProduction) {
const consolePath = window.__env.consolePath;
if (consolePath) {
const currentUrl = stripTrailingSlash(window.location.href);
const currentPath = stripTrailingSlash(window.location.pathname);

globals.dataApiUrl = currentUrl.slice(
0,
currentUrl.lastIndexOf(consolePath)
);

const currentPath = stripTrailingSlash(window.location.pathname);
globals.urlPrefix =
currentPath.slice(0, currentPath.lastIndexOf(consolePath)) + '/console';
} else {
const windowUrl = window.location.protocol + '//' + window.location.host;
const windowHostUrl =
window.location.protocol + '//' + window.location.host;

globals.dataApiUrl = windowUrl;
globals.dataApiUrl = windowHostUrl;
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion console/src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ class App extends Component {
);
}

if (telemetry.console_opts && !telemetry.console_opts.telemetryNotificationShown) {
if (
telemetry.console_opts &&
!telemetry.console_opts.telemetryNotificationShown
) {
dispatch(showTelemetryNotification());
dispatch(telemetryNotificationShown());
}
Expand Down
2 changes: 1 addition & 1 deletion console/src/components/Main/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class Main extends React.Component {
const getAdminSecretSection = () => {
let adminSecretHtml = null;

if (!(globals.isAdminSecretSet || globals.adminSecret)) {
if (!globals.isAdminSecretSet) {
adminSecretHtml = (
<div className={styles.secureSection}>
<a
Expand Down
4 changes: 2 additions & 2 deletions console/src/components/Services/Settings/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export const dropInconsistentObjects = () => {
};

export const isMetadataStatusPage = () => {
return window.location.pathname.includes('/setting/metadata-status');
return window.location.pathname.includes('/settings/metadata-status');
};

export const redirectToMetadataStatus = () => {
Expand Down Expand Up @@ -535,7 +535,7 @@ export const metadataReducer = (state = defaultState, action) => {
...state,
allowedQueries: [
...state.allowedQueries.map(q =>
(q.name === action.data.queryName ? action.data.newQuery : q)
q.name === action.data.queryName ? action.data.newQuery : q
),
],
};
Expand Down
59 changes: 32 additions & 27 deletions console/src/helpers/localDev.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
let envObj = `
apiHost: '${process.env.API_HOST}',
apiPort: '${process.env.API_PORT}',
dataApiUrl: '${process.env.DATA_API_URL}',
consoleMode: '${process.env.CONSOLE_MODE}',
nodeEnv: '${process.env.NODE_ENV}',
urlPrefix: '${process.env.URL_PREFIX}',
enableTelemetry: ${process.env.ENABLE_TELEMETRY},
assetsPath: '${process.env.ASSETS_PATH}',
assetsVersion: '${process.env.ASSETS_VERSION}',
serverVersion: '${process.env.SERVER_VERSION}',
cdnAssets: ${process.env.CDN_ASSETS},`;
import { CLI_CONSOLE_MODE } from '../constants';

if (process.env.ADMIN_SECRET !== undefined) {
envObj += `
adminSecret: '${process.env.ADMIN_SECRET}',`;
} else {
// ADMIN_SECRET is undefined
if (process.env.IS_ADMIN_SECRET_SET !== undefined) {
envObj += `
isAdminSecretSet: ${process.env.IS_ADMIN_SECRET_SET},`;
}
}
const serverEnvVars = `
dataApiUrl: '${process.env.DATA_API_URL}',
isAdminSecretSet: '${process.env.IS_ADMIN_SECRET_SET}',
consoleMode: '${process.env.CONSOLE_MODE}',
nodeEnv: '${process.env.NODE_ENV}',
serverVersion: '${process.env.SERVER_VERSION}',
urlPrefix: '${process.env.URL_PREFIX}',
consolePath: '${process.env.CONSOLE_PATH}',
enableTelemetry: ${process.env.ENABLE_TELEMETRY},
assetsPath: '${process.env.ASSETS_PATH}',
assetsVersion: '${process.env.ASSETS_VERSION}',
cdnAssets: ${process.env.CDN_ASSETS}
`;

const env = `
window.__env={
${envObj}
};
const cliEnvVars = `
apiPort: '${process.env.API_PORT}',
apiHost: '${process.env.API_HOST}',
dataApiUrl: '${process.env.DATA_API_URL}',
adminSecret: '${process.env.ADMIN_SECRET}',
consoleMode: '${process.env.CONSOLE_MODE}',
nodeEnv: '${process.env.NODE_ENV}',
enableTelemetry: ${process.env.ENABLE_TELEMETRY},
assetsPath: '${process.env.ASSETS_PATH}',
assetsVersion: '${process.env.ASSETS_VERSION}',
serverVersion: '${process.env.SERVER_VERSION}',
cdnAssets: ${process.env.CDN_ASSETS},
`;

export { env };
const envVars =
process.env.CONSOLE_MODE === CLI_CONSOLE_MODE ? cliEnvVars : serverEnvVars;

export const env = `
window.__env = {${envVars}};
`;
3 changes: 2 additions & 1 deletion console/src/telemetry/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Endpoints, { globalCookiePolicy } from '../Endpoints';
import requestAction from '../utils/requestAction';
import dataHeaders from '../components/Services/Data/Common/Headers';
import defaultTelemetryState from './State';
import globals from '../Globals';

const SET_CONSOLE_OPTS = 'Telemetry/SET_CONSOLE_OPTS';
const SET_NOTIFICATION_SHOWN = 'Telemetry/SET_NOTIFICATION_SHOWN';
Expand Down Expand Up @@ -43,7 +44,7 @@ const setNotificationShownInDB = () => (dispatch, getState) => {

const loadConsoleTelemetryOpts = () => {
return (dispatch, getState) => {
if (window.__env.enableTelemetry === undefined) {
if (globals.enableTelemetry === undefined) {
return dispatch({ type: SET_TELEMETRY_DISABLED });
}

Expand Down
2 changes: 1 addition & 1 deletion console/src/utils/validateLogin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CLI_CONSOLE_MODE } from '../constants';
const validateLogin = ({ dispatch }) => {
return (nextState, replaceState, cb) => {
// care about admin secret only if it is set
if (globals.isAdminSecretSet || globals.adminSecret) {
if (globals.isAdminSecretSet) {
const validationSuccessCallback = () => {
if (nextState.location.pathname === '/login') {
replaceState('/');
Expand Down