[arvados-workbench2] created: 2.4.0-183-g78ed213a

git repository hosting git at public.arvados.org
Fri Aug 12 14:24:27 UTC 2022


        at  78ed213aa29f8af76d973b295c159a0b4764a4a1 (commit)


commit 78ed213aa29f8af76d973b295c159a0b4764a4a1
Author: Stephen Smith <stephen at curii.com>
Date:   Thu Aug 11 17:57:28 2022 -0400

    18979: Disable vm login form submit and warn with unsaved group input
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/src/components/chips-input/chips-input.tsx b/src/components/chips-input/chips-input.tsx
index cbb1fb12..7b9ff4a6 100644
--- a/src/components/chips-input/chips-input.tsx
+++ b/src/components/chips-input/chips-input.tsx
@@ -12,6 +12,7 @@ interface ChipsInputProps<Value> {
     values: Value[];
     getLabel?: (value: Value) => string;
     onChange: (value: Value[]) => void;
+    onPartialInput?: (value: boolean) => void;
     handleFocus?: (e: any) => void;
     handleBlur?: (e: any) => void;
     chipsClassName?: string;
@@ -54,6 +55,9 @@ export const ChipsInput = withStyles(styles)(
 
         setText = (event: React.ChangeEvent<HTMLInputElement>) => {
             this.setState({ text: event.target.value }, () => {
+                // Update partial input status
+                this.props.onPartialInput && this.props.onPartialInput(this.state.text !== '');
+
                 // If pattern is provided, check for delimiter
                 if (this.props.pattern) {
                     const matches = this.state.text.match(this.props.pattern);
@@ -92,6 +96,7 @@ export const ChipsInput = withStyles(styles)(
                     this.setState({ text: '' });
                     this.props.onChange([...this.props.values, newValue]);
                 }
+                this.props.onPartialInput && this.props.onPartialInput(false);
             }
         }
 
diff --git a/src/views-components/virtual-machines-dialog/add-login-dialog.tsx b/src/views-components/virtual-machines-dialog/add-login-dialog.tsx
index 1654452b..b591bb8f 100644
--- a/src/views-components/virtual-machines-dialog/add-login-dialog.tsx
+++ b/src/views-components/virtual-machines-dialog/add-login-dialog.tsx
@@ -9,7 +9,7 @@ import { withDialog, WithDialogProps } from "store/dialog/with-dialog";
 import { FormDialog } from 'components/form-dialog/form-dialog';
 import { VIRTUAL_MACHINE_ADD_LOGIN_DIALOG, VIRTUAL_MACHINE_ADD_LOGIN_FORM, addUpdateVirtualMachineLogin, AddLoginFormData, VIRTUAL_MACHINE_ADD_LOGIN_USER_FIELD, VIRTUAL_MACHINE_ADD_LOGIN_GROUPS_FIELD } from 'store/virtual-machines/virtual-machines-actions';
 import { ParticipantSelect } from 'views-components/sharing-dialog/participant-select';
-import { GroupArrayInput } from 'views-components/virtual-machines-dialog/group-array-input';
+import { GroupArrayInput, GroupArrayDataProps } from 'views-components/virtual-machines-dialog/group-array-input';
 
 export const VirtualMachineAddLoginDialog = compose(
     withDialog(VIRTUAL_MACHINE_ADD_LOGIN_DIALOG),
@@ -20,16 +20,25 @@ export const VirtualMachineAddLoginDialog = compose(
         }
     })
 )(
-    (props: CreateGroupDialogComponentProps) =>
-        <FormDialog
+    (props: CreateGroupDialogComponentProps) => {
+        const [hasPartialGroupInput, setPartialGroupInput] = React.useState<boolean>(false);
+
+        return <FormDialog
             dialogTitle={props.data.updating ? "Update login permission" : "Add login permission"}
             formFields={AddLoginFormFields}
             submitLabel={props.data.updating ? "Update" : "Add"}
             {...props}
-        />
+            data={{
+                ...props.data,
+                setPartialGroupInput,
+                hasPartialGroupInput,
+            }}
+            invalid={props.invalid || hasPartialGroupInput}
+        />;
+    }
 );
 
-type CreateGroupDialogComponentProps = WithDialogProps<{updating: boolean}> & InjectedFormProps<AddLoginFormData>;
+type CreateGroupDialogComponentProps = WithDialogProps<{updating: boolean}> & GroupArrayDataProps & InjectedFormProps<AddLoginFormData>;
 
 const AddLoginFormFields = (props) => {
     return <>
@@ -42,6 +51,8 @@ const AddLoginFormFields = (props) => {
             name={VIRTUAL_MACHINE_ADD_LOGIN_GROUPS_FIELD}
             input={{id:"Add groups to VM login (eg: docker, sudo)", disabled:false}}
             required={false}
+            setPartialGroupInput={props.data.setPartialGroupInput}
+            hasPartialGroupInput={props.data.hasPartialGroupInput}
         />
     </>;
 }
diff --git a/src/views-components/virtual-machines-dialog/group-array-input.tsx b/src/views-components/virtual-machines-dialog/group-array-input.tsx
index 3ea5e77c..95a86420 100644
--- a/src/views-components/virtual-machines-dialog/group-array-input.tsx
+++ b/src/views-components/virtual-machines-dialog/group-array-input.tsx
@@ -4,34 +4,59 @@
 
 import React from 'react';
 import { StringArrayCommandInputParameter } from 'models/workflow';
-import { Field } from 'redux-form';
+import { Field, GenericField } from 'redux-form';
 import { GenericInputProps } from 'views/run-process-panel/inputs/generic-input';
 import { ChipsInput } from 'components/chips-input/chips-input';
 import { identity } from 'lodash';
-import { withStyles, WithStyles, FormGroup, Input, InputLabel, FormControl } from '@material-ui/core';
+import { withStyles, WithStyles, FormGroup, Input, InputLabel, FormControl, FormHelperText } from '@material-ui/core';
+import classnames from "classnames";
+import { ArvadosTheme } from 'common/custom-theme';
 
-export interface StringArrayInputProps {
+export interface GroupArrayDataProps {
+  hasPartialGroupInput?: boolean;
+  setPartialGroupInput?: (value: boolean) => void;
+}
+
+interface GroupArrayFieldProps {
+  commandInput: StringArrayCommandInputParameter;
+}
+
+const GroupArrayField = Field as new () => GenericField<GroupArrayDataProps & GroupArrayFieldProps>;
+
+export interface GroupArrayInputProps {
   name: string;
   input: StringArrayCommandInputParameter;
   required: boolean;
 }
 
-type CssRules = 'chips';
+type CssRules = 'chips' | 'partialInputHelper' | 'partialInputHelperVisible';
 
-const styles = {
+const styles = (theme: ArvadosTheme) => ({
     chips: {
         marginTop: "16px",
     },
-};
+    partialInputHelper: {
+        textAlign: 'right' as 'right',
+        visibility: 'hidden' as 'hidden',
+        color: theme.palette.error.dark,
+    },
+    partialInputHelperVisible: {
+        visibility: 'visible' as 'visible',
+    }
+});
 
-export const GroupArrayInput = ({name, input}: StringArrayInputProps) =>
-    <Field
-        name={name}
-        commandInput={input}
-        component={StringArrayInputComponent as any}
-        />;
+export const GroupArrayInput = ({name, input, setPartialGroupInput, hasPartialGroupInput}: GroupArrayInputProps & GroupArrayDataProps) => {
+  console.log(hasPartialGroupInput);
+  return <GroupArrayField
+      name={name}
+      commandInput={input}
+      component={GroupArrayInputComponent as any}
+      setPartialGroupInput={setPartialGroupInput}
+      hasPartialGroupInput={hasPartialGroupInput}
+      />;
+}
 
-const StringArrayInputComponent = (props: GenericInputProps) => {
+const GroupArrayInputComponent = (props: GenericInputProps & GroupArrayDataProps) => {
   return <FormGroup>
         <FormControl fullWidth error={props.meta.error}>
           <InputLabel shrink={props.meta.active || props.input.value.length > 0}>{props.commandInput.id}</InputLabel>
@@ -41,24 +66,30 @@ const StringArrayInputComponent = (props: GenericInputProps) => {
     };
 
 const StyledInputComponent = withStyles(styles)(
-  class InputComponent extends React.PureComponent<GenericInputProps & WithStyles<CssRules>>{
+  class InputComponent extends React.PureComponent<GenericInputProps & WithStyles<CssRules> & GroupArrayDataProps>{
       render() {
           const { classes } = this.props;
-          const { commandInput, input, meta } = this.props;
-          return <ChipsInput
-              deletable={!commandInput.disabled}
-              orderable={!commandInput.disabled}
-              disabled={commandInput.disabled}
-              values={input.value}
-              onChange={this.handleChange}
-              handleFocus={input.onFocus}
-              createNewValue={identity}
-              inputComponent={Input}
-              chipsClassName={classes.chips}
-              pattern={/[_a-z][-0-9_a-z]*/ig}
-              inputProps={{
-                  error: meta.error,
-              }} />;
+          const { commandInput, input, meta, hasPartialGroupInput } = this.props;
+          return <>
+            <ChipsInput
+                deletable={!commandInput.disabled}
+                orderable={!commandInput.disabled}
+                disabled={commandInput.disabled}
+                values={input.value}
+                onChange={this.handleChange}
+                handleFocus={input.onFocus}
+                createNewValue={identity}
+                inputComponent={Input}
+                chipsClassName={classes.chips}
+                pattern={/[_a-z][-0-9_a-z]*/ig}
+                onPartialInput={this.props.setPartialGroupInput}
+                inputProps={{
+                    error: meta.error || hasPartialGroupInput,
+                }} />
+                <FormHelperText className={classnames([classes.partialInputHelper, ...(hasPartialGroupInput ? [classes.partialInputHelperVisible] : [])])}>
+                  Press enter to complete group name
+                </FormHelperText>
+          </>;
       }
 
       handleChange = (values: {}[]) => {

commit c2c920158f714754e3066460bc013cdf492b60dc
Author: Stephen Smith <stephen at curii.com>
Date:   Thu Aug 11 17:55:39 2022 -0400

    18979: Add horizontal scroll for vm user/admin panels
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/src/views/virtual-machine-panel/virtual-machine-admin-panel.tsx b/src/views/virtual-machine-panel/virtual-machine-admin-panel.tsx
index 468ef35a..864218e4 100644
--- a/src/views/virtual-machine-panel/virtual-machine-admin-panel.tsx
+++ b/src/views/virtual-machine-panel/virtual-machine-admin-panel.tsx
@@ -16,7 +16,7 @@ import { VirtualMachineLogins, VirtualMachinesResource } from 'models/virtual-ma
 import { openVirtualMachinesContextMenu } from 'store/context-menu/context-menu-actions';
 import { ResourceUuid, VirtualMachineHostname, VirtualMachineLogin } from 'views-components/data-explorer/renderers';
 
-type CssRules = 'moreOptionsButton' | 'moreOptions' | 'chipsRoot';
+type CssRules = 'moreOptionsButton' | 'moreOptions' | 'chipsRoot' | 'vmTableWrapper';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     moreOptionsButton: {
@@ -31,6 +31,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     chipsRoot: {
         margin: `0px -${theme.spacing.unit / 2}px`,
     },
+    vmTableWrapper: {
+        overflowX: 'auto',
+    },
 });
 
 const mapStateToProps = (state: RootState) => {
@@ -95,7 +98,7 @@ export const VirtualMachineAdminPanel = compose(
 const CardContentWithVirtualMachines = (props: VirtualMachineProps) =>
     <Grid item xs={12}>
         <Card>
-            <CardContent>
+            <CardContent className={props.classes.vmTableWrapper}>
                 {virtualMachinesTable(props)}
             </CardContent>
         </Card>
diff --git a/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx b/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx
index 70f97daf..751ca5f1 100644
--- a/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx
+++ b/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx
@@ -19,7 +19,7 @@ import { CopyIcon } from 'components/icon/icon';
 import CopyToClipboard from 'react-copy-to-clipboard';
 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
 
-type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon' | 'chipsRoot' | 'copyIcon' | 'webshellButton';
+type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon' | 'chipsRoot' | 'copyIcon' | 'tableWrapper' | 'webshellButton';
 
 const EXTRA_TOKEN = "exraToken";
 
@@ -72,6 +72,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             fontSize: '1rem'
         }
     },
+    tableWrapper: {
+        overflowX: 'auto',
+    },
     webshellButton: {
         textTransform: "initial",
     },
@@ -176,7 +179,9 @@ const CardContentWithVirtualMachines = (props: VirtualMachineProps) =>
                             </Tooltip>
                         </a>
                     </div>
-                    {virtualMachinesTable(props)}
+                    <div className={props.classes.tableWrapper}>
+                        {virtualMachinesTable(props)}
+                    </div>
                 </span>
 
             </CardContent>

commit 717af8aba7abe8530f25020c5d2db6997ee7addf
Author: Stephen Smith <stephen at curii.com>
Date:   Thu Aug 11 17:54:44 2022 -0400

    18979: Increase query limit for vm login admin
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/src/store/virtual-machines/virtual-machines-actions.ts b/src/store/virtual-machines/virtual-machines-actions.ts
index e4b17ea0..37503e61 100644
--- a/src/store/virtual-machines/virtual-machines-actions.ts
+++ b/src/store/virtual-machines/virtual-machines-actions.ts
@@ -83,7 +83,8 @@ export const loadVirtualMachinesAdminData = () =>
             filters: new FilterBuilder()
             .addIn('head_uuid', virtualMachines.items.map(item => item.uuid))
             .addEqual('name', PermissionLevel.CAN_LOGIN)
-            .getFilters()
+            .getFilters(),
+            limit: 1000
         });
         dispatch(updateResources(logins.items));
         dispatch(virtualMachinesActions.SET_LINKS(logins));
@@ -92,7 +93,8 @@ export const loadVirtualMachinesAdminData = () =>
             filters: new FilterBuilder()
             .addIn('uuid', logins.items.map(item => item.tailUuid))
             .getFilters(),
-            count: "none"
+            count: "none", // Necessary for federated queries
+            limit: 1000
         });
         dispatch(updateResources(users.items));
 

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list