mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
[WEB-756] chore: module and cycle feature toggle validation (#4112)
* chore: cycle and module feature issue block validation * chore: cycle and module feature display properties validation * chore: cycle and module feature display filters validation * chore: cycle and module feature project view validation
This commit is contained in:
parent
bc0752f7e8
commit
e9518ced89
@ -10,7 +10,7 @@ import { CustomMenu } from "@plane/ui";
|
||||
import { ProjectAnalyticsModal } from "@/components/analytics";
|
||||
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues";
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue";
|
||||
import { useIssues, useCycle, useProjectState, useLabel, useMember } from "@/hooks/store";
|
||||
import { useIssues, useCycle, useProjectState, useLabel, useMember, useProject } from "@/hooks/store";
|
||||
|
||||
export const CycleMobileHeader = () => {
|
||||
const [analyticsModal, setAnalyticsModal] = useState(false);
|
||||
@ -24,6 +24,7 @@ export const CycleMobileHeader = () => {
|
||||
const { workspaceSlug, projectId, cycleId } = router.query;
|
||||
const cycleDetails = cycleId ? getCycleById(cycleId.toString()) : undefined;
|
||||
// store hooks
|
||||
const { currentProjectDetails } = useProject();
|
||||
const {
|
||||
issuesFilter: { issueFilters, updateFilters },
|
||||
} = useIssues(EIssuesStoreType.CYCLE);
|
||||
@ -151,6 +152,8 @@ export const CycleMobileHeader = () => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
@ -174,6 +177,8 @@ export const CycleMobileHeader = () => {
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
ignoreGroupedFilters={["cycle"]}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -250,6 +250,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
<FiltersDropdown title="Display" placement="bottom-end">
|
||||
@ -262,6 +264,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
ignoreGroupedFilters={["cycle"]}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
|
||||
|
@ -252,6 +252,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
<FiltersDropdown title="Display" placement="bottom-end">
|
||||
@ -264,6 +266,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
ignoreGroupedFilters={["module"]}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -141,6 +141,8 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
<FiltersDropdown title="Display" placement="bottom-end">
|
||||
@ -152,6 +154,8 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
|
||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -192,6 +192,8 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
<FiltersDropdown title="Display" placement="bottom-end">
|
||||
@ -203,6 +205,8 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -210,6 +210,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
<FiltersDropdown title="Display" placement="bottom-end">
|
||||
@ -221,6 +223,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
{canUserCreateIssue && (
|
||||
|
@ -9,13 +9,14 @@ import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/com
|
||||
// constants
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue";
|
||||
// hooks
|
||||
import { useIssues, useLabel, useMember, useProjectState } from "@/hooks/store";
|
||||
import { useIssues, useLabel, useMember, useProject, useProjectState } from "@/hooks/store";
|
||||
|
||||
export const ArchivedIssuesHeader: FC = observer(() => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
// store hooks
|
||||
const { currentProjectDetails } = useProject();
|
||||
const {
|
||||
issuesFilter: { issueFilters, updateFilters },
|
||||
} = useIssues(EIssuesStoreType.ARCHIVED);
|
||||
@ -89,6 +90,8 @@ export const ArchivedIssuesHeader: FC = observer(() => {
|
||||
layoutDisplayFiltersOptions={
|
||||
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
||||
}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -21,6 +21,8 @@ type Props = {
|
||||
handleDisplayPropertiesUpdate: (updatedDisplayProperties: Partial<IIssueDisplayProperties>) => void;
|
||||
layoutDisplayFiltersOptions: ILayoutDisplayFiltersOptions | undefined;
|
||||
ignoreGroupedFilters?: Partial<TIssueGroupByOptions>[];
|
||||
cycleViewDisabled?: boolean;
|
||||
moduleViewDisabled?: boolean;
|
||||
};
|
||||
|
||||
export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
|
||||
@ -31,17 +33,32 @@ export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
|
||||
handleDisplayPropertiesUpdate,
|
||||
layoutDisplayFiltersOptions,
|
||||
ignoreGroupedFilters = [],
|
||||
cycleViewDisabled = false,
|
||||
moduleViewDisabled = false,
|
||||
} = props;
|
||||
|
||||
const isDisplayFilterEnabled = (displayFilter: keyof IIssueDisplayFilterOptions) =>
|
||||
Object.keys(layoutDisplayFiltersOptions?.display_filters ?? {}).includes(displayFilter);
|
||||
|
||||
const computedIgnoreGroupedFilters: Partial<TIssueGroupByOptions>[] = [];
|
||||
if (cycleViewDisabled) {
|
||||
ignoreGroupedFilters.push("cycle");
|
||||
}
|
||||
if (moduleViewDisabled) {
|
||||
ignoreGroupedFilters.push("module");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="vertical-scrollbar scrollbar-sm relative h-full w-full divide-y divide-custom-border-200 overflow-hidden overflow-y-auto px-2.5">
|
||||
{/* display properties */}
|
||||
{layoutDisplayFiltersOptions?.display_properties && (
|
||||
<div className="py-2">
|
||||
<FilterDisplayProperties displayProperties={displayProperties} handleUpdate={handleDisplayPropertiesUpdate} />
|
||||
<FilterDisplayProperties
|
||||
displayProperties={displayProperties}
|
||||
handleUpdate={handleDisplayPropertiesUpdate}
|
||||
cycleViewDisabled={cycleViewDisabled}
|
||||
moduleViewDisabled={moduleViewDisabled}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -56,7 +73,7 @@ export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
|
||||
group_by: val,
|
||||
})
|
||||
}
|
||||
ignoreGroupedFilters={ignoreGroupedFilters}
|
||||
ignoreGroupedFilters={[...ignoreGroupedFilters, ...computedIgnoreGroupedFilters]}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@ -74,7 +91,7 @@ export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
|
||||
})
|
||||
}
|
||||
subGroupByOptions={layoutDisplayFiltersOptions?.display_filters.sub_group_by ?? []}
|
||||
ignoreGroupedFilters={ignoreGroupedFilters}
|
||||
ignoreGroupedFilters={[...ignoreGroupedFilters, ...computedIgnoreGroupedFilters]}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -10,13 +10,22 @@ import { FilterHeader } from "../helpers/filter-header";
|
||||
type Props = {
|
||||
displayProperties: IIssueDisplayProperties;
|
||||
handleUpdate: (updatedDisplayProperties: Partial<IIssueDisplayProperties>) => void;
|
||||
cycleViewDisabled?: boolean;
|
||||
moduleViewDisabled?: boolean;
|
||||
};
|
||||
|
||||
export const FilterDisplayProperties: React.FC<Props> = observer((props) => {
|
||||
const { displayProperties, handleUpdate } = props;
|
||||
const { displayProperties, handleUpdate, cycleViewDisabled = false, moduleViewDisabled = false } = props;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
// Filter out "cycle" and "module" keys if cycleViewDisabled or moduleViewDisabled is true
|
||||
const filteredDisplayProperties = ISSUE_DISPLAY_PROPERTIES.filter((property) => {
|
||||
if (cycleViewDisabled && property.key === "cycle") return false;
|
||||
if (moduleViewDisabled && property.key === "modules") return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<FilterHeader
|
||||
@ -26,23 +35,25 @@ export const FilterDisplayProperties: React.FC<Props> = observer((props) => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="mt-1 flex flex-wrap items-center gap-2">
|
||||
{ISSUE_DISPLAY_PROPERTIES.map((displayProperty) => (
|
||||
<button
|
||||
key={displayProperty.key}
|
||||
type="button"
|
||||
className={`rounded border px-2 py-0.5 text-xs transition-all ${
|
||||
displayProperties?.[displayProperty.key]
|
||||
? "border-custom-primary-100 bg-custom-primary-100 text-white"
|
||||
: "border-custom-border-200 hover:bg-custom-background-80"
|
||||
}`}
|
||||
onClick={() =>
|
||||
handleUpdate({
|
||||
[displayProperty.key]: !displayProperties?.[displayProperty.key],
|
||||
})
|
||||
}
|
||||
>
|
||||
{displayProperty.title}
|
||||
</button>
|
||||
{filteredDisplayProperties.map((displayProperty) => (
|
||||
<>
|
||||
<button
|
||||
key={displayProperty.key}
|
||||
type="button"
|
||||
className={`rounded border px-2 py-0.5 text-xs transition-all ${
|
||||
displayProperties?.[displayProperty.key]
|
||||
? "border-custom-primary-100 bg-custom-primary-100 text-white"
|
||||
: "border-custom-border-200 hover:bg-custom-background-80"
|
||||
}`}
|
||||
onClick={() =>
|
||||
handleUpdate({
|
||||
[displayProperty.key]: !displayProperties?.[displayProperty.key],
|
||||
})
|
||||
}
|
||||
>
|
||||
{displayProperty.title}
|
||||
</button>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
@ -30,10 +30,21 @@ type Props = {
|
||||
labels?: IIssueLabel[] | undefined;
|
||||
memberIds?: string[] | undefined;
|
||||
states?: IState[] | undefined;
|
||||
cycleViewDisabled?: boolean;
|
||||
moduleViewDisabled?: boolean;
|
||||
};
|
||||
|
||||
export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||
const { filters, handleFiltersUpdate, layoutDisplayFiltersOptions, labels, memberIds, states } = props;
|
||||
const {
|
||||
filters,
|
||||
handleFiltersUpdate,
|
||||
layoutDisplayFiltersOptions,
|
||||
labels,
|
||||
memberIds,
|
||||
states,
|
||||
cycleViewDisabled = false,
|
||||
moduleViewDisabled = false,
|
||||
} = props;
|
||||
// hooks
|
||||
const {
|
||||
router: { moduleId, cycleId },
|
||||
@ -111,7 +122,7 @@ export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||
)}
|
||||
|
||||
{/* cycle */}
|
||||
{isFilterEnabled("cycle") && !cycleId && (
|
||||
{isFilterEnabled("cycle") && !cycleId && !cycleViewDisabled && (
|
||||
<div className="py-2">
|
||||
<FilterCycle
|
||||
appliedFilters={filters.cycle ?? null}
|
||||
@ -122,7 +133,7 @@ export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||
)}
|
||||
|
||||
{/* module */}
|
||||
{isFilterEnabled("module") && !moduleId && (
|
||||
{isFilterEnabled("module") && !moduleId && !moduleViewDisabled && (
|
||||
<div className="py-2">
|
||||
<FilterModule
|
||||
appliedFilters={filters.module ?? null}
|
||||
|
@ -24,7 +24,7 @@ import { EIssuesStoreType } from "@/constants/issue";
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper";
|
||||
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
|
||||
import { useEventTracker, useEstimate, useLabel, useIssues, useProjectState } from "@/hooks/store";
|
||||
import { useEventTracker, useEstimate, useLabel, useIssues, useProjectState, useProject } from "@/hooks/store";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// components
|
||||
import { IssuePropertyLabels } from "../properties/labels";
|
||||
@ -45,6 +45,7 @@ export interface IIssueProperties {
|
||||
export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
const { issue, updateIssue, displayProperties, activeLayout, isReadOnly, className } = props;
|
||||
// store hooks
|
||||
const { getProjectById } = useProject();
|
||||
const { labelMap } = useLabel();
|
||||
const { captureIssueEvent } = useEventTracker();
|
||||
const {
|
||||
@ -56,6 +57,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
const { areEstimatesEnabledForCurrentProject } = useEstimate();
|
||||
const { getStateById } = useProjectState();
|
||||
const { isMobile } = usePlatformOS();
|
||||
const projectDetails = getProjectById(issue.project_id);
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
@ -349,36 +351,40 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
</WithDisplayPropertiesHOC>
|
||||
|
||||
{/* modules */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="modules">
|
||||
<div className="h-5">
|
||||
<ModuleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
value={issue?.module_ids ?? []}
|
||||
onChange={handleModule}
|
||||
disabled={isReadOnly}
|
||||
multiple
|
||||
buttonVariant="border-with-text"
|
||||
showCount
|
||||
showTooltip
|
||||
/>
|
||||
</div>
|
||||
</WithDisplayPropertiesHOC>
|
||||
{projectDetails?.module_view && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="modules">
|
||||
<div className="h-5">
|
||||
<ModuleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
value={issue?.module_ids ?? []}
|
||||
onChange={handleModule}
|
||||
disabled={isReadOnly}
|
||||
multiple
|
||||
buttonVariant="border-with-text"
|
||||
showCount
|
||||
showTooltip
|
||||
/>
|
||||
</div>
|
||||
</WithDisplayPropertiesHOC>
|
||||
)}
|
||||
|
||||
{/* cycles */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="cycle">
|
||||
<div className="h-5">
|
||||
<CycleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
value={issue?.cycle_id}
|
||||
onChange={handleCycle}
|
||||
disabled={isReadOnly}
|
||||
buttonVariant="border-with-text"
|
||||
showTooltip
|
||||
/>
|
||||
</div>
|
||||
</WithDisplayPropertiesHOC>
|
||||
{projectDetails?.cycle_view && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="cycle">
|
||||
<div className="h-5">
|
||||
<CycleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
value={issue?.cycle_id}
|
||||
onChange={handleCycle}
|
||||
disabled={isReadOnly}
|
||||
buttonVariant="border-with-text"
|
||||
showTooltip
|
||||
/>
|
||||
</div>
|
||||
</WithDisplayPropertiesHOC>
|
||||
)}
|
||||
|
||||
{/* estimates */}
|
||||
{areEstimatesEnabledForCurrentProject && (
|
||||
|
@ -132,6 +132,8 @@ export const IssuesMobileHeader = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
@ -154,6 +156,8 @@ export const IssuesMobileHeader = observer(() => {
|
||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -11,12 +11,13 @@ import { ProjectAnalyticsModal } from "@/components/analytics";
|
||||
import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues";
|
||||
// hooks
|
||||
import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue";
|
||||
import { useIssues, useLabel, useMember, useModule, useProjectState } from "@/hooks/store";
|
||||
import { useIssues, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store";
|
||||
// types
|
||||
// constants
|
||||
|
||||
export const ModuleMobileHeader = observer(() => {
|
||||
const [analyticsModal, setAnalyticsModal] = useState(false);
|
||||
const { currentProjectDetails } = useProject();
|
||||
const { getModuleById } = useModule();
|
||||
const layouts = [
|
||||
{ key: "list", title: "List", icon: List },
|
||||
@ -134,6 +135,8 @@ export const ModuleMobileHeader = observer(() => {
|
||||
labels={projectLabels}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
@ -157,6 +160,8 @@ export const ModuleMobileHeader = observer(() => {
|
||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||
ignoreGroupedFilters={["module"]}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ import { IProjectView, IIssueFilterOptions } from "@plane/types";
|
||||
import { Button, Input, TextArea } from "@plane/ui";
|
||||
import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "@/components/issues";
|
||||
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue";
|
||||
import { useLabel, useMember, useProjectState } from "@/hooks/store";
|
||||
import { useLabel, useMember, useProject, useProjectState } from "@/hooks/store";
|
||||
// components
|
||||
// ui
|
||||
// types
|
||||
@ -27,6 +27,7 @@ const defaultValues: Partial<IProjectView> = {
|
||||
export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
||||
const { handleFormSubmit, handleClose, data, preLoadedData } = props;
|
||||
// store hooks
|
||||
const { currentProjectDetails } = useProject();
|
||||
const { projectStates } = useProjectState();
|
||||
const { projectLabels } = useLabel();
|
||||
const {
|
||||
@ -184,6 +185,8 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
||||
labels={projectLabels ?? undefined}
|
||||
memberIds={projectMemberIds ?? undefined}
|
||||
states={projectStates}
|
||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||
/>
|
||||
</FiltersDropdown>
|
||||
)}
|
||||
@ -212,8 +215,8 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
||||
? "Updating View..."
|
||||
: "Update View"
|
||||
: isSubmitting
|
||||
? "Creating View..."
|
||||
: "Create View"}
|
||||
? "Creating View..."
|
||||
: "Create View"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue
Block a user