import type { ReactIsland } from "@ethicdevs/react-monolith";
import React, { useCallback, useEffect, useState } from "react";
import type { Organization, ResourceVisibility } from "@prisma/client";
import type { WithThemeSchemeProp } from "../types";
import { slugify } from "../utils/shared";
import { Button, Card, Grid, Select, TextInput } from "../components";
export interface RepositoryForkFormProps {
disabled?: boolean;
availableParentOrgs: Organization[];
editMode?: boolean;
initialValues?: {
target_org_slug: string;
target_repo_display_name: string;
target_repo_slug: string;
target_repo_visibility: ResourceVisibility;
};
}
const RepositoryForkForm: ReactIsland<
RepositoryForkFormProps & WithThemeSchemeProp
> = ({
availableParentOrgs,
themeScheme,
disabled = false,
editMode = false,
initialValues = undefined,
}) => {
const [displayName, setDisplayName] = useState<string>(
initialValues?.target_repo_display_name || ""
);
const [slug, setSlug] = useState<string>(
initialValues?.target_repo_slug ||
slugify(initialValues?.target_repo_display_name || "")
);
const [slugInputDirty, setSlugInputDirty] = useState<boolean>(false);
editMode;
const onDisplayNameInputChange = useCallback(
(ev: React.ChangeEvent<HTMLInputElement>) => {
if (ev == null || ev.target == null || ev.target.value == null) {
return undefined;
}
setDisplayName(ev.target.value);
return undefined;
},
[setDisplayName]
);
const onSlugInputChange = useCallback(
(ev: React.ChangeEvent<HTMLInputElement>) => {
if (ev == null || ev.target == null || ev.target.value == null) {
return undefined;
}
setSlug(ev.target.value);
if (slugInputDirty === false) {
setSlugInputDirty(true);
}
return undefined;
},
[slugInputDirty, setSlug, setSlugInputDirty]
);
useEffect(() => {
const nextSlug = slugify(displayName);
if (
slugInputDirty === false &&
displayName != null &&
displayName.trim() !== "" &&
nextSlug !== slug
) {
setSlug(nextSlug);
}
}, [displayName, slug, slugInputDirty, setSlug]);
return (
<Grid.Col fluid nowrap gap={24}>
<Grid.Col fluid nowrap gap={8}>
<label>
<strong>Fork details</strong>
</label>
<Card themeScheme={themeScheme}>
<Grid.Col fluid nowrap gap={16}>
{}
<Grid.Col fluid nowrap gap={4}>
<label htmlFor={"target_repo_display_name"}>
Repository Name<span style={{ color: "red" }}>*</span>:
</label>
<TextInput
themeScheme={themeScheme}
name={"target_repo_display_name"}
disabled={disabled}
onChange={onDisplayNameInputChange}
placeholder={"i.e. My Super Project"}
required
style={styles.inputMaxWidth}
type={"text"}
value={displayName}
/>
</Grid.Col>
<Grid.Row fluid nowrap alignItems={"center"} gap={16}>
{}
<Grid.Col fluid nowrap gap={4}>
<label htmlFor={"target_org_slug"}>
Owner Organization<span style={{ color: "red" }}>*</span>:
</label>
<Select
themeScheme={themeScheme}
disabled={disabled}
defaultValue={
availableParentOrgs.length >= 1
? availableParentOrgs[0].slug
: initialValues?.target_org_slug
}
name={"target_org_slug"}
required
style={styles.inputMaxWidth}
>
{availableParentOrgs.map((org) => (
<option key={org.id} value={org.slug}>
{org.displayName || org.slug}
</option>
))}
</Select>
</Grid.Col>
{}
<Grid.Col fluid nowrap gap={4}>
<label htmlFor={"target_repo_slug"}>
Repository Slug<span style={{ color: "red" }}>*</span>:
</label>
<TextInput
themeScheme={themeScheme}
name={"target_repo_slug"}
disabled={disabled}
onChange={onSlugInputChange}
placeholder={"i.e. my-super-project"}
required
style={styles.inputMaxWidth}
type={"text"}
value={slug}
/>
</Grid.Col>
</Grid.Row>
{}
<Grid.Col fluid nowrap gap={4}>
<label htmlFor={"target_repo_visibility"}>
Repository Visibility<span style={{ color: "red" }}>*</span>:
</label>
<Select
themeScheme={themeScheme}
disabled={disabled}
defaultValue={
initialValues?.target_repo_visibility || "PRIVATE"
}
name={"target_repo_visibility"}
style={styles.inputMaxWidth}
>
<option key={"private"} value={"PRIVATE"}>
Private
</option>
<option key={"unlisted"} value={"UNLISTED"}>
Unlisted
</option>
<option key={"public"} value={"PUBLIC"}>
Public
</option>
</Select>
</Grid.Col>
</Grid.Col>
</Card>
</Grid.Col>
{}
<Button style={styles.inputMaxWidth} type={"submit"} disabled={disabled}>
Fork Repository!
</Button>
</Grid.Col>
);
};
const styles = {
alignSelfEnd: {
alignSelf: "flex-end",
},
inputMaxWidth: {
minWidth: "100%",
width: "100%",
maxWidth: "100%",
},
labelFlexOne: {
flex: 1,
marginRight: 8,
},
shortDescriptionTextArea: {
minHeight: 75,
height: 75,
maxHeight: 75,
},
};
RepositoryForkForm.displayName = "RepositoryForkForm";
export default RepositoryForkForm;