From c63bd07c37ca4688e5d6475d3a368549cd998b7f Mon Sep 17 00:00:00 2001 From: Stanislaw Adaszewski Date: Thu, 16 Apr 2020 14:18:13 +0200 Subject: [PATCH] Started implementing properties editors - WBCollectionFields for starters. --- frontend/src/css/index.css | 4 ++ .../src/js/arvados/base/wb-update-field.js | 16 +++++ .../src/js/component/wb-collection-fields.js | 71 +++++++++++-------- frontend/src/js/component/wb-json-editor.js | 60 ++++++++++++++++ frontend/src/js/widget/wb-accordion.js | 6 +- frontend/src/js/widget/wb-dialog.js | 13 ++-- 6 files changed, 131 insertions(+), 39 deletions(-) create mode 100644 frontend/src/js/arvados/base/wb-update-field.js create mode 100644 frontend/src/js/component/wb-json-editor.js diff --git a/frontend/src/css/index.css b/frontend/src/css/index.css index d7ab0a9..2c49b82 100755 --- a/frontend/src/css/index.css +++ b/frontend/src/css/index.css @@ -21,3 +21,7 @@ div.wb-json-viewer { font-family: "Courier New", fixed-width; white-space: pre-wrap; } + +textarea.wb-json-editor { + font-family: "Courier New", fixed-width; +} diff --git a/frontend/src/js/arvados/base/wb-update-field.js b/frontend/src/js/arvados/base/wb-update-field.js new file mode 100644 index 0000000..b5c2362 --- /dev/null +++ b/frontend/src/js/arvados/base/wb-update-field.js @@ -0,0 +1,16 @@ +import makeArvadosRequest from 'make-arvados-request'; +import arvadosTypeName from 'arvados-type-name'; + +function wbUpdateField(arvHost, arvToken, uuid, fieldName, fieldValue) { + const typeName = arvadosTypeName(uuid); + const data = {}; + data[fieldName] = fieldValue; + const prom = makeArvadosRequest(arvHost, arvToken, + '/arvados/v1/' + typeName + 's/' + uuid, { + method: 'PUT', + data: JSON.stringify(data) + }); + return prom; +} + +export default wbUpdateField; diff --git a/frontend/src/js/component/wb-collection-fields.js b/frontend/src/js/component/wb-collection-fields.js index d693123..45a7ae0 100644 --- a/frontend/src/js/component/wb-collection-fields.js +++ b/frontend/src/js/component/wb-collection-fields.js @@ -9,18 +9,54 @@ import WBNameAndUuid from 'wb-name-and-uuid'; import WBAccordion from 'wb-accordion'; import wbFormatSpecialValue from 'wb-format-special-value'; import WBJsonViewer from 'wb-json-viewer'; +import WBJsonEditor from 'wb-json-editor'; +import wbUpdateField from 'wb-update-field'; class WBCollectionFields extends Component { componentDidMount() { - this.prepareRows(); + this.fetchData(); } componentWillReceiveProps(nextProps) { this.props = nextProps; - this.prepareRows(); + this.fetchData(); } - prepareRows() { + prepareRows(item) { + const { app } = this.props; + const { arvHost, arvToken } = app.state; + + let rows = [ + [ 'Name', item.name ], + [ 'Description', wbFormatSpecialValue(item.description) ], + [ 'Properties', ( + wbUpdateField(arvHost, arvToken, item.uuid, 'properties', value) + .then(() => { item.properties = value; this.prepareRows(item); }) } /> + ) ], + [ 'Portable Data Hash', item.portable_data_hash ], + [ 'Replication Desired', item.replication_desired ? item.replication_desired : ( + { String(item.replication_desired) } + ) ], + [ 'Replication Confirmed', item.replication_confirmed ? item.replication_confirmed : ( + { String(item.replication_confirmed) } + ) ], + [ 'Replication Confirmed At', wbFormatDate(item.replication_confirmed_at) ], + [ 'Trash At', wbFormatDate(item.trash_at) ], + [ 'Delete At', wbFormatDate(item.delete_at) ], + [ 'Is Trashed', String(item.is_trashed) ], + [ 'Current Version UUID', ( + + ) ], + [ 'Version', item.version ], + [ 'Preserve Version', String(item.preserve_version) ], + [ 'File Count', item.file_count ], + [ 'Total Size', filesize(item.file_size_total) ] + ]; + this.setState({ 'rows': rows }); + } + + fetchData() { let { uuid, app } = this.props; let { arvHost, arvToken } = app.state; @@ -35,34 +71,7 @@ class WBCollectionFields extends Component { const item = xhr.response.items[0]; if (!item) throw Error('Item not found'); - let rows = [ - [ 'Name', item.name ], - [ 'Description', wbFormatSpecialValue(item.description) ], - [ 'Properties', ( - - - - ) ], - [ 'Portable Data Hash', item.portable_data_hash ], - [ 'Replication Desired', item.replication_desired ? item.replication_desired : ( - { String(item.replication_desired) } - ) ], - [ 'Replication Confirmed', item.replication_confirmed ? item.replication_confirmed : ( - { String(item.replication_confirmed) } - ) ], - [ 'Replication Confirmed At', wbFormatDate(item.replication_confirmed_at) ], - [ 'Trash At', wbFormatDate(item.trash_at) ], - [ 'Delete At', wbFormatDate(item.delete_at) ], - [ 'Is Trashed', String(item.is_trashed) ], - [ 'Current Version UUID', ( - - ) ], - [ 'Version', item.version ], - [ 'Preserve Version', String(item.preserve_version) ], - [ 'File Count', item.file_count ], - [ 'Total Size', filesize(item.file_size_total) ] - ]; - this.setState({ 'rows': rows }); + this.prepareRows(item); }); } diff --git a/frontend/src/js/component/wb-json-editor.js b/frontend/src/js/component/wb-json-editor.js new file mode 100644 index 0000000..c77400e --- /dev/null +++ b/frontend/src/js/component/wb-json-editor.js @@ -0,0 +1,60 @@ +import { h, Component, createRef } from 'preact'; +import WBJsonViewer from 'wb-json-viewer'; +import WBAccordion from 'wb-accordion'; +import WBDialog from 'wb-dialog'; + +class WBJsonEditor extends Component { + constructor(...args) { + super(...args); + this.dialogRef = createRef(); + } + + render({ app, name, value, stringify, pretty, onChange }, { editValue, parseError }) { + return ( +
+ { + onChange(JSON.parse(editValue)); + } } + canAccept={ () => { + try { JSON.parse(editValue) } + catch (exc) { this.setState({ parseError: exc.message }); return false; } + return true; + } }> +
+