@canmingir/link 1.2.23 → 1.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/src/Platform.jsx +10 -14
- package/src/context/Context.js +98 -0
- package/src/context/reducer.js +590 -10
- package/src/layouts/auth/modern.jsx +2 -2
- package/src/lib/APIDialogAction/APIDialogAction.jsx +109 -0
- package/src/lib/APIDialogAction/index.js +1 -0
- package/src/lib/APIDialogAction/styles.js +6 -0
- package/src/lib/APIParams/APIParams.jsx +57 -0
- package/src/lib/APIParams/index.js +1 -0
- package/src/lib/APIPath/APIPath.jsx +82 -0
- package/src/lib/APIPath/index.js +1 -0
- package/src/lib/APIPath/styles.js +19 -0
- package/src/lib/APITree/APITree.jsx +409 -0
- package/src/lib/APITree/Arrow.jsx +21 -0
- package/src/lib/APITree/DeleteMethodDialog.jsx +41 -0
- package/src/lib/APITree/index.js +1 -0
- package/src/lib/APITree/styles.js +19 -0
- package/src/lib/APITypes/APITypes.jsx +141 -0
- package/src/lib/APITypes/TypeEditor.jsx +46 -0
- package/src/lib/APITypes/TypeList.jsx +180 -0
- package/src/lib/APITypes/index.js +1 -0
- package/src/lib/BlankTreeMessage/BlankTreeMessage.jsx +39 -0
- package/src/lib/BlankTreeMessage/index.js +1 -0
- package/src/lib/DialogTootip/DialogTooltip.jsx +67 -0
- package/src/lib/DialogTootip/index.js +1 -0
- package/src/lib/DialogTootip/styles.js +9 -0
- package/src/lib/NewApiBody/NewAPIBody.jsx +97 -0
- package/src/lib/NewApiBody/ParamView.jsx +38 -0
- package/src/lib/NucDialog/NucDialog.jsx +108 -0
- package/src/lib/NucDialog/index.js +1 -0
- package/src/lib/ParamTable/ParamTable.jsx +133 -0
- package/src/lib/ParamTable/TypeMenu.jsx +102 -0
- package/src/lib/ParamTable/defaults.js +47 -0
- package/src/lib/ParamTable/index.js +1 -0
- package/src/lib/ParamTable/styles.js +12 -0
- package/src/lib/ResourceMenu/AlertMassage.jsx +28 -0
- package/src/lib/ResourceMenu/DeleteResourceDialog.jsx +60 -0
- package/src/lib/ResourceMenu/ResourceMenu.jsx +156 -0
- package/src/lib/ResourceMenu/index.js +1 -0
- package/src/lib/ResourceMenu/styles.js +5 -0
- package/src/lib/Schema/Schema.jsx +204 -0
- package/src/lib/Schema/index.js +1 -0
- package/src/lib/SchemaEditor/SchemaEditor.jsx +258 -0
- package/src/lib/SchemaEditor/SchemaEditor.test.js +193 -0
- package/src/lib/SchemaEditor/SchemaPropertyEditor.jsx +135 -0
- package/src/lib/SchemaEditor/SchemaUtils.js +152 -0
- package/src/lib/SchemaEditor/index.js +1 -0
- package/src/lib/ToggleableMenu/ToggleableMenu.jsx +35 -0
- package/src/lib/ToggleableMenu/index.js +1 -0
- package/src/lib/index.js +14 -0
- package/src/pages/Callback.jsx +2 -4
- package/src/pages/LoginPage.jsx +3 -12
- package/src/stories/APITree.stories.jsx +429 -0
- package/src/stories/FlowChart.stories.jsx +1 -1
- package/src/templates/ActionTemplate.js +24 -0
- package/src/widgets/Login/CognitoLogin.jsx +2 -2
- package/src/widgets/Login/DemoLogin.jsx +1 -1
- package/src/widgets/LoginForm/LoginForm.jsx +8 -3
- package/src/widgets/SettingsDialog.jsx +33 -11
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Box, Input, MenuItem, Select, Typography } from "@mui/material";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
|
|
4
|
+
const SchemaPropertyEditor = ({
|
|
5
|
+
node,
|
|
6
|
+
onNameChange,
|
|
7
|
+
disableNameChange,
|
|
8
|
+
onTypeChange,
|
|
9
|
+
customTypes,
|
|
10
|
+
}) => {
|
|
11
|
+
const [editMode, setEditMode] = useState(null);
|
|
12
|
+
const [name, setName] = useState(node.name || "");
|
|
13
|
+
const [type, setType] = useState(node.type);
|
|
14
|
+
const [isSelectOpen, setIsSelectOpen] = useState(false);
|
|
15
|
+
|
|
16
|
+
const handleNameChange = (newName) => {
|
|
17
|
+
setName(newName);
|
|
18
|
+
onNameChange(newName);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleTypeChange = (newType) => {
|
|
22
|
+
setType(newType);
|
|
23
|
+
onTypeChange(newType);
|
|
24
|
+
setEditMode(null);
|
|
25
|
+
setIsSelectOpen(false);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const isRootNode = node.level === 0;
|
|
29
|
+
|
|
30
|
+
const propertyTypes = isRootNode
|
|
31
|
+
? ["object", "array", ...customTypes.map((type) => type.name)]
|
|
32
|
+
: [
|
|
33
|
+
"string",
|
|
34
|
+
"number",
|
|
35
|
+
"boolean",
|
|
36
|
+
"object",
|
|
37
|
+
"array",
|
|
38
|
+
...customTypes.map((type) => type.name),
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Box
|
|
43
|
+
sx={{
|
|
44
|
+
display: "flex",
|
|
45
|
+
justifyContent: "space-between",
|
|
46
|
+
width: "100%",
|
|
47
|
+
gap: "4px",
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
{!disableNameChange ? (
|
|
51
|
+
<Box
|
|
52
|
+
sx={{
|
|
53
|
+
display: "flex",
|
|
54
|
+
justifyContent: "space-between",
|
|
55
|
+
width: "100%",
|
|
56
|
+
gap: "4px",
|
|
57
|
+
}}
|
|
58
|
+
onClick={() => {
|
|
59
|
+
setEditMode("name");
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
<Input
|
|
63
|
+
value={name}
|
|
64
|
+
onChange={(e) => handleNameChange(e.target.value)}
|
|
65
|
+
disableUnderline
|
|
66
|
+
fullWidth
|
|
67
|
+
sx={{
|
|
68
|
+
borderBottom: "2px solid transparent",
|
|
69
|
+
"&:hover": {
|
|
70
|
+
borderBottom: "2px solid gray",
|
|
71
|
+
},
|
|
72
|
+
"&:focus": {
|
|
73
|
+
borderBottom: "2px solid blue",
|
|
74
|
+
},
|
|
75
|
+
}}
|
|
76
|
+
data-cy={`property-name-field-${node.id}`}
|
|
77
|
+
/>
|
|
78
|
+
</Box>
|
|
79
|
+
) : (
|
|
80
|
+
<Box
|
|
81
|
+
sx={{
|
|
82
|
+
width: "100%",
|
|
83
|
+
display: "flex",
|
|
84
|
+
alignItems: "center",
|
|
85
|
+
}}
|
|
86
|
+
></Box>
|
|
87
|
+
)}
|
|
88
|
+
|
|
89
|
+
{editMode === "type" ? (
|
|
90
|
+
<Select
|
|
91
|
+
open={isSelectOpen}
|
|
92
|
+
value={type}
|
|
93
|
+
onChange={(e) => handleTypeChange(e.target.value)}
|
|
94
|
+
onClose={() => {
|
|
95
|
+
setEditMode(null);
|
|
96
|
+
setIsSelectOpen(false);
|
|
97
|
+
}}
|
|
98
|
+
onOpen={() => setIsSelectOpen(true)}
|
|
99
|
+
>
|
|
100
|
+
{propertyTypes.map((typeOption) => (
|
|
101
|
+
<MenuItem
|
|
102
|
+
value={typeOption}
|
|
103
|
+
key={typeOption}
|
|
104
|
+
data-cy={`property-type-option-${typeOption}`}
|
|
105
|
+
>
|
|
106
|
+
{typeOption}
|
|
107
|
+
</MenuItem>
|
|
108
|
+
))}
|
|
109
|
+
</Select>
|
|
110
|
+
) : (
|
|
111
|
+
<Box sx={{ display: "flex", alignItems: "center", cursor: "pointer" }}>
|
|
112
|
+
<Typography
|
|
113
|
+
variant="body2"
|
|
114
|
+
onClick={() => {
|
|
115
|
+
setEditMode("type");
|
|
116
|
+
setIsSelectOpen(true);
|
|
117
|
+
}}
|
|
118
|
+
sx={{
|
|
119
|
+
cursor: "pointer",
|
|
120
|
+
borderRadius: "4px",
|
|
121
|
+
"&:hover": {
|
|
122
|
+
backgroundColor: (theme) => theme.palette.grey[600],
|
|
123
|
+
},
|
|
124
|
+
}}
|
|
125
|
+
data-cy={`property-type-select-${node.id}`}
|
|
126
|
+
>
|
|
127
|
+
{node.type}
|
|
128
|
+
</Typography>
|
|
129
|
+
</Box>
|
|
130
|
+
)}
|
|
131
|
+
</Box>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export default SchemaPropertyEditor;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
|
|
3
|
+
export const getTypeStyle = (type) => {
|
|
4
|
+
return {
|
|
5
|
+
fontWeight: "normal",
|
|
6
|
+
color: getTypeColor(type),
|
|
7
|
+
marginLeft: "auto",
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const getTypeColor = (type) => {
|
|
12
|
+
switch (type) {
|
|
13
|
+
case "object":
|
|
14
|
+
return "red";
|
|
15
|
+
case "string":
|
|
16
|
+
return "green";
|
|
17
|
+
case "integer":
|
|
18
|
+
return "blue";
|
|
19
|
+
|
|
20
|
+
default:
|
|
21
|
+
return "black";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const addProperty = (parentId = null, setSchemaData) => {
|
|
26
|
+
const addPropertyToNode = (node, parentId) => {
|
|
27
|
+
if (node.id === parentId) {
|
|
28
|
+
const propertyCount = node.properties ? node.properties.length : 0;
|
|
29
|
+
const newName = propertyCount === 0 ? "id" : `prop${propertyCount + 1}`;
|
|
30
|
+
const newType = "string";
|
|
31
|
+
|
|
32
|
+
const newProperty = {
|
|
33
|
+
name: newName,
|
|
34
|
+
type: newType,
|
|
35
|
+
id: uuidv4(),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const updatedProperties = node.properties
|
|
39
|
+
? [...node.properties, newProperty]
|
|
40
|
+
: [newProperty];
|
|
41
|
+
|
|
42
|
+
return { ...node, properties: updatedProperties };
|
|
43
|
+
} else if (node.properties) {
|
|
44
|
+
const updatedProperties = node.properties.map((childNode) =>
|
|
45
|
+
addPropertyToNode(childNode, parentId)
|
|
46
|
+
);
|
|
47
|
+
return { ...node, properties: updatedProperties };
|
|
48
|
+
}
|
|
49
|
+
return node;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
setSchemaData((currentData) => {
|
|
53
|
+
if (!parentId) {
|
|
54
|
+
const propertyCount = currentData.properties
|
|
55
|
+
? currentData.properties.length
|
|
56
|
+
: 0;
|
|
57
|
+
const newName = propertyCount === 0 ? "id" : `prop${propertyCount + 1}`;
|
|
58
|
+
const newType = "string";
|
|
59
|
+
|
|
60
|
+
const newProperty = {
|
|
61
|
+
name: newName,
|
|
62
|
+
type: newType,
|
|
63
|
+
id: uuidv4(),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const updatedProperties = currentData.properties
|
|
67
|
+
? [...currentData.properties, newProperty]
|
|
68
|
+
: [newProperty];
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
...currentData,
|
|
72
|
+
properties: updatedProperties,
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
return addPropertyToNode(currentData, parentId);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const removeProperty = (propertyId, setSchemaData) => {
|
|
81
|
+
const removePropertyFromNode = (node, propertyId) => {
|
|
82
|
+
if (node.id === propertyId) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (node.properties) {
|
|
86
|
+
const updatedProperties = node.properties
|
|
87
|
+
.map((childNode) => removePropertyFromNode(childNode, propertyId))
|
|
88
|
+
.filter((childNode) => childNode !== null);
|
|
89
|
+
|
|
90
|
+
return { ...node, properties: updatedProperties };
|
|
91
|
+
}
|
|
92
|
+
return node;
|
|
93
|
+
};
|
|
94
|
+
setSchemaData((currentData) => {
|
|
95
|
+
const updatedProperties = currentData.properties
|
|
96
|
+
.map((node) => removePropertyFromNode(node, propertyId))
|
|
97
|
+
.filter((node) => node !== null);
|
|
98
|
+
const updatedData = { ...currentData, properties: updatedProperties };
|
|
99
|
+
|
|
100
|
+
return updatedData;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
export const changeProperty = (propertyId, changes, setSchemaData) => {
|
|
104
|
+
const updateProperty = (node, propertyId, changes) => {
|
|
105
|
+
if (node.id === propertyId || propertyId === "1") {
|
|
106
|
+
const updatedNode = {
|
|
107
|
+
...node,
|
|
108
|
+
name: changes.name,
|
|
109
|
+
type: changes.type,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
if (changes.type === "object") {
|
|
113
|
+
if (!updatedNode.properties || updatedNode.properties.length === 0) {
|
|
114
|
+
updatedNode.properties = [
|
|
115
|
+
{
|
|
116
|
+
name: "id",
|
|
117
|
+
type: "string",
|
|
118
|
+
id: uuidv4(),
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
} else if (changes.type === "array") {
|
|
123
|
+
if (!updatedNode.properties || updatedNode.properties.length === 0) {
|
|
124
|
+
updatedNode.properties = [
|
|
125
|
+
{
|
|
126
|
+
name: "item",
|
|
127
|
+
type: "string",
|
|
128
|
+
id: uuidv4(),
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
} else {
|
|
132
|
+
updatedNode.properties = updatedNode.properties.slice(0, 1);
|
|
133
|
+
}
|
|
134
|
+
} else if (changes.type !== "object" && changes.type !== "array") {
|
|
135
|
+
delete updatedNode.properties;
|
|
136
|
+
}
|
|
137
|
+
return updatedNode;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (node.properties) {
|
|
141
|
+
const updatedProperties = node.properties.map((childNode) =>
|
|
142
|
+
updateProperty(childNode, propertyId, changes)
|
|
143
|
+
);
|
|
144
|
+
return { ...node, properties: updatedProperties };
|
|
145
|
+
}
|
|
146
|
+
return node;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
setSchemaData((currentData) => {
|
|
150
|
+
return updateProperty(currentData, propertyId, changes);
|
|
151
|
+
});
|
|
152
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./SchemaEditor";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Box, ClickAwayListener, IconButton } from "@mui/material";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
|
|
4
|
+
function ToggleableMenu({ defaultIcon, children }) {
|
|
5
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6
|
+
|
|
7
|
+
const handleDefaultIconClick = (event) => {
|
|
8
|
+
event.stopPropagation();
|
|
9
|
+
setIsOpen(!isOpen);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const handleClose = () => {
|
|
13
|
+
setIsOpen(false);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const handleMenuItemClick = (event) => {
|
|
17
|
+
event.stopPropagation();
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ClickAwayListener onClickAway={handleClose}>
|
|
22
|
+
<Box>
|
|
23
|
+
{isOpen ? (
|
|
24
|
+
<Box onClick={handleMenuItemClick}>{children}</Box>
|
|
25
|
+
) : (
|
|
26
|
+
<IconButton size="small" onClick={handleDefaultIconClick}>
|
|
27
|
+
{defaultIcon}
|
|
28
|
+
</IconButton>
|
|
29
|
+
)}
|
|
30
|
+
</Box>
|
|
31
|
+
</ClickAwayListener>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default ToggleableMenu;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ToggleableMenu";
|
package/src/lib/index.js
CHANGED
|
@@ -34,3 +34,17 @@ export {
|
|
|
34
34
|
export { default as ActionNode } from "./Flow/layouts/ActionNode";
|
|
35
35
|
|
|
36
36
|
export { default as InfoNode } from "./Flow/layouts/InfoNode";
|
|
37
|
+
|
|
38
|
+
export { default as APITree, compile as compileAPITree } from "./APITree";
|
|
39
|
+
export { default as APIDialogAction } from "./APIDialogAction";
|
|
40
|
+
export { default as APIParams } from "./APIParams";
|
|
41
|
+
export { default as APIPath } from "./APIPath";
|
|
42
|
+
export { default as APITypes } from "./APITypes";
|
|
43
|
+
export { default as BlankTreeMessage } from "./BlankTreeMessage";
|
|
44
|
+
export { default as DialogTooltip } from "./DialogTootip";
|
|
45
|
+
export { default as NucDialog } from "./NucDialog";
|
|
46
|
+
export { default as ParamTable } from "./ParamTable";
|
|
47
|
+
export { default as ResourceMenu } from "./ResourceMenu";
|
|
48
|
+
export { default as Schema } from "./Schema";
|
|
49
|
+
export { default as SchemaEditor } from "./SchemaEditor";
|
|
50
|
+
export { default as ToggleableMenu } from "./ToggleableMenu";
|
package/src/pages/Callback.jsx
CHANGED
|
@@ -2,9 +2,9 @@ import Page from "../layouts/Page";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import config from "../config/config";
|
|
4
4
|
import oauth from "../http/oauth";
|
|
5
|
+
import { publish } from "@nucleoidai/react-event";
|
|
5
6
|
import qs from "qs";
|
|
6
7
|
import { storage } from "@nucleoidjs/webstorage";
|
|
7
|
-
import { useContext } from "../ContextProvider/ContextProvider";
|
|
8
8
|
import { useLocation } from "react-router-dom";
|
|
9
9
|
import { useNavigate } from "react-router-dom";
|
|
10
10
|
|
|
@@ -15,7 +15,6 @@ function Callback() {
|
|
|
15
15
|
const projectBar = config().template?.projectBar;
|
|
16
16
|
|
|
17
17
|
const { google, github, linkedin } = appConfig;
|
|
18
|
-
const [, dispatch] = useContext();
|
|
19
18
|
const location = useLocation();
|
|
20
19
|
const navigate = useNavigate();
|
|
21
20
|
const hasProcessed = useRef(false);
|
|
@@ -91,14 +90,13 @@ function Callback() {
|
|
|
91
90
|
.then(({ data }) => {
|
|
92
91
|
const accessToken = data.accessToken;
|
|
93
92
|
const refreshToken = data.refreshToken;
|
|
94
|
-
const userInfo = data.user;
|
|
95
93
|
|
|
96
94
|
storage.set("link", "accessToken", accessToken);
|
|
97
95
|
storage.set("link", "refreshToken", refreshToken);
|
|
98
96
|
// TODO - update provider info
|
|
99
97
|
storage.set("link", "identityProvider", identityProvider);
|
|
100
98
|
|
|
101
|
-
|
|
99
|
+
publish("LOGIN", { data: data });
|
|
102
100
|
|
|
103
101
|
window.history.replaceState(
|
|
104
102
|
{},
|
package/src/pages/LoginPage.jsx
CHANGED
|
@@ -30,20 +30,11 @@ function LoginPage() {
|
|
|
30
30
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
31
|
}, [navigate]);
|
|
32
32
|
|
|
33
|
-
if (credentials?.provider === "COGNITO") {
|
|
34
|
-
return <CognitoLogin />;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (credentials?.provider === "DEMO") {
|
|
38
|
-
return (
|
|
39
|
-
<Page title={`Sign in to ${name}`}>
|
|
40
|
-
<DemoLogin />
|
|
41
|
-
</Page>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
33
|
return (
|
|
46
34
|
<Page title={`Sign in to ${name}`}>
|
|
35
|
+
{credentials?.provider === "COGNITO" && <CognitoLogin />}
|
|
36
|
+
{credentials?.provider === "DEMO" && <DemoLogin />}
|
|
37
|
+
|
|
47
38
|
<LoginForm icon={template.login.icon} name={name} formColor={formColor} />
|
|
48
39
|
</Page>
|
|
49
40
|
);
|