[WEB-3788] improvement: enhance project properties related components modularity (#6882)

* improvement: work item modal data preload and parent work item details

* improvement: collapsible button title

* improvement: project creation form and modal

* improvement: emoji helper

* improvement: enhance labels component modularity

* improvement: enable state group and state list components modularity

* improvement: project settings feature list

* improvement: common utils
This commit is contained in:
Prateek Shourya 2025-04-09 14:50:43 +05:30 committed by GitHub
parent 670134562f
commit 1f9222065e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 622 additions and 381 deletions

View file

@ -19,6 +19,7 @@ type Props = {
setToFavorite?: boolean;
workspaceSlug: string;
data?: Partial<TProject>;
templateId?: string;
};
enum EProjectCreationSteps {
@ -27,7 +28,7 @@ enum EProjectCreationSteps {
}
export const CreateProjectModal: FC<Props> = (props) => {
const { isOpen, onClose, setToFavorite = false, workspaceSlug, data } = props;
const { isOpen, onClose, setToFavorite = false, workspaceSlug, data, templateId } = props;
// states
const [currentStep, setCurrentStep] = useState<EProjectCreationSteps>(EProjectCreationSteps.CREATE_PROJECT);
const [createdProjectId, setCreatedProjectId] = useState<string | null>(null);
@ -63,6 +64,7 @@ export const CreateProjectModal: FC<Props> = (props) => {
updateCoverImageStatus={handleCoverImageStatusUpdate}
handleNextStep={handleNextStep}
data={data}
templateId={templateId}
/>
)}
{currentStep === EProjectCreationSteps.FEATURE_SELECTION && (

View file

@ -14,6 +14,8 @@ import { ImagePickerPopover } from "@/components/core";
import { convertHexEmojiToDecimal } from "@/helpers/emoji.helper";
import { getFileURL } from "@/helpers/file.helper";
import { getTabIndex } from "@/helpers/tab-indices.helper";
// plane web imports
import { ProjectTemplateSelect } from "@/plane-web/components/projects/create/template-select";
type Props = {
handleClose: () => void;
@ -39,6 +41,9 @@ const ProjectCreateHeader: React.FC<Props> = (props) => {
/>
)}
<div className="absolute left-2.5 top-2.5">
<ProjectTemplateSelect handleModalClose={handleClose} />
</div>
<div className="absolute right-2 top-2 p-2">
<button data-posthog="PROJECT_MODAL_CLOSE" type="button" onClick={handleClose} tabIndex={getIndex("close")}>
<X className="h-5 w-5 text-white" />

View file

@ -59,58 +59,51 @@ export const ProjectFeaturesList: FC<Props> = observer((props) => {
return (
<div className="space-y-6">
{Object.keys(PROJECT_FEATURES_LIST).map((featureSectionKey) => {
const feature = PROJECT_FEATURES_LIST[featureSectionKey];
return (
<div key={featureSectionKey} className="">
<div className="flex flex-col justify-center pb-2 border-b border-custom-border-100">
<h3 className="text-xl font-medium">{t(feature.key)}</h3>
<h4 className="text-sm leading-5 text-custom-text-200">{t(`${feature.key}_description`)}</h4>
</div>
{Object.keys(feature.featureList).map((featureItemKey) => {
const featureItem = feature.featureList[featureItemKey];
return (
<div
key={featureItemKey}
className="gap-x-8 gap-y-2 border-b border-custom-border-100 bg-custom-background-100 pb-2 pt-4"
>
<div key={featureItemKey} className="flex items-center justify-between">
<div className="flex items-start gap-3">
<div className="flex items-center justify-center rounded bg-custom-background-90 p-3">
{featureItem.icon}
</div>
<div>
<div className="flex items-center gap-2">
<h4 className="text-sm font-medium leading-5">{t(featureItem.key)}</h4>
{featureItem.isPro && (
<Tooltip tooltipContent="Pro feature" position="top">
<UpgradeBadge className="rounded" />
</Tooltip>
)}
</div>
<p className="text-sm leading-5 tracking-tight text-custom-text-300">
{t(`${featureItem.key}_description`)}
</p>
</div>
</div>
<ToggleSwitch
value={Boolean(currentProjectDetails?.[featureItem.property as keyof IProject])}
onChange={() => handleSubmit(featureItemKey, featureItem.property)}
disabled={!featureItem.isEnabled || !isAdmin}
size="sm"
/>
{Object.entries(PROJECT_FEATURES_LIST).map(([featureSectionKey, feature]) => (
<div key={featureSectionKey} className="">
<div className="flex flex-col justify-center pb-2 border-b border-custom-border-100">
<h3 className="text-xl font-medium">{t(feature.key)}</h3>
<h4 className="text-sm leading-5 text-custom-text-200">{t(`${feature.key}_description`)}</h4>
</div>
{Object.entries(feature.featureList).map(([featureItemKey, featureItem]) => (
<div
key={featureItemKey}
className="gap-x-8 gap-y-2 border-b border-custom-border-100 bg-custom-background-100 pb-2 pt-4"
>
<div key={featureItemKey} className="flex items-center justify-between">
<div className="flex items-start gap-3">
<div className="flex items-center justify-center rounded bg-custom-background-90 p-3">
{featureItem.icon}
</div>
<div className="pl-14">
{currentProjectDetails?.[featureItem.property as keyof IProject] &&
featureItem.renderChildren?.(currentProjectDetails, workspaceSlug)}
<div>
<div className="flex items-center gap-2">
<h4 className="text-sm font-medium leading-5">{t(featureItem.key)}</h4>
{featureItem.isPro && (
<Tooltip tooltipContent="Pro feature" position="top">
<UpgradeBadge className="rounded" />
</Tooltip>
)}
</div>
<p className="text-sm leading-5 tracking-tight text-custom-text-300">
{t(`${featureItem.key}_description`)}
</p>
</div>
</div>
);
})}
</div>
);
})}
<ToggleSwitch
value={Boolean(currentProjectDetails?.[featureItem.property as keyof IProject])}
onChange={() => handleSubmit(featureItemKey, featureItem.property)}
disabled={!featureItem.isEnabled || !isAdmin}
size="sm"
/>
</div>
<div className="pl-14">
{currentProjectDetails?.[featureItem.property as keyof IProject] &&
featureItem.renderChildren?.(currentProjectDetails, workspaceSlug)}
</div>
</div>
))}
</div>
))}
</div>
);
});