Skip to content

Commit 77e0eaf

Browse files
authored
Merge pull request #11 from Quansight/enums_and_disables
Enums and disables - a rather bad title and large PR
2 parents eb7d264 + 38b22f1 commit 77e0eaf

File tree

8 files changed

+288
-59
lines changed

8 files changed

+288
-59
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ labextension
66
tsconfig.tsbuildinfo
77
yarn.lock
88
.DS_Store
9+
*.ipynb
10+
.ipynb_checkpoints

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,21 @@
5252
"@jupyterlab/services": "^6.0.0",
5353
"@rjsf/bootstrap-4": "^2.4.2",
5454
"@rjsf/core": "^2.4.2",
55-
"@types/lodash": "^4.14.168",
5655
"bootstrap": "^4.6.0",
5756
"framer-motion": "^4.0.3",
5857
"lodash": "^4.17.21",
59-
"react-ace": "^9.3.0",
60-
"react-bootstrap": "^1.5.2",
58+
"react-bootstrap": "!1.5.2",
59+
"react-dom": "^17.0.2",
6160
"react-spinners": "^0.10.6"
6261
},
6362
"devDependencies": {
6463
"@jupyterlab/builder": "^3.0.0",
64+
"@popperjs/core": "^2.9.2",
65+
"@types/react-bootstrap": "^0.32.25",
66+
"@types/lodash": "^4.14.168",
6567
"@typescript-eslint/eslint-plugin": "^2.27.0",
6668
"@typescript-eslint/parser": "^2.27.0",
67-
"eslint": "^7.5.0",
69+
"eslint": "^7.27.0",
6870
"eslint-config-prettier": "^6.10.1",
6971
"eslint-plugin-jsdoc": "^22.0.0",
7072
"eslint-plugin-prettier": "^3.1.2",

src/components/alerts.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from "react";
2+
import Alert from "react-bootstrap/Alert";
3+
4+
export const SuccessAlertBox = (props: any): JSX.Element => {
5+
return (
6+
<div>
7+
<Alert variant="success" onClose={() => props.handleClose()} dismissible>
8+
<Alert.Heading> The deployment of env_name was success. </Alert.Heading>
9+
</Alert>
10+
</div>
11+
);
12+
};

src/components/envvarwidget.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//import React, {useState} from 'react';
2+
3+
// export const EnvVariablesField = (props: any) => {
4+
// return (
5+
// <div id="custom">
6+
// <p>Yeah, I'm pretty dumb.</p>
7+
// <div>My props are: {JSON.stringify(props)}</div>
8+
// </div>
9+
// );
10+
// };
11+
12+
// export const envvarsfield = {
13+
// SchemaField: EnvVariablesField
14+
// };

src/components/ipyform.tsx

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,70 @@
1-
//import React from "react";
1+
import React, { useState } from "react";
22
//import { JSONSchema7 } from "json-schema";
3-
//import Form from "@rjsf/bootstrap-4";
4-
//import Card from "react-bootstrap/Card";
5-
//import { motion } from "framer-motion";
6-
//
7-
//const iPyArgumentControl = (props: any): JSX.Element => {
8-
// return (
9-
// <div>
10-
// <h1> Hello </h1>
11-
// </div>
12-
// );
13-
//};
14-
//
15-
//const iPyEnvironmentControl = (props: any): JSX.Element => {
16-
// return (
17-
// <div>
18-
// <p>{JSON.stringify(props)}</p>
19-
// </div>
20-
// );
21-
//};
22-
//
23-
//export const iPyForm = (props: any): JSX.Element => {
24-
// return (
25-
// <div>
26-
// <p> {JSON.stringify(props)} </p>
27-
// </div>
28-
// );
29-
//};
3+
import Form from "@rjsf/bootstrap-4";
4+
import Tabs from "react-bootstrap/Tabs";
5+
import Tab from "react-bootstrap/Tab";
6+
import {
7+
EnvVarForm,
8+
IPythonFormGroup,
9+
KeyValueWidget,
10+
} from "./ipythonformgroup";
11+
12+
export const IPyForm = (props: any): JSX.Element => {
13+
//console.log(props.schema);
14+
const TabMenu = (props: any): JSX.Element => {
15+
const [tab, setTab] = useState("General Settings");
16+
/*
17+
* Generate the menu titles for the schema
18+
*/
19+
var menuHeaders = [
20+
"General Settings",
21+
"Launch Arguments",
22+
"Environment Variables",
23+
"Compute Parameters",
24+
"Metadata",
25+
];
26+
27+
return (
28+
<div>
29+
<Tabs
30+
defaultActiveKey={menuHeaders[0]}
31+
onSelect={(k: string) => setTab(k)}
32+
>
33+
{menuHeaders.map((menuHeader: string) => (
34+
<Tab eventKey={menuHeader} key={menuHeader} title={menuHeader}>
35+
<IPythonFormGroup
36+
selecteditem={tab}
37+
properties={props.properties}
38+
handleAdditionalProperties={props.onAddClick}
39+
mainprops={props}
40+
/>
41+
</Tab>
42+
))}
43+
</Tabs>
44+
</div>
45+
);
46+
};
47+
48+
const uiSchema = {
49+
"ui:ObjectFieldTemplate": TabMenu,
50+
env: {
51+
"ui:widget": KeyValueWidget,
52+
"ui:autofocus": true,
53+
"ui:ObjectFieldTemplate": EnvVarForm,
54+
"ui:options": {
55+
expandable: true,
56+
},
57+
},
58+
};
59+
60+
return (
61+
<div>
62+
<Form
63+
schema={props.schema}
64+
uiSchema={uiSchema}
65+
formData={props.formData}
66+
onSubmit={props.onSubmit}
67+
/>
68+
</div>
69+
);
70+
};
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React, { useState } from "react";
2+
3+
/*
4+
* This is a nested comoponenet in the FieldTemplate, and
5+
* does all the work for rendering the different optins in their
6+
* respective places.
7+
*
8+
* props:
9+
*
10+
* data -> The data to render - namely, the data as defined in the schema
11+
*/
12+
export const IPythonFormGroup = (props: {
13+
properties: any;
14+
selecteditem: string;
15+
mainprops: any;
16+
handleAdditionalProperties: any;
17+
}) => {
18+
const fg: any = generateFormGroupMap(props.properties);
19+
return (
20+
<div>
21+
{fg[props.selecteditem].map((index: number) => (
22+
<div className="property-wrapper" key={index}>
23+
{props.properties[index].content}
24+
</div>
25+
))}
26+
</div>
27+
);
28+
};
29+
30+
export const KeyValueWidget = (props: any) => {
31+
const [key, setKey] = useState(props.value.name);
32+
const [val, setVal] = useState(props.formData[props.value.name]);
33+
return (
34+
<div>
35+
<input
36+
type="string"
37+
value={key}
38+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
39+
props.handleKey(key, e.target.value);
40+
setKey(e.target.value);
41+
}}
42+
/>
43+
<input
44+
type="string"
45+
value={val}
46+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
47+
props.handleVal(key, e.target.value);
48+
setVal(e.target.value);
49+
}}
50+
/>
51+
</div>
52+
);
53+
};
54+
55+
/*
56+
* This function is a field
57+
* that is rendered for the environment variable.
58+
*/
59+
export const EnvVarForm = (props: any) => {
60+
/*
61+
* Function to handle a change of key values in a key value store
62+
*/
63+
const handleKeyChange = (key: string, newkey: string) => {
64+
props.formData[newkey] = props.formData[key];
65+
delete props.formData[key];
66+
console.log(props.formData);
67+
};
68+
69+
/*
70+
* Function to handle any changing values
71+
*/
72+
const handleValueChange = (key: string, newvalue: string) => {
73+
props.formData[key] = newvalue;
74+
console.log(props.formData);
75+
};
76+
77+
const widget: (props: any) => JSX.Element = props.uiSchema["ui:widget"];
78+
const formData = props.formData;
79+
return (
80+
<div>
81+
{props.properties.map((item: any) =>
82+
widget(
83+
(props = {
84+
value: item,
85+
formData: formData,
86+
handleKey: handleKeyChange,
87+
handleVal: handleValueChange,
88+
})
89+
)
90+
)}
91+
<button
92+
type="button"
93+
onClick={(e: any) => {
94+
alert(props.onAddClick);
95+
}}
96+
>
97+
Add New
98+
</button>
99+
</div>
100+
);
101+
};
102+
103+
/*
104+
* Grab the location of the element in the array,
105+
* returning a value of the postions in the array.
106+
*/
107+
function generateFormGroupMap(dataArr: any) {
108+
const GeneralSettingsArray: Array<number> = [];
109+
const LaunchArgumentsArray: Array<number> = [];
110+
const EnvironmentVariableArray: Array<number> = [];
111+
const ComputeParametersArray: Array<number> = [];
112+
const MetadataArray: Array<number> = [];
113+
dataArr.forEach((element: any) => {
114+
if (
115+
element.name == "display_name" ||
116+
element.name == "interrupt_mode" ||
117+
element.name == "language"
118+
) {
119+
GeneralSettingsArray.push(dataArr.indexOf(element));
120+
} else if (element.name == "argv") {
121+
LaunchArgumentsArray.push(dataArr.indexOf(element));
122+
} else if (element.name == "env") {
123+
EnvironmentVariableArray.push(dataArr.indexOf(element));
124+
} else if (element.name == "parameters") {
125+
ComputeParametersArray.push(dataArr.indexOf(element));
126+
} else if (element.name == "metadata") {
127+
MetadataArray.push(dataArr.indexOf(element));
128+
} else {
129+
console.log("oopsies");
130+
}
131+
});
132+
return {
133+
["General Settings"]: GeneralSettingsArray,
134+
["Launch Arguments"]: LaunchArgumentsArray,
135+
["Environment Variables"]: EnvironmentVariableArray,
136+
["Compute Parameters"]: ComputeParametersArray,
137+
["Metadata"]: MetadataArray,
138+
};
139+
}

src/ipyschema.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,39 @@ import { JSONSchema7 } from "json-schema";
1313
* is also subject to change based on the types.
1414
*/
1515
export const iPySchema: JSONSchema7 = {
16-
title: "ipykernel mm",
16+
title: "iPyKernel Management Menu",
1717
type: "object",
1818
properties: {
19-
argv: { type: "array", items: { type: "string" } },
20-
env: { type: "object" },
21-
display_name: { type: "string" },
22-
language: { type: "string" },
23-
interrupt_mode: { type: "string" },
24-
metadata: { type: "object" },
19+
argv: { type: "array", items: { type: "string" }, title: "" },
20+
env: {
21+
type: "object",
22+
title: "object",
23+
properties: {
24+
EnvVar: { type: "string" },
25+
},
26+
additionalProperties: {
27+
type: "string",
28+
},
29+
},
30+
display_name: { type: "string", title: "Display Name" },
31+
language: { type: "string", title: "Programming Language" },
32+
interrupt_mode: {
33+
type: "string",
34+
title: "Interrupt Mode",
35+
enum: ["signal", "message"],
36+
},
37+
parameters: {
38+
type: "object",
39+
properties: {
40+
cores: { type: "string", enum: ["4", "6", "8"], title: "CPU Cores" },
41+
memory: {
42+
type: "string",
43+
enum: ["8GB", "16GB", "32GB"],
44+
title: "Memory",
45+
},
46+
},
47+
},
48+
metadata: { type: "object", title: "" },
2549
},
2650
required: [
2751
"argv",
@@ -40,7 +64,7 @@ export const iPySchema: JSONSchema7 = {
4064
* returns a ipyCardSchema.
4165
*/
4266
export const iPyCardSchema: JSONSchema7 = {
43-
title: "iPyKernel Manager",
67+
title: "iPyKernel Card",
4468
type: "array",
4569
items: {
4670
type: "object",

0 commit comments

Comments
 (0)