Skip to content

Commit

Permalink
feat: added concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
mikededo committed Aug 13, 2023
1 parent 49d5e5b commit f1ccd15
Show file tree
Hide file tree
Showing 18 changed files with 304 additions and 59 deletions.
81 changes: 81 additions & 0 deletions src/apps/editor/components/box-concurrency/box-concurrency.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { useRef } from 'react';

import {
Draggable,
DraggableTitle,
DraggableWrapper,
Input,
Label,
Toggle,
VCol,
} from '@/aero';
import { Positions } from '@/editor/config';
import { useOptionalSection, useWorkflowConcurrency } from '@/editor/stores';

import { Max } from './max';

export const ConcurrencyContent = React.forwardRef<HTMLDivElement>((_, ref) => {
const {
concurrency: { cancelInProgress, group },
onChangeGroup,
toggleCancelInProgress,
} = useWorkflowConcurrency();

const handleOnChangeGroup = (e: React.ChangeEvent<HTMLInputElement>) => {
onChangeGroup(e.target.value);
};

return (
<DraggableWrapper>
<VCol
ref={ref}
variant="md"
className="relative px-3 pb-3"
align="between"
>
<DraggableWrapper>
<Toggle
text="Cancel in progress"
value={cancelInProgress}
onClick={toggleCancelInProgress}
/>
<VCol variant="md">
<Label className="text-muted-foreground">Group</Label>
<Input
placeholder="workflow-name"
value={group}
onChange={handleOnChangeGroup}
/>
</VCol>
<Max />
<Label className="text-muted-foreground">
Matrix (available soon)
</Label>
</DraggableWrapper>
</VCol>
</DraggableWrapper>
);
});

export const BoxConcurrency: React.FC = () => {
const innerRef = useRef(null);
const { osConcurrency } = useOptionalSection('osConcurrency');

return osConcurrency ? (
<DraggableWrapper>
<Draggable
innerRef={innerRef}
initialX={Positions.BoxEnvX}
initialY={Positions.BoxEnvY}
visible={({ ref, onExpand }) => (
<DraggableWrapper>
<div ref={ref}>
<DraggableTitle title="Concurrency" onExpand={onExpand} />
</div>
</DraggableWrapper>
)}
invisible={({ ref }) => <ConcurrencyContent ref={ref} />}
/>
</DraggableWrapper>
) : null;
};
1 change: 1 addition & 0 deletions src/apps/editor/components/box-concurrency/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BoxConcurrency } from './box-concurrency';
27 changes: 27 additions & 0 deletions src/apps/editor/components/box-concurrency/max.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

import { Input, Label, VCol } from '@/aero';
import { useAdvancedInput } from '@/editor/hooks';
import { useWorkflowConcurrency } from '@/editor/stores';

export const Max: React.FC = () => {
const {
concurrency: { max },
onChangeMax,
} = useWorkflowConcurrency();

const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChangeMax(+e.target.value);
};

const { onKeyDown } = useAdvancedInput(String(max), {
numOnly: true,
});

return (
<VCol variant="md">
<Label className="text-muted-foreground">Max</Label>
<Input onKeyDown={onKeyDown} onChange={handleOnChange} placeholder="2" />
</VCol>
);
};
5 changes: 5 additions & 0 deletions src/apps/editor/components/features/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const FeatureList: Parameters<typeof Feature>[0][] = [
title: 'Dark theme',
description: 'Enables the dark theme mode, by enabling the toggler.',
},
{
feature: 'fsConcurrency',
title: 'Concurrency',
description: 'Enables the concurrency configuration for the workflow',
},
{
feature: 'fsCopyAction',
title: 'Copy action',
Expand Down
1 change: 1 addition & 0 deletions src/apps/editor/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { BoxConcurrency } from './box-concurrency';
export { BoxEnv } from './box-env';
export { BoxName } from './box-name';
export { BoxPermissions } from './box-permissions';
Expand Down
6 changes: 6 additions & 0 deletions src/apps/editor/components/news/news.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { New } from './new';
import { useNews } from './use-news';

const NewsList: NewItem[] = [
{
title: 'Added support for concurrency',
description:
'Now you can add concurrency to your workflow. The feature has to be enabled through a feature switch.',
date: new Date('2023-08-13'),
},
{
title: 'Added support for environment variables',
description:
Expand Down
63 changes: 34 additions & 29 deletions src/apps/editor/components/optional-sections/optional-sections.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,45 @@
import React from 'react';

import { AppearTransition, Label, VCol } from '@/aero';
import { useFeatureSwitch } from '@/editor/stores';

import { OptionalSection } from './optional-section';

type Props = {
show?: boolean;
};

export const OptionalSections: React.FC<Props> = ({ show = false }) => (
<AppearTransition as={React.Fragment} show={show}>
<div className="absolute transition-all top-14 w-[300px] min-h-[140px] bg-card px-3 py-2 border rounded-lg -translate-x-1/4">
<VCol variant="md">
<VCol variant="xs">
<p className="font-semibold">Enabled sections</p>
<Label>
There are some configurations that are not strictly required, such
as the pemissions. In case you want to show them, enable them
through this menu.
</Label>
</VCol>
<VCol className="w-full" align="between">
<OptionalSection text="Permissions" section="osPermissions" />
<OptionalSection text="Env" section="osEnv" />
<OptionalSection
text="Defaults (coming soon)"
section="osDefaults"
disabled
/>
<OptionalSection
text="Concurrency (coming soon)"
section="osConcurrency"
disabled
/>
export const OptionalSections: React.FC<Props> = ({ show = false }) => {
const { fsConcurrency } = useFeatureSwitch('fsConcurrency');

return (
<AppearTransition as={React.Fragment} show={show}>
<div className="absolute transition-all top-14 w-[300px] min-h-[140px] bg-card px-3 py-2 border rounded-lg -translate-x-1/4">
<VCol variant="md">
<VCol variant="xs">
<p className="font-semibold">Enabled sections</p>
<Label>
There are some configurations that are not strictly required, such
as the pemissions. In case you want to show them, enable them
through this menu.
</Label>
</VCol>
<VCol className="w-full" align="between">
<OptionalSection text="Permissions" section="osPermissions" />
<OptionalSection text="Env" section="osEnv" />
<OptionalSection
text="Defaults (coming soon)"
section="osDefaults"
disabled
/>
<OptionalSection
text={`Concurrency ${!fsConcurrency ? '(coming soon)' : ''}`}
section="osConcurrency"
disabled={!fsConcurrency}
/>
</VCol>
</VCol>
</VCol>
</div>
</AppearTransition>
);
</div>
</AppearTransition>
);
};
1 change: 1 addition & 0 deletions src/apps/editor/components/visualiser/sections/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './workflow-basics';
export * from './workflow-concurrency';
export * from './workflow-env';
export * from './workflow-jobs';
export * from './workflow-permissions';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

import { Keyword, Line, Tabbed } from '@/aero';
import { useWorkflowConcurrency } from '@/editor/stores';

export const WorkflowConcurrency: React.FC = () => {
const {
concurrency: { cancelInProgress, group, max },
} = useWorkflowConcurrency();

const anyConcurrency = cancelInProgress || group !== '' || max > 0;
if (!anyConcurrency) {
return null;
}

return (
<>
<Line>
<Keyword>concurrency</Keyword>:
</Line>
{cancelInProgress ? (
<Tabbed tabs={2}>
<Keyword>cancel-in-progress</Keyword>: true
</Tabbed>
) : null}
{group !== '' ? (
<Tabbed tabs={2}>
<Keyword>group</Keyword>: {group}
</Tabbed>
) : null}
{max > 0 ? (
<Tabbed tabs={2}>
<Keyword>max</Keyword>: {max}
</Tabbed>
) : null}
</>
);
};
2 changes: 2 additions & 0 deletions src/apps/editor/components/visualiser/visualiser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { VCol } from '@/aero';
import { Content, Footer, Header, Main } from './layout';
import {
WorkflowBasics,
WorkflowConcurrency,
WorkflowEnv,
WorkflowJobs,
WorkflowPermissions,
Expand All @@ -20,6 +21,7 @@ export const Visualiser: React.FC = () => (
<WorkflowTriggers />
<WorkflowEnv />
<WorkflowPermissions />
<WorkflowConcurrency />
<WorkflowJobs />
</Main>
<Footer />
Expand Down
6 changes: 5 additions & 1 deletion src/apps/editor/domain/feature-switches.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export type FeatureSwitches = 'fsGlobalDrag' | 'fsDarkTheme' | 'fsCopyAction';
export type FeatureSwitches =
| 'fsGlobalDrag'
| 'fsDarkTheme'
| 'fsCopyAction'
| 'fsConcurrency';
7 changes: 7 additions & 0 deletions src/apps/editor/hooks/use-advanced-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type SideEffectHelpers = {
};
type Options = {
tabCount?: [number, number];
numOnly?: boolean;
};
type SideEffects = {
onEnterPress?: (value: string, helpers: SideEffectHelpers) => void;
Expand All @@ -25,6 +26,7 @@ export const useAdvancedInput = (
initialValue: string,
{
tabCount: [minTabCount, maxTabCount] = [-Infinity, Infinity],
numOnly,
onEnterPress,
onTabPress,
onShiftTabPress,
Expand All @@ -45,6 +47,11 @@ export const useAdvancedInput = (
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
const helpers = { onResetInput };

if (numOnly && !/^[0-9]+$/.test(e.key) && e.key !== 'Backspace') {
e.preventDefault();
return;
}

if (e.key === 'Enter') {
e.preventDefault();
onEnterPress?.(e.currentTarget.value, helpers);
Expand Down
1 change: 1 addition & 0 deletions src/apps/editor/stores/global-state/feature-switches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const featureSwitchesStore: StateCreator<
fsGlobalDrag: LSFeatureSwitches?.fsGlobalDrag ?? false,
fsDarkTheme: LSFeatureSwitches?.fsDarkTheme ?? false,
fsCopyAction: LSFeatureSwitches?.fsCopyAction ?? false,
fsConcurrency: LSFeatureSwitches?.fsConcurrency ?? false,
activeFSCount: Object.values(LSFeatureSwitches ?? {}).reduce(
(count, active) => count + +active,
0,
Expand Down
20 changes: 19 additions & 1 deletion src/apps/editor/stores/global-state/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,28 @@ export type WorkflowEnvActions = {
};
export type WorkflowEnvStore = WorkflowEnvState & WorkflowEnvActions;

export type WorkflowConcurrencyState = {
concurrency: {
cancelInProgress: boolean;
group: string;
max: number;
// TODO: Add matrix
};
};
export type WorkflowConcurrencyActions = {
toggleCancelInProgress: Empty;
onChangeGroup: Single<string>;
onChangeMax: Single<number>;
// TODO: Add matrix
};
export type WorkflowConcurrencyStore = WorkflowConcurrencyState &
WorkflowConcurrencyActions;

export type GlobalStore = FeatureSwitchesStore &
OptionalSectionsStore &
GlobalDragStore &
WorkflowBasicsStore &
WorkflowTriggersStore &
WorkflowPermissionsStore &
WorkflowEnvStore;
WorkflowEnvStore &
WorkflowConcurrencyStore;
12 changes: 12 additions & 0 deletions src/apps/editor/stores/global-state/use-global-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { globalDragStore } from './global-drag';
import { optionalSectionsStore } from './optional-sections';
import type { Empty, GlobalStore } from './types';
import { workflowBasicsStore } from './workflow-basics';
import { workflowConcurrencyStore } from './workflow-concurrency';
import { workflowEnvStore } from './workflow-env';
import { worfklowPermissionsStore } from './workflow-permissions';
import { workflowTriggersStore } from './workflow-triggers';
Expand All @@ -20,6 +21,7 @@ const globalStore = create<GlobalStore>()((...args) => ({
...workflowTriggersStore(...args),
...worfklowPermissionsStore(...args),
...workflowEnvStore(...args),
...workflowConcurrencyStore(...args),
}));

export const useFeatureSwitch = <FS extends FeatureSwitches>(
Expand Down Expand Up @@ -140,3 +142,13 @@ export const useWorkflowEnv = () =>
addVariable,
deleteVariable,
}));

export const useWorkflowConcurrency = () =>
globalStore(
({ concurrency, toggleCancelInProgress, onChangeMax, onChangeGroup }) => ({
concurrency,
toggleCancelInProgress,
onChangeMax,
onChangeGroup,
}),
);
Loading

0 comments on commit f1ccd15

Please sign in to comment.