Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-756] chore: module and cycle feature toggle validation #4112

Merged
merged 5 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion web/components/cycles/cycle-mobile-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -151,6 +152,8 @@ export const CycleMobileHeader = () => {
labels={projectLabels}
memberIds={projectMemberIds ?? undefined}
states={projectStates}
cycleViewDisabled={!currentProjectDetails?.cycle_view}
moduleViewDisabled={!currentProjectDetails?.module_view}
/>
</FiltersDropdown>
</div>
Expand All @@ -174,6 +177,8 @@ export const CycleMobileHeader = () => {
displayProperties={issueFilters?.displayProperties ?? {}}
handleDisplayPropertiesUpdate={handleDisplayProperties}
ignoreGroupedFilters={["cycle"]}
cycleViewDisabled={!currentProjectDetails?.cycle_view}
moduleViewDisabled={!currentProjectDetails?.module_view}
/>
</FiltersDropdown>
</div>
Expand Down
4 changes: 4 additions & 0 deletions web/components/headers/cycle-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>

Expand Down
4 changes: 4 additions & 0 deletions web/components/headers/module-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>
Expand Down
4 changes: 4 additions & 0 deletions web/components/headers/project-draft-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>
Expand Down
4 changes: 4 additions & 0 deletions web/components/headers/project-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>
Expand Down
4 changes: 4 additions & 0 deletions web/components/headers/project-view-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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 && (
Expand Down
5 changes: 4 additions & 1 deletion web/components/issues/archived-issues-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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>
)}

Expand All @@ -56,7 +73,7 @@ export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
group_by: val,
})
}
ignoreGroupedFilters={ignoreGroupedFilters}
ignoreGroupedFilters={[...ignoreGroupedFilters, ...computedIgnoreGroupedFilters]}
/>
</div>
)}
Expand All @@ -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>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down Expand Up @@ -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}
Expand All @@ -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}
Expand Down