[ARVADOS-WORKBENCH2] created: 2.1.0-181-g4159df75

Git user git at public.arvados.org
Tue Jan 26 14:28:30 UTC 2021


        at  4159df75086835ceef2ab6c4e9d1d53bdc14f7cb (commit)


commit 4159df75086835ceef2ab6c4e9d1d53bdc14f7cb
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Tue Jan 26 11:27:52 2021 -0300

    17266: Fixes change event handling on property editor.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/views-components/resource-properties-form/property-field-common.tsx b/src/views-components/resource-properties-form/property-field-common.tsx
index 90a6a301..949a1125 100644
--- a/src/views-components/resource-properties-form/property-field-common.tsx
+++ b/src/views-components/resource-properties-form/property-field-common.tsx
@@ -2,7 +2,6 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { ChangeEvent } from 'react';
 import { connect } from 'react-redux';
 import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps, reset } from 'redux-form';
 import { Vocabulary, PropFieldSuggestion } from '~/models/vocabulary';
@@ -76,7 +75,7 @@ export const handleChange = (
     formName: string,
     { onChange }: WrappedFieldInputProps,
     { dispatch }: WrappedFieldMetaProps) =>
-    (value: ChangeEvent<HTMLInputElement>) => {
+    (value: string) => {
         if (fieldName === PROPERTY_KEY_FIELD_ID) {
             // Properties' values are dependant on the keys, if any value is
             // pre-existant, a change on the property key should mean that the
diff --git a/src/views-components/resource-properties-form/property-key-field.tsx b/src/views-components/resource-properties-form/property-key-field.tsx
index 0c3a49be..7a95d8e6 100644
--- a/src/views-components/resource-properties-form/property-key-field.tsx
+++ b/src/views-components/resource-properties-form/property-key-field.tsx
@@ -33,8 +33,9 @@ const PropertyKeyInput = ({ vocabulary, ...props }: WrappedFieldProps & Vocabula
             suggestions={getSuggestions(props.input.value, vocabulary)}
             onSelect={handleSelect(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)}
             onBlur={handleBlur(PROPERTY_KEY_FIELD_ID, data.form, props.meta, props.input, getTagKeyID(props.input.value, vocabulary))}
-            onChange={(value: ChangeEvent<HTMLInputElement>) => {
-                handleChange(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)(value);
+            onChange={(e: ChangeEvent<HTMLInputElement>) => {
+                const newValue = e.currentTarget.value;
+                handleChange(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)(newValue);
             }}
             {...buildProps(props)}
         />
diff --git a/src/views-components/resource-properties-form/property-value-field.tsx b/src/views-components/resource-properties-form/property-value-field.tsx
index 9ce9d521..c106ab43 100644
--- a/src/views-components/resource-properties-form/property-value-field.tsx
+++ b/src/views-components/resource-properties-form/property-value-field.tsx
@@ -11,6 +11,7 @@ import { PROPERTY_KEY_FIELD_ID, PROPERTY_KEY_FIELD_NAME } from '~/views-componen
 import { handleSelect, handleBlur, VocabularyProp, ValidationProp, connectVocabulary, buildProps, handleChange } from '~/views-components/resource-properties-form/property-field-common';
 import { TAG_VALUE_VALIDATION } from '~/validators/validators';
 import { escapeRegExp } from '~/common/regexp.ts';
+import { ChangeEvent } from 'react';
 
 interface PropertyKeyProp {
     propertyKeyId: string;
@@ -53,7 +54,10 @@ const PropertyValueInput = ({ vocabulary, propertyKeyId, propertyKeyName, ...pro
             suggestions={getSuggestions(props.input.value, propertyKeyId, vocabulary)}
             onSelect={handleSelect(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
             onBlur={handleBlur(PROPERTY_VALUE_FIELD_ID, data.form, props.meta, props.input, getTagValueID(propertyKeyId, props.input.value, vocabulary))}
-            onChange={handleChange(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
+            onChange={(e: ChangeEvent<HTMLInputElement>) => {
+                const newValue = e.currentTarget.value;
+                handleChange(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)(newValue);
+            }}
             {...buildProps(props)}
         />
     )} />;
diff --git a/src/views-components/resource-properties-form/resource-properties-form.tsx b/src/views-components/resource-properties-form/resource-properties-form.tsx
index 0632b97c..c8d0959a 100644
--- a/src/views-components/resource-properties-form/resource-properties-form.tsx
+++ b/src/views-components/resource-properties-form/resource-properties-form.tsx
@@ -30,6 +30,7 @@ export const ResourcePropertiesForm = ({ handleSubmit, submitting, invalid, clas
             </Grid>
             <Grid item xs>
                 <Button
+                    data-cy='property-add-btn'
                     disabled={invalid}
                     loading={submitting}
                     color='primary'

commit 76090ef444f95160521b4458ed256f3a6306fa90
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Tue Jan 26 11:23:43 2021 -0300

    17266: Avoids reloading the app on cypress tests by using search.
    
    Instead of using visit(url), whenever possible we should use some method
    that makes the app do the routing. One way is to use the search bar with
    UUIDs, as it will use the route to the proper resource panel.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/cypress/integration/collection-panel.spec.js b/cypress/integration/collection-panel.spec.js
index 424c2bad..0669b313 100644
--- a/cypress/integration/collection-panel.spec.js
+++ b/cypress/integration/collection-panel.spec.js
@@ -28,7 +28,7 @@ describe('Collection panel tests', function() {
         cy.clearLocalStorage();
     });
 
-    it.only('shows collection by URL', function() {
+    it('shows collection by URL', function() {
         cy.loginAs(activeUser);
         [true, false].map(function(isWritable) {
             cy.createGroup(adminUser.token, {
@@ -50,10 +50,7 @@ describe('Collection panel tests', function() {
                         head_uuid: this.sharedGroup.uuid,
                         tail_uuid: activeUser.user.uuid
                     })
-                    cy.visit(`/collections/${this.testCollection.uuid}`);
-
-                    cy.get('[data-cy=linear-progress]').should('exist');
-                    cy.get('[data-cy=linear-progress]').should('not.exist');
+                    cy.doSearch(`${this.testCollection.uuid}`);
 
                     // Check that name & uuid are correct.
                     cy.get('[data-cy=collection-info-panel]')
@@ -143,10 +140,7 @@ describe('Collection panel tests', function() {
             manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"})
         .as('testCollection').then(function() {
             cy.loginAs(activeUser);
-            cy.visit(`/collections/${this.testCollection.uuid}`);
-
-            cy.get('[data-cy=linear-progress]').should('exist');
-            cy.get('[data-cy=linear-progress]').should('not.exist');
+            cy.doSearch(`${this.testCollection.uuid}`);
 
             const nameTransitions = [
                 ['bar', '&'],
@@ -183,10 +177,7 @@ describe('Collection panel tests', function() {
             manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"})
         .as('testCollection').then(function() {
             cy.loginAs(activeUser);
-            cy.visit(`/collections/${this.testCollection.uuid}`);
-
-            cy.get('[data-cy=linear-progress]').should('exist');
-            cy.get('[data-cy=linear-progress]').should('not.exist');
+            cy.doSearch(`${this.testCollection.uuid}`);
 
             // Rename 'bar' to 'subdir/foo'
             cy.get('[data-cy=collection-files-panel]')
@@ -234,10 +225,7 @@ describe('Collection panel tests', function() {
             manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"})
         .as('testCollection').then(function() {
             cy.loginAs(activeUser);
-            cy.visit(`/collections/${this.testCollection.uuid}`);
-
-            cy.get('[data-cy=linear-progress]').should('exist');
-            cy.get('[data-cy=linear-progress]').should('not.exist');
+            cy.doSearch(`${this.testCollection.uuid}`);
 
             const illegalNamesFromUI = [
                 ['.', "Name cannot be '.' or '..'"],
@@ -312,10 +300,7 @@ describe('Collection panel tests', function() {
             });
             // Check the old version displays as what it is.
             cy.loginAs(activeUser)
-            cy.visit(`/collections/${oldVersionUuid}`);
-
-            cy.get('[data-cy=linear-progress]').should('exist');
-            cy.get('[data-cy=linear-progress]').should('not.exist');
+            cy.doSearch(`${oldVersionUuid}`);
 
             cy.get('[data-cy=collection-info-panel]').should('contain', 'This is an old version');
             cy.get('[data-cy=read-only-icon]').should('exist');
@@ -337,10 +322,7 @@ describe('Collection panel tests', function() {
         .as('collection').then(function() {
             // Visit collection, check basic information
             cy.loginAs(activeUser)
-            cy.visit(`/collections/${this.collection.uuid}`);
-
-            cy.get('[data-cy=linear-progress]').should('exist');
-            cy.get('[data-cy=linear-progress]').should('not.exist');
+            cy.doSearch(`${this.collection.uuid}`);
 
             cy.get('[data-cy=collection-info-panel]').should('not.contain', 'This is an old version');
             cy.get('[data-cy=read-only-icon]').should('not.exist');
diff --git a/cypress/integration/delete-multiple-files.spec.js b/cypress/integration/delete-multiple-files.spec.js
index 0955f56a..f9e87117 100644
--- a/cypress/integration/delete-multiple-files.spec.js
+++ b/cypress/integration/delete-multiple-files.spec.js
@@ -32,10 +32,7 @@ describe('Multi-file deletion tests', function () {
         })
             .as('testCollection').then(function () {
                 cy.loginAs(activeUser);
-                cy.visit(`/collections/${this.testCollection.uuid}`);
-
-                cy.get('[data-cy=linear-progress]').should('exist');
-                cy.get('[data-cy=linear-progress]').should('not.exist');
+                cy.doSearch(`${this.testCollection.uuid}`);
 
                 cy.get('[data-cy=collection-files-panel]').within(() => {
                     cy.get('[type="checkbox"]').first().check();
@@ -58,10 +55,7 @@ describe('Multi-file deletion tests', function () {
         })
             .as('testCollection').then(function () {
                 cy.loginAs(activeUser);
-                cy.visit(`/collections/${this.testCollection.uuid}`);
-
-                cy.get('[data-cy=linear-progress]').should('exist');
-                cy.get('[data-cy=linear-progress]').should('not.exist');
+                cy.doSearch(`${this.testCollection.uuid}`);
 
                 cy.get('[data-cy=virtual-file-tree] > div > i').first().click();
                 cy.get('[data-cy=collection-files-panel]')
diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js
index 06131a2e..8806d12d 100644
--- a/cypress/integration/search.spec.js
+++ b/cypress/integration/search.spec.js
@@ -72,11 +72,11 @@ describe('Search tests', function() {
             cy.loginAs(activeUser);
             const searchQuery = `${colName} type:arvados#collection`;
             // Search for only collection's current version
-            cy.visit(`/search-results?q=${encodeURIComponent(searchQuery)}`);
+            cy.doSearch(`${searchQuery}`);
             cy.get('[data-cy=search-results]').should('contain', 'head version');
             cy.get('[data-cy=search-results]').should('not.contain', 'version 1');
             // ...and then, include old versions.
-            cy.visit(`/search-results?q=${encodeURIComponent(searchQuery + ' is:pastVersion')}`);
+            cy.doSearch(`${searchQuery} is:pastVersion`);
             cy.get('[data-cy=search-results]').should('contain', 'head version');
             cy.get('[data-cy=search-results]').should('contain', 'version 1');
         });
diff --git a/cypress/integration/side-panel.spec.js b/cypress/integration/side-panel.spec.js
index 40f39144..fe9d8400 100644
--- a/cypress/integration/side-panel.spec.js
+++ b/cypress/integration/side-panel.spec.js
@@ -30,7 +30,7 @@ describe('Side panel tests', function() {
 
     it('enables the +NEW side panel button on users home project', function() {
         cy.loginAs(activeUser);
-        cy.visit(`/projects/${activeUser.user.uuid}`);
+        cy.doSearch(`${activeUser.user.uuid}`);
         cy.get('[data-cy=side-panel-button]')
             .should('exist')
             .and('not.be.disabled');
@@ -49,7 +49,7 @@ describe('Side panel tests', function() {
                     head_uuid: this.sharedGroup.uuid,
                     tail_uuid: activeUser.user.uuid
                 })
-                cy.visit(`/projects/${this.sharedGroup.uuid}`);
+                cy.doSearch(`${this.sharedGroup.uuid}`);
                 cy.get('[data-cy=side-panel-button]')
                     .should('exist')
                     .and(`${isWritable ? 'not.' : ''}be.disabled`);
@@ -78,7 +78,7 @@ describe('Side panel tests', function() {
 
     it('creates new collection on home project', function() {
         cy.loginAs(activeUser);
-        cy.visit(`/projects/${activeUser.user.uuid}`);
+        cy.doSearch(`${activeUser.user.uuid}`);
         cy.get('[data-cy=breadcrumb-first]').should('contain', 'Projects');
         cy.get('[data-cy=breadcrumb-last]').should('not.exist');
         // Create new collection
@@ -122,7 +122,7 @@ describe('Side panel tests', function() {
         }
 
         cy.loginAs(activeUser);
-        cy.visit(`/projects/${activeUser.user.uuid}`);
+        cy.doSearch(`${activeUser.user.uuid}`);
         cy.get('[data-cy=breadcrumb-first]').should('contain', 'Projects');
         cy.get('[data-cy=breadcrumb-last]').should('not.exist');
         // Create new project
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 216012c4..bba04ba8 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -176,10 +176,14 @@ Cypress.Commands.add(
 Cypress.Commands.add(
     "loginAs", (user) => {
         cy.visit(`/token/?api_token=${user.token}`);
-        cy.get('[data-cy=loading-spinner]').should('exist');
-        cy.get('[data-cy=loading-spinner]').should('not.exist');
         cy.url().should('contain', '/projects/');
         cy.get('div#root').should('contain', 'Arvados Workbench (zzzzz)');
         cy.get('div#root').should('not.contain', 'Your account is inactive');
     }
 )
+
+Cypress.Commands.add(
+    "doSearch", (searchTerm) => {
+        cy.get('[data-cy=searchbar-input-field]').type(`{selectall}${searchTerm}{enter}`);
+    }
+)
\ No newline at end of file
diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx
index 20536fd7..073aae6e 100644
--- a/src/views-components/search-bar/search-bar-view.tsx
+++ b/src/views-components/search-bar/search-bar-view.tsx
@@ -177,7 +177,7 @@ export const SearchBarView = compose(connectVocabulary, withStyles(styles))(
                     <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
                         <form onSubmit={this.handleSubmit}>
                             <Input
-                                data-cy='search-input-field'
+                                data-cy='searchbar-input-field'
                                 className={classes.input}
                                 onChange={this.handleChange}
                                 placeholder="Search"

commit bb18ea7238065603568d21fd9a44abbd35768599
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Mon Jan 25 17:33:55 2021 -0300

    17266: Avoids adding a property value without a key.
    
    Also resets the form whenever a property key changes, this avoids a previously
    validated property value to be taken as valid with a different property key.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/components/autocomplete/autocomplete.tsx b/src/components/autocomplete/autocomplete.tsx
index e01673b7..67bc9fa1 100644
--- a/src/components/autocomplete/autocomplete.tsx
+++ b/src/components/autocomplete/autocomplete.tsx
@@ -18,6 +18,7 @@ export interface AutocompleteProps<Item, Suggestion> {
     label?: string;
     value: string;
     items: Item[];
+    disabled?: boolean;
     suggestions?: Suggestion[];
     error?: boolean;
     helperText?: string;
@@ -67,6 +68,7 @@ export class Autocomplete<Value, Suggestion> extends React.Component<Autocomplet
 
     renderInput() {
         return <Input
+            disabled={this.props.disabled}
             autoFocus={this.props.autofocus}
             inputRef={this.inputRef}
             value={this.props.value}
diff --git a/src/views-components/resource-properties-form/property-field-common.tsx b/src/views-components/resource-properties-form/property-field-common.tsx
index e802ad5c..90a6a301 100644
--- a/src/views-components/resource-properties-form/property-field-common.tsx
+++ b/src/views-components/resource-properties-form/property-field-common.tsx
@@ -2,11 +2,13 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+import { ChangeEvent } from 'react';
 import { connect } from 'react-redux';
-import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps } from 'redux-form';
+import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps, reset } from 'redux-form';
 import { Vocabulary, PropFieldSuggestion } from '~/models/vocabulary';
 import { RootState } from '~/store/store';
 import { getVocabulary } from '~/store/vocabulary/vocabulary-selectors';
+import { PROPERTY_KEY_FIELD_ID } from './property-key-field';
 
 export interface VocabularyProp {
     vocabulary: Vocabulary;
@@ -36,7 +38,6 @@ export const getErrorMsg = (meta: WrappedFieldMetaProps) =>
 export const buildProps = ({ input, meta }: WrappedFieldProps) => {
     return {
         value: input.value,
-        onChange: input.onChange,
         items: ITEMS_PLACEHOLDER,
         renderSuggestion: (item: PropFieldSuggestion) => item.label,
         error: hasError(meta),
@@ -69,3 +70,19 @@ export const handleSelect = (
             dispatch(change(formName, fieldName, item.id));
         }
     };
+
+export const handleChange = (
+    fieldName: string,
+    formName: string,
+    { onChange }: WrappedFieldInputProps,
+    { dispatch }: WrappedFieldMetaProps) =>
+    (value: ChangeEvent<HTMLInputElement>) => {
+        if (fieldName === PROPERTY_KEY_FIELD_ID) {
+            // Properties' values are dependant on the keys, if any value is
+            // pre-existant, a change on the property key should mean that the
+            // previous value is invalid.
+            dispatch(reset(formName));
+        }
+        onChange(value);
+        dispatch(change(formName, fieldName, value));
+    };
\ No newline at end of file
diff --git a/src/views-components/resource-properties-form/property-key-field.tsx b/src/views-components/resource-properties-form/property-key-field.tsx
index d17f50d4..0c3a49be 100644
--- a/src/views-components/resource-properties-form/property-key-field.tsx
+++ b/src/views-components/resource-properties-form/property-key-field.tsx
@@ -7,9 +7,10 @@ import { WrappedFieldProps, Field, FormName } from 'redux-form';
 import { memoize } from 'lodash';
 import { Autocomplete } from '~/components/autocomplete/autocomplete';
 import { Vocabulary, getTags, getTagKeyID } from '~/models/vocabulary';
-import { handleSelect, handleBlur, connectVocabulary, VocabularyProp, ValidationProp, buildProps } from '~/views-components/resource-properties-form/property-field-common';
+import { handleSelect, handleBlur, connectVocabulary, VocabularyProp, ValidationProp, buildProps, handleChange } from '~/views-components/resource-properties-form/property-field-common';
 import { TAG_KEY_VALIDATION } from '~/validators/validators';
 import { escapeRegExp } from '~/common/regexp.ts';
+import { ChangeEvent } from 'react';
 
 export const PROPERTY_KEY_FIELD_NAME = 'key';
 export const PROPERTY_KEY_FIELD_ID = 'keyID';
@@ -32,6 +33,9 @@ const PropertyKeyInput = ({ vocabulary, ...props }: WrappedFieldProps & Vocabula
             suggestions={getSuggestions(props.input.value, vocabulary)}
             onSelect={handleSelect(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)}
             onBlur={handleBlur(PROPERTY_KEY_FIELD_ID, data.form, props.meta, props.input, getTagKeyID(props.input.value, vocabulary))}
+            onChange={(value: ChangeEvent<HTMLInputElement>) => {
+                handleChange(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)(value);
+            }}
             {...buildProps(props)}
         />
     )} />;
diff --git a/src/views-components/resource-properties-form/property-value-field.tsx b/src/views-components/resource-properties-form/property-value-field.tsx
index c5a5071f..9ce9d521 100644
--- a/src/views-components/resource-properties-form/property-value-field.tsx
+++ b/src/views-components/resource-properties-form/property-value-field.tsx
@@ -7,23 +7,31 @@ import { WrappedFieldProps, Field, formValues, FormName } from 'redux-form';
 import { compose } from 'redux';
 import { Autocomplete } from '~/components/autocomplete/autocomplete';
 import { Vocabulary, isStrictTag, getTagValues, getTagValueID } from '~/models/vocabulary';
-import { PROPERTY_KEY_FIELD_ID } from '~/views-components/resource-properties-form/property-key-field';
-import { handleSelect, handleBlur, VocabularyProp, ValidationProp, connectVocabulary, buildProps } from '~/views-components/resource-properties-form/property-field-common';
+import { PROPERTY_KEY_FIELD_ID, PROPERTY_KEY_FIELD_NAME } from '~/views-components/resource-properties-form/property-key-field';
+import { handleSelect, handleBlur, VocabularyProp, ValidationProp, connectVocabulary, buildProps, handleChange } from '~/views-components/resource-properties-form/property-field-common';
 import { TAG_VALUE_VALIDATION } from '~/validators/validators';
 import { escapeRegExp } from '~/common/regexp.ts';
 
 interface PropertyKeyProp {
-    propertyKey: string;
+    propertyKeyId: string;
+    propertyKeyName: string;
 }
 
-type PropertyValueFieldProps = VocabularyProp & PropertyKeyProp & ValidationProp;
+interface PropertyValueInputProp {
+    disabled: boolean;
+}
+
+type PropertyValueFieldProps = VocabularyProp & PropertyKeyProp & ValidationProp & PropertyValueInputProp;
 
 export const PROPERTY_VALUE_FIELD_NAME = 'value';
 export const PROPERTY_VALUE_FIELD_ID = 'valueID';
 
 const connectVocabularyAndPropertyKey = compose(
     connectVocabulary,
-    formValues({ propertyKey: PROPERTY_KEY_FIELD_ID }),
+    formValues({
+        propertyKeyId: PROPERTY_KEY_FIELD_ID,
+        propertyKeyName: PROPERTY_KEY_FIELD_NAME,
+    }),
 );
 
 export const PropertyValueField = connectVocabularyAndPropertyKey(
@@ -33,29 +41,31 @@ export const PropertyValueField = connectVocabularyAndPropertyKey(
             name={PROPERTY_VALUE_FIELD_NAME}
             component={PropertyValueInput}
             validate={skipValidation ? undefined : getValidation(props)}
-            {...props} />
+            {...{...props, disabled: !props.propertyKeyName}} />
         </span>
 );
 
-const PropertyValueInput = ({ vocabulary, propertyKey, ...props }: WrappedFieldProps & PropertyValueFieldProps) =>
+const PropertyValueInput = ({ vocabulary, propertyKeyId, propertyKeyName, ...props }: WrappedFieldProps & PropertyValueFieldProps) =>
     <FormName children={data => (
         <Autocomplete
             label='Value'
-            suggestions={getSuggestions(props.input.value, propertyKey, vocabulary)}
+            disabled={props.disabled}
+            suggestions={getSuggestions(props.input.value, propertyKeyId, vocabulary)}
             onSelect={handleSelect(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
-            onBlur={handleBlur(PROPERTY_VALUE_FIELD_ID, data.form, props.meta, props.input, getTagValueID(propertyKey, props.input.value, vocabulary))}
+            onBlur={handleBlur(PROPERTY_VALUE_FIELD_ID, data.form, props.meta, props.input, getTagValueID(propertyKeyId, props.input.value, vocabulary))}
+            onChange={handleChange(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
             {...buildProps(props)}
         />
     )} />;
 
 const getValidation = (props: PropertyValueFieldProps) =>
-    isStrictTag(props.propertyKey, props.vocabulary)
+    isStrictTag(props.propertyKeyId, props.vocabulary)
         ? [...TAG_VALUE_VALIDATION, matchTagValues(props)]
         : TAG_VALUE_VALIDATION;
 
-const matchTagValues = ({ vocabulary, propertyKey }: PropertyValueFieldProps) =>
+const matchTagValues = ({ vocabulary, propertyKeyId }: PropertyValueFieldProps) =>
     (value: string) =>
-        getTagValues(propertyKey, vocabulary).find(v => v.label === value)
+        getTagValues(propertyKeyId, vocabulary).find(v => v.label === value)
             ? undefined
             : 'Incorrect value';
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list