console: unique filenames for exported metadata (close #1772) (#4106)

Generate metadata filenames such as: hasura_metadata_2020_03_13_18_10_31_711.json
This commit is contained in:
Rikin Kachhia 2020-03-18 20:27:18 +05:30 committed by GitHub
parent e93179fae0
commit 3c6e1a39e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 43 deletions

View File

@ -6,20 +6,23 @@
- Introducing Actions: https://docs.hasura.io/1.0/graphql/manual/actions/index.html
- Downgrade command: https://hasura.io/docs/1.0/graphql/manual/deployment/downgrading.html#downgrading-hasura-graphql-engine
- console: add multi select to data table and bulk delete (#3735)
Added a checkbox to each row on Browse Rows view that allows selecting one or more rows from the table and bulk delete them.
- console: add multi select in browse rows to allow bulk delete (close #1739) (#3735)
Adds a checkbox to each row on Browse Rows view that allows selecting one or more rows from the table and bulk delete them.
- console: allow setting check constraints during table create (#3881)
Added a component that allows adding check constraints while creating a new table in the same way as it can be done on the `Modify` view.
Adds a component that allows adding check constraints while creating a new table in the same way as it can be done on the `Modify` view.
### Select dropdown for Enum columns (console)
- console: add dropdown for enum fields in insert/edit rows page (close #3748) (#3810)
If a table has a field referencing an Enum table via a foreign key, then there will be a select dropdown with all possible enum values on `Insert Row` and `Edit Row` views on the Console.
(close #3748) (#3810)
If a table has a field referencing an enum table via a foreign key, then there will be a select dropdown with all possible enum values for that field on `Insert Row` and `Edit Row` views.
- console: generate unique exported metadata filenames (close #1772) (#4106)
Exporting metadata from the console will now generate metadata files of the form `hasura_metadata_<timestamp>.json`.
### Other changes
- console: disable editing action relationships
@ -85,4 +88,4 @@
- auto-include `__typename` field in custom types' objects (fix #4063)
- squash some potential space leaks (#3937)
- docs: bump MarupSafe version (#4102)
- console: add design system base components (#3866)
- console: add design system base components (#3866)

View File

@ -242,6 +242,45 @@ export const getFileExtensionFromFilename = filename => {
return filename.match(/\.[0-9a-z]+$/i)[0];
};
// return time in format YYYY_MM_DD_hh_mm_ss_s
export const getCurrTimeForFileName = () => {
const currTime = new Date();
const year = currTime
.getFullYear()
.toString()
.padStart(4, '0');
const month = (currTime.getMonth() + 1).toString().padStart(2, '0');
const day = currTime
.getDate()
.toString()
.padStart(2, '0');
const hours = currTime
.getHours()
.toString()
.padStart(2, '0');
const minutes = currTime
.getMinutes()
.toString()
.padStart(2, '0');
const seconds = currTime
.getSeconds()
.toString()
.padStart(2, '0');
const milliSeconds = currTime
.getMilliseconds()
.toString()
.padStart(3, '0');
return [year, month, day, hours, minutes, seconds, milliSeconds].join('_');
};
export const isValidTemplateLiteral = literal_ => {
const literal = literal_.trim();
if (!literal) return false;

View File

@ -99,9 +99,7 @@ const Login = ({ dispatch }) => {
type="checkbox"
checked={shouldPersist}
onChange={toggleShouldPersist}
className={`${styles.add_mar_right_small} ${
styles.remove_margin_top
} ${styles.cursorPointer}`}
className={`${styles.add_mar_right_small} ${styles.remove_margin_top} ${styles.cursorPointer}`}
/>
Remember in this browser
</label>

View File

@ -191,17 +191,17 @@ const RelationshipEditor = ({
disabled={!name}
>
{// default unselected option
refSchema === '' && (
<option value={''} disabled>
{'-- reference schema --'}
</option>
)}
refSchema === '' && (
<option value={''} disabled>
{'-- reference schema --'}
</option>
)}
{// all reference schema options
orderedSchemaList.map((rs, j) => (
<option key={j} value={rs}>
{rs}
</option>
))}
orderedSchemaList.map((rs, j) => (
<option key={j} value={rs}>
{rs}
</option>
))}
</select>
</div>
);

View File

@ -204,9 +204,7 @@ const deleteRelMigrate = relMeta => (dispatch, getState) => {
const relChangesDown = [upQuery];
// Apply migrations
const migrationName = `drop_relationship_${relMeta.relName}_${
relMeta.lSchema
}_table_${relMeta.lTable}`;
const migrationName = `drop_relationship_${relMeta.relName}_${relMeta.lSchema}_table_${relMeta.lTable}`;
const requestMsg = 'Deleting Relationship...';
const successMsg = 'Relationship deleted';
@ -250,9 +248,7 @@ const addRelNewFromStateMigrate = () => (dispatch, getState) => {
const relChangesDown = [downQuery];
// Apply migrations
const migrationName = `add_relationship_${state.name}_table_${
state.lSchema
}_${state.lTable}`;
const migrationName = `add_relationship_${state.name}_table_${state.lSchema}_${state.lTable}`;
const requestMsg = 'Adding Relationship...';
const successMsg = 'Relationship created';
@ -568,9 +564,7 @@ const autoAddRelName = obj => (dispatch, getState) => {
const relChangesDown = [obj.downQuery];
// Apply migrations
const migrationName = `add_relationship_${relName}_table_${currentSchema}_${
obj.data.tableName
}`;
const migrationName = `add_relationship_${relName}_table_${currentSchema}_${obj.data.tableName}`;
const requestMsg = 'Adding Relationship...';
const successMsg = 'Relationship created';

View File

@ -6,9 +6,7 @@ const Logout = props => {
return (
<div
className={`${styles.clear_fix} ${styles.padd_left} ${styles.padd_top} ${
styles.metadata_wrapper
} container-fluid`}
className={`${styles.clear_fix} ${styles.padd_left} ${styles.padd_top} ${styles.metadata_wrapper} container-fluid`}
>
<div className={styles.subHeader}>
<h2 className={`${styles.heading_text} ${styles.remove_pad_bottom}`}>

View File

@ -7,7 +7,10 @@ import {
showErrorNotification,
} from '../../Common/Notification';
import { exportMetadata } from '../Actions';
import { downloadObjectAsJsonFile } from '../../../Common/utils/jsUtils';
import {
downloadObjectAsJsonFile,
getCurrTimeForFileName,
} from '../../../Common/utils/jsUtils';
class ExportMetadata extends Component {
constructor() {
@ -31,11 +34,19 @@ class ExportMetadata extends Component {
this.setState({ isExporting: true });
const successCallback = data => {
downloadObjectAsJsonFile('metadata', data);
const fileName =
'hasura_metadata_' + getCurrTimeForFileName() + '.json';
downloadObjectAsJsonFile(fileName, data);
this.setState({ isExporting: false });
dispatch(showSuccessNotification('Metadata exported successfully!'));
dispatch(
showSuccessNotification(
'Metadata exported successfully!',
`Metadata file "${fileName}"`
)
);
};
const errorCallback = error => {

View File

@ -34,7 +34,7 @@ Exporting Hasura metadata
1. Click on the settings (⚙) icon at the top right corner of the console screen.
2. In the Hasura metadata actions page that opens, click on the ``Export Metadata`` button.
3. This will prompt a file download for ``metadata.json``. Save the file.
3. This will prompt a file download for ``hasura_metadata_<timestamp>.json``. Save the file.
.. tab:: API
@ -45,9 +45,9 @@ Exporting Hasura metadata
.. code-block:: bash
curl -d'{"type": "export_metadata", "args": {}}' http://localhost:8080/v1/query -o metadata.json
curl -d'{"type": "export_metadata", "args": {}}' http://localhost:8080/v1/query -o hasura_metadata.json
This command will create a ``metadata.json`` file.
This command will create a ``hasura_metadata.json`` file.
If an admin secret is set, add ``-H 'X-Hasura-Admin-Secret: <your-admin-secret>'`` as the API is an
admin-only API.
@ -67,7 +67,7 @@ before.
1. Click on the settings (⚙) icon at the top right corner of the console screen.
2. Click on ``Import Metadata`` button.
3. Choose a ``metadata.json`` file that was exported earlier.
3. Choose a ``hasura_metadata.json`` file that was exported earlier.
4. A notification should appear indicating the success or error.
.. tab:: API
@ -78,9 +78,9 @@ before.
.. code-block:: bash
curl -d'{"type":"replace_metadata", "args":'$(cat metadata.json)'}' http://localhost:8080/v1/query
curl -d'{"type":"replace_metadata", "args":'$(cat hasura_metadata.json)'}' http://localhost:8080/v1/query
This command reads the ``metadata.json`` file and makes a POST request to
This command reads the ``hasura_metadata.json`` file and makes a POST request to
replace the metadata.
If an admin secret is set, add ``-H 'X-Hasura-Admin-Secret: <your-admin-secret>'`` as the API is an
admin-only API.

View File

@ -33,7 +33,7 @@ data. One thing to note is that all the Postgres resources the metadata refers
to should already exist when the import happens, otherwise Hasura will throw an
error.
To understand the format of the ``metadata.json`` file, refer to :ref:`metadata_file_format`.
To understand the format of the ``hasura_metadata.json`` file, refer to :ref:`metadata_file_format`.
For more details on how to import and export metadata, refer to :ref:`manage_hasura_metadata`.