|
|
@@ -1,16 +1,17 @@
|
|
|
import React, { useCallback, useMemo } from "react";
|
|
|
import cronstrue from "cronstrue";
|
|
|
-import {Controller, useFormContext} from "react-hook-form";
|
|
|
+import { Controller, useFormContext } from "react-hook-form";
|
|
|
+import { match } from "ts-pattern";
|
|
|
|
|
|
+import Checkbox from "components/porter/Checkbox";
|
|
|
+import Container from "components/porter/Container";
|
|
|
import { ControlledInput } from "components/porter/ControlledInput";
|
|
|
+import Link from "components/porter/Link";
|
|
|
import Spacer from "components/porter/Spacer";
|
|
|
-import { PorterAppFormData } from "lib/porter-apps";
|
|
|
-import { ClientService } from "lib/porter-apps/services";
|
|
|
import Text from "components/porter/Text";
|
|
|
-import Link from "components/porter/Link";
|
|
|
-import Checkbox from "components/porter/Checkbox";
|
|
|
-import { match } from "ts-pattern";
|
|
|
import Tooltip from "components/porter/Tooltip";
|
|
|
+import { type PorterAppFormData } from "lib/porter-apps";
|
|
|
+import { type ClientService } from "lib/porter-apps/services";
|
|
|
|
|
|
type MainTabProps = {
|
|
|
index: number;
|
|
|
@@ -18,7 +19,11 @@ type MainTabProps = {
|
|
|
isPredeploy?: boolean;
|
|
|
};
|
|
|
|
|
|
-const MainTab: React.FC<MainTabProps> = ({ index, service, isPredeploy = false }) => {
|
|
|
+const MainTab: React.FC<MainTabProps> = ({
|
|
|
+ index,
|
|
|
+ service,
|
|
|
+ isPredeploy = false,
|
|
|
+}) => {
|
|
|
const { register, control, watch } = useFormContext<PorterAppFormData>();
|
|
|
const cron = watch(`app.services.${index}.config.cron.value`);
|
|
|
const run = watch(`app.services.${index}.run.value`);
|
|
|
@@ -56,16 +61,22 @@ const MainTab: React.FC<MainTabProps> = ({ index, service, isPredeploy = false }
|
|
|
return (
|
|
|
<>
|
|
|
<Spacer y={1} />
|
|
|
- {isRunCommandOptional ?
|
|
|
+ {isRunCommandOptional ? (
|
|
|
<Tooltip
|
|
|
- content={"If your Docker image has a CMD or ENTRYPOINT, you may leave this field empty."}
|
|
|
+ content={
|
|
|
+ "If your Docker image has a CMD or ENTRYPOINT, you may leave this field empty."
|
|
|
+ }
|
|
|
position={"right"}
|
|
|
>
|
|
|
<Text color="helper">Start command (optional)</Text>
|
|
|
</Tooltip>
|
|
|
- :
|
|
|
- <Text color="helper">Start command (required)</Text>
|
|
|
- }
|
|
|
+ ) : (
|
|
|
+ <Container row>
|
|
|
+ <Text>Start command</Text>
|
|
|
+ <Spacer inline x={0.2} />
|
|
|
+ <span style={{ color: "red" }}>*</span>
|
|
|
+ </Container>
|
|
|
+ )}
|
|
|
<Spacer y={0.5} />
|
|
|
<ControlledInput
|
|
|
type="text"
|
|
|
@@ -73,55 +84,62 @@ const MainTab: React.FC<MainTabProps> = ({ index, service, isPredeploy = false }
|
|
|
width="300px"
|
|
|
disabled={service.run.readOnly}
|
|
|
disabledTooltip={"You may only edit this field in your porter.yaml."}
|
|
|
- {...register(isPredeploy ? `app.predeploy.${index}.run.value` : `app.services.${index}.run.value`)}
|
|
|
+ {...register(
|
|
|
+ isPredeploy
|
|
|
+ ? `app.predeploy.${index}.run.value`
|
|
|
+ : `app.services.${index}.run.value`
|
|
|
+ )}
|
|
|
/>
|
|
|
- {isStartCommandValid &&
|
|
|
- <>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <Text color="warner">Chained commands are not supported at this time. To run multiple commands, move all commands into a script that can be run from a single endpoint (e.g. bash ./run.sh).</Text>
|
|
|
- </>
|
|
|
- }
|
|
|
- {match(service.config)
|
|
|
- .with({ type: "job" }, (jobConfig) => (
|
|
|
+ {isStartCommandValid && (
|
|
|
<>
|
|
|
- <Spacer y={1} />
|
|
|
- <ControlledInput
|
|
|
- type="text"
|
|
|
- label="Cron schedule"
|
|
|
- placeholder="ex: */5 * * * *"
|
|
|
- width="300px"
|
|
|
- disabled={jobConfig.cron.readOnly}
|
|
|
- disabledTooltip={
|
|
|
- "You may only edit this field in your porter.yaml."
|
|
|
- }
|
|
|
- {...register(`app.services.${index}.config.cron.value`)}
|
|
|
- />
|
|
|
-
|
|
|
- <Spacer y={0.5} />
|
|
|
- {getScheduleDescription(cron)}
|
|
|
<Spacer y={0.5} />
|
|
|
- <Controller
|
|
|
+ <Text color="warner">
|
|
|
+ Chained commands are not supported at this time. To run multiple
|
|
|
+ commands, move all commands into a script that can be run from a
|
|
|
+ single endpoint (e.g. bash ./run.sh).
|
|
|
+ </Text>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ {match(service.config)
|
|
|
+ .with({ type: "job" }, (jobConfig) => (
|
|
|
+ <>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <ControlledInput
|
|
|
+ type="text"
|
|
|
+ label="Cron schedule"
|
|
|
+ placeholder="ex: */5 * * * *"
|
|
|
+ width="300px"
|
|
|
+ disabled={jobConfig.cron.readOnly}
|
|
|
+ disabledTooltip={
|
|
|
+ "You may only edit this field in your porter.yaml."
|
|
|
+ }
|
|
|
+ {...register(`app.services.${index}.config.cron.value`)}
|
|
|
+ />
|
|
|
+
|
|
|
+ <Spacer y={0.5} />
|
|
|
+ {getScheduleDescription(cron)}
|
|
|
+ <Spacer y={0.5} />
|
|
|
+ <Controller
|
|
|
name={`app.services.${index}.config.suspendCron.value`}
|
|
|
control={control}
|
|
|
render={({ field: { value, onChange } }) => (
|
|
|
- <Checkbox
|
|
|
- checked={value}
|
|
|
- disabled={jobConfig.suspendCron?.readOnly}
|
|
|
- toggleChecked={() => {
|
|
|
- onChange(!value);
|
|
|
- }}
|
|
|
- disabledTooltip={
|
|
|
- "You may only edit this field in your porter.yaml."
|
|
|
- }
|
|
|
- >
|
|
|
- <Text color="helper">Suspend cron job</Text>
|
|
|
- </Checkbox>
|
|
|
+ <Checkbox
|
|
|
+ checked={value}
|
|
|
+ disabled={jobConfig.suspendCron?.readOnly}
|
|
|
+ toggleChecked={() => {
|
|
|
+ onChange(!value);
|
|
|
+ }}
|
|
|
+ disabledTooltip={
|
|
|
+ "You may only edit this field in your porter.yaml."
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Text color="helper">Suspend cron job</Text>
|
|
|
+ </Checkbox>
|
|
|
)}
|
|
|
- />
|
|
|
- </>
|
|
|
- ))
|
|
|
- .otherwise(() => null)
|
|
|
- }
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ ))
|
|
|
+ .otherwise(() => null)}
|
|
|
</>
|
|
|
);
|
|
|
};
|