Skip to content
This repository was archived by the owner on Jun 13, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"homepage": "https://circleci-public.github.io/visual-config-editor/",
"dependencies": {
"@circleci/circleci-config-sdk": "0.5.0-alpha.10",
"@circleci/circleci-config-sdk": "0.5.0-alpha.11",
"@craco/craco": "^6.3.0",
"@monaco-editor/react": "^4.3.1",
"@testing-library/jest-dom": "^5.11.4",
Expand Down Expand Up @@ -33,6 +33,9 @@
"uuid": "^8.3.2",
"web-vitals": "^2.1.2"
},
"resolutions": {
"@types/react": "^17.0.38"
},
"scripts": {
"start": "craco start",
"build": "craco build",
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import NavigationPane from './components/panes/NavigationPane';
import WorkflowsPane from './components/panes/WorkflowsPane';
import Store from './state/Store';

// Workaround for https://github.com/ctrlplusb/easy-peasy/issues/741
// const StoreProviderOverride = StoreProvider as any;

const App = () => {
return (
Expand Down
26 changes: 26 additions & 0 deletions src/components/atoms/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export interface CardProps {
description?: string;
title: string;
pinned?: React.ReactElement;
onClick: React.MouseEventHandler<HTMLButtonElement>;
}

const Card = (props: CardProps) => {
return (
<button
type="button"
className="p-4 mb-4 w-full border-circle-gray-300 border-2 rounded text-left"
onClick={props.onClick}
>
<div className="flex flex-row">
<p className="font-bold">{props.title}</p>
<div className="ml-auto z-10">{props.pinned}</div>
</div>
<p className="text-sm mt-1 leading-4 text-circle-gray-500">
{props.description}
</p>
</button>
);
};

export default Card;
16 changes: 12 additions & 4 deletions src/components/atoms/ComponentInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ import ComponentMapping from '../../mappings/ComponentMapping';

const ComponentInfo = (props: { type: ComponentMapping }) => {
return (
<>
<p className="font-medium text-sm text-circle-gray-500">{props.type.docsInfo.description}</p>
<a className="ml-auto tracking-wide hover:underline leading-6 text-sm text-circle-blue font-medium" href={props.type.docsInfo.link}>Learn More</a><br></br>
</>
<div className="pb-4">
<p className="font-medium text-sm text-circle-gray-500">
{props.type.docsInfo.description}
</p>
<a
className="ml-auto tracking-wide hover:underline leading-6 text-sm text-circle-blue font-medium"
href={props.type.docsInfo.link}
target="circleci_docs"
>
Learn More
</a>
</div>
);
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/atoms/Definition.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ComponentMapping from '../../mappings/ComponentMapping';
import { useStoreActions } from '../../state/Hooks';
import EditDefinitionMenu from '../menus/definitions/EditDefinitionMenu';
import { InspectorDefinitionMenuNav } from '../menus/definitions/InspectorDefinitionMenu';

const Definition = (props: { data: any; type: ComponentMapping }) => {
const Summary = props.type.components.summary;
Expand All @@ -21,8 +21,8 @@ const Definition = (props: { data: any; type: ComponentMapping }) => {
}}
onClick={(e) => {
navigateTo({
component: EditDefinitionMenu,
props: { data: props.data, dataType: props.type },
component: InspectorDefinitionMenuNav,
props: { editing: true, values: props.data, dataType: props.type },
});
}}
>
Expand Down
40 changes: 40 additions & 0 deletions src/components/atoms/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { MutableRefObject, ReactElement, useEffect, useState } from 'react';
import ToolTipPointerIcon from '../../icons/ui/ToolTipPointerIcon';

export interface ToolTipProps {
target: MutableRefObject<any>;
pointerColor?: string;
pointerClass?: string;
offsetX?: number;
offsetY?: number;
centered?: boolean;
facing?: 'top' | 'bottom' | 'left' | 'right';
children: ReactElement;
}

const ToolTip = (props: ToolTipProps) => {
const [pos, setPos] = useState({ left: 0, top: 0 });

const updatePos = () => {
const rect = props.target.current.getBoundingClientRect();

setPos({ left: rect.x - rect.width - 32, top: rect.y + 6 });
};

useEffect(() => {
updatePos();
});

return (
<div style={pos} className="fixed flex z-10">
{props.children}
<ToolTipPointerIcon
color="#FFFFFF"
className="h-3 mt-4"
direction="right"
/>
</div>
);
};

export default ToolTip;
34 changes: 9 additions & 25 deletions src/components/atoms/nodes/JobNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const JobNode: React.FunctionComponent<NodeProps & { data: WorkflowJob }> = (
// );
const updateJob = useStoreActions((actions) => actions.updateJob);
const setConnecting = useStoreActions((actions) => actions.setConnecting);
const removeWorkflowElement = useStoreActions((actions) => actions.removeWorkflowElement);

const connecting = useStoreState((state) => state.connecting);
const updateConnecting = useStoreActions(
(actions) => actions.updateConnecting,
Expand Down Expand Up @@ -72,27 +74,6 @@ const JobNode: React.FunctionComponent<NodeProps & { data: WorkflowJob }> = (

const nodeRef = useRef(null);

// const onConnect = (params: Connection) => {
// const targetJob = elements.find(
// (element) => element.id === params.target,
// )?.data;

// setWorkflowElements(
// addEdge(
// {
// ...params,
// animated: false,
// style: { stroke: '#A3A3A3', strokeWidth: '2px' },
// },
// updateWorkflowJob(targetJob, {
// parameters: {
// requires: [props.data.job.name],
// },
// }),
// ),
// );
// };

return (
<div
className={`p-8 flex flex-row cursor-default`}
Expand Down Expand Up @@ -171,17 +152,20 @@ const JobNode: React.FunctionComponent<NodeProps & { data: WorkflowJob }> = (
<JobIcon className="w-5 mr-2" />
{props.data.parameters?.name || props.data.job.name}
</div>
<div
<button
className={`my-auto
opacity-${hovering['node'] ? 100 : 0}
transition-opacity duration-150 w-8 h-full flex`}
{...trackHovering(['remove'], ['remove'])}
onClick={() => {
removeWorkflowElement(props.id);
}}
>
<DeleteItemIcon
className="w-3 cursor-pointer m-auto"
color={hovering['remove'] ? 'red' : '#AAAAAA'}
/>
</div>
</button>
</button>

<button
Expand Down Expand Up @@ -218,12 +202,12 @@ const JobNode: React.FunctionComponent<NodeProps & { data: WorkflowJob }> = (

<Handle
type="source"
className="opacity-0"
className="opacity-0 cursor-default"
position={Position.Right}
id={`${props.id}_source`}
></Handle>
<Handle
className="opacity-0"
className="opacity-0 cursor-default"
id={`${props.id}_target`}
type="target"
position={Position.Left}
Expand Down
24 changes: 15 additions & 9 deletions src/components/containers/DefinitionsContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { useRef } from 'react';
import ComponentMapping from '../../mappings/ComponentMapping';
import { useStoreActions, useStoreState } from '../../state/Hooks';
import CollapsibleList from './CollapsibleList';
import ComponentInfo from '../atoms/ComponentInfo';
import Definition from '../atoms/Definition';
import {
CreateDefinitionMenu,
CreateDefinitionMenuNav,
} from '../menus/definitions/CreateDefinitionMenu';
InspectorDefinitionMenu,
InspectorDefinitionMenuNav,
} from '../menus/definitions/InspectorDefinitionMenu';
import SubTypeMenuNav from '../menus/SubTypeMenu';
import ComponentInfo from '../atoms/ComponentInfo';
import CollapsibleList from './CollapsibleList';
import GuideContainer from './GuideContainer';

export interface DefinitionsProps {
type: ComponentMapping;
Expand All @@ -18,10 +20,14 @@ export interface DefinitionsProps {
const DefinitionsContainer = (props: DefinitionsProps) => {
const items = useStoreState(props.type.store.get);
const navigateTo = useStoreActions((actions) => actions.navigateTo);
const guideStep = useStoreState((state) => state.guideStep);
const ref = useRef(null);

console.log(props, 'props')
return (
<div className="w-full p-4 pb-0">
<div ref={ref} className="w-full p-4 pb-0">
{props.type.guide && guideStep === props.type.guide.step && (
<GuideContainer target={ref}>{props.type.guide.info}</GuideContainer>
)}
<CollapsibleList
title={props.type.name.plural}
expanded={props.expanded}
Expand All @@ -35,12 +41,12 @@ const DefinitionsContainer = (props: DefinitionsProps) => {
component: SubTypeMenuNav,
props: {
typePage: props.type.subtypes?.component,
menuPage: CreateDefinitionMenu,
menuPage: InspectorDefinitionMenu,
menuProps: { dataType: props.type },
},
}
: {
component: CreateDefinitionMenuNav,
component: InspectorDefinitionMenuNav,
props: { dataType: props.type },
},
)
Expand Down
38 changes: 38 additions & 0 deletions src/components/containers/GuideContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MutableRefObject } from 'react';
import InfoIcon from '../../icons/ui/InfoIcon';
import { useStoreState } from '../../state/Hooks';
import ToolTip from '../atoms/Tooltip';

export interface GuideContainerProps {
target: MutableRefObject<any>;
children: string;
}

const GuideContainer = (props: GuideContainerProps) => {
const guideStep = useStoreState((state) => state.guideStep);

return (
<ToolTip target={props.target}>
<div className="w-80 p-4 bg-white drop-shadow-lg rounded-lg">
<div className="flex flex-row">
<InfoIcon className="w-5 h-5" color="#000000"></InfoIcon>
<div className="px-3 w-full">
<header className="pb-3 font-bold leading-5">
Step {guideStep} of 3
</header>
<div className="font-medium text-sm text-circle-gray-500 whitespace-pre-line">
{props.children}
</div>
<div className="w-full flex flex-row pt-2">
<button className=" ml-auto tracking-wide hover:underline leading-6 text-sm text-circle-blue font-medium">
Dismiss
</button>
</div>
</div>
</div>
</div>
</ToolTip>
);
};

export default GuideContainer;
4 changes: 2 additions & 2 deletions src/components/containers/ParametersContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FieldArray, useField } from 'formik';
import ComponentMapping from '../../mappings/ComponentMapping';
import ParameterMapping from '../../mappings/ParameterMapping';
import { useStoreActions } from '../../state/Hooks';
import { CreateDefinitionMenu } from '../menus/definitions/CreateDefinitionMenu';
import { InspectorDefinitionMenu } from '../menus/definitions/InspectorDefinitionMenu';
import SubTypeMenuNav from '../menus/SubTypeMenu';

const ParameterContainer = (props: {
Expand All @@ -26,7 +26,7 @@ const ParameterContainer = (props: {
props: {
typePage: ParameterMapping.subtypes?.component,
typeProps: { component: props.dataMapping },
menuPage: CreateDefinitionMenu,
menuPage: InspectorDefinitionMenu,
menuProps: {
dataType: ParameterMapping,
passBackKey: 'parameters',
Expand Down
4 changes: 0 additions & 4 deletions src/components/containers/WorkflowContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ const WorkflowPane = (props: ElementProps) => {
applyToData: (parameters: WorkflowJobParameters) => WorkflowJobParameters,
) =>
elements.map((element) => {
console.log(
(element.data.parameters?.name || element.data.job.name) === targetJob,
);

return isNode(element) &&
JobMapping.node?.transform &&
(element.data.parameters?.name || element.data.job.name) === targetJob
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { executor } from '@circleci/circleci-config-sdk';
import { DockerExecutor, MachineExecutor, MacOSExecutor, WindowsExecutor } from '@circleci/circleci-config-sdk/dist/src/lib/Components/Executor';
import { SubTypeMapping } from '../../../../mappings/ComponentMapping';
import InspectorProperty from '../../../atoms/form/InspectorProperty';

Expand All @@ -10,6 +12,7 @@ export interface ExecutorSubTypes {
const executorSubtypes: ExecutorSubTypes = {
docker: {
text: 'Docker',
component: executor.DockerExecutor,
resourceClasses: [
'small',
'medium',
Expand All @@ -27,13 +30,15 @@ const executorSubtypes: ExecutorSubTypes = {
},
machine: {
text: 'Machine',
component: executor.MachineExecutor,
resourceClasses: ['medium', 'large', 'xlarge', '2xlarge'],
fields: <InspectorProperty label="Image" name="executor.image" required />,
docsLink: 'https://circleci.com/docs/2.0/executor-types/#using-machine',
description: 'Steps run on Linux Virtual Machine',
},
macos: {
text: 'MacOS',
component: executor.MacOSExecutor,
resourceClasses: ['medium', 'large'],
fields: <InspectorProperty label="Xcode" name="executor.xcode" required />,
docsLink: 'https://circleci.com/docs/2.0/executor-types/#using-macos',
Expand All @@ -42,6 +47,7 @@ const executorSubtypes: ExecutorSubTypes = {
},
windows: {
text: 'Windows',
component: executor.WindowsExecutor,
resourceClasses: ['medium', 'large', 'xlarge', '2xlarge'],
fields: <InspectorProperty label="Image" name="executor.image" required />,
docsLink: 'https://circleci.com/docs/2.0/executor-types/#using-the-windows-executor',
Expand Down
Loading