feat: init
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
chuan
2025-11-11 01:56:44 +08:00
commit bba4bb40c8
4638 changed files with 447437 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
import { useCallback } from "react";
// plane imports
import type { TExtendedFileHandler } from "@plane/editor";
export type TExtendedEditorFileHandlersArgs = {
projectId?: string;
workspaceSlug: string;
};
export type TExtendedEditorConfig = {
getExtendedEditorFileHandlers: (args: TExtendedEditorFileHandlersArgs) => TExtendedFileHandler;
};
export const useExtendedEditorConfig = (): TExtendedEditorConfig => {
const getExtendedEditorFileHandlers: TExtendedEditorConfig["getExtendedEditorFileHandlers"] = useCallback(
() => ({}),
[]
);
return {
getExtendedEditorFileHandlers,
};
};

View File

@@ -0,0 +1,2 @@
export * from "./use-pages-pane-extensions";
export * from "./use-extended-editor-extensions";

View File

@@ -0,0 +1,20 @@
import type { IEditorPropsExtended } from "@plane/editor";
import type { TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
import type { TPageInstance } from "@/store/pages/base-page";
import type { EPageStoreType } from "../store";
export type TExtendedEditorExtensionsHookParams = {
workspaceSlug: string;
page: TPageInstance;
storeType: EPageStoreType;
fetchEntity: (payload: TSearchEntityRequestPayload) => Promise<TSearchResponse>;
getRedirectionLink: (pageId?: string) => string;
extensionHandlers?: Map<string, unknown>;
projectId?: string;
};
export type TExtendedEditorExtensionsConfig = IEditorPropsExtended;
export const useExtendedEditorProps = (
_params: TExtendedEditorExtensionsHookParams
): TExtendedEditorExtensionsConfig => ({});

View File

@@ -0,0 +1,62 @@
import { useCallback, useMemo } from "react";
import type { RefObject } from "react";
import { useSearchParams } from "next/navigation";
import type { EditorRefApi } from "@plane/editor";
import {
PAGE_NAVIGATION_PANE_TAB_KEYS,
PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM,
PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM,
} from "@/components/pages/navigation-pane";
import { useAppRouter } from "@/hooks/use-app-router";
import { useQueryParams } from "@/hooks/use-query-params";
import type { TPageNavigationPaneTab } from "@/plane-web/components/pages/navigation-pane";
import type { INavigationPaneExtension } from "@/plane-web/types/pages/pane-extensions";
import type { TPageInstance } from "@/store/pages/base-page";
export type TPageExtensionHookParams = {
page: TPageInstance;
editorRef: RefObject<EditorRefApi>;
};
export const usePagesPaneExtensions = (_params: TPageExtensionHookParams) => {
const router = useAppRouter();
const { updateQueryParams } = useQueryParams();
const searchParams = useSearchParams();
// Generic navigation pane logic - hook manages feature-specific routing
const navigationPaneQueryParam = searchParams.get(
PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM
) as TPageNavigationPaneTab | null;
const isNavigationPaneOpen =
!!navigationPaneQueryParam && PAGE_NAVIGATION_PANE_TAB_KEYS.includes(navigationPaneQueryParam);
const handleOpenNavigationPane = useCallback(() => {
const updatedRoute = updateQueryParams({
paramsToAdd: { [PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM]: "outline" },
});
router.push(updatedRoute);
}, [router, updateQueryParams]);
const editorExtensionHandlers: Map<string, unknown> = useMemo(() => {
const map: Map<string, unknown> = new Map();
return map;
}, []);
const navigationPaneExtensions: INavigationPaneExtension[] = [];
const handleCloseNavigationPane = useCallback(() => {
const updatedRoute = updateQueryParams({
paramsToRemove: [PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM, PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM],
});
router.push(updatedRoute);
}, [router, updateQueryParams]);
return {
editorExtensionHandlers,
navigationPaneExtensions,
handleOpenNavigationPane,
isNavigationPaneOpen,
handleCloseNavigationPane,
};
};

View File

@@ -0,0 +1,16 @@
import type { TSupportedOperators } from "@plane/types";
import { CORE_OPERATORS } from "@plane/types";
export type TFiltersOperatorConfigs = {
allowedOperators: Set<TSupportedOperators>;
allowNegative: boolean;
};
export type TUseFiltersOperatorConfigsProps = {
workspaceSlug: string;
};
export const useFiltersOperatorConfigs = (_props: TUseFiltersOperatorConfigsProps): TFiltersOperatorConfigs => ({
allowedOperators: new Set(Object.values(CORE_OPERATORS)),
allowNegative: false,
});

View File

@@ -0,0 +1,2 @@
export * from "./use-page-store";
export * from "./use-page";

View File

@@ -0,0 +1,24 @@
import { useContext } from "react";
// context
import { StoreContext } from "@/lib/store-context";
// mobx store
import type { IProjectPageStore } from "@/store/pages/project-page.store";
export enum EPageStoreType {
PROJECT = "PROJECT_PAGE",
}
export type TReturnType = {
[EPageStoreType.PROJECT]: IProjectPageStore;
};
export const usePageStore = <T extends EPageStoreType>(storeType: T): TReturnType[T] => {
const context = useContext(StoreContext);
if (context === undefined) throw new Error("usePageStore must be used within StoreProvider");
if (storeType === EPageStoreType.PROJECT) {
return context.projectPages;
}
throw new Error(`Invalid store type: ${storeType}`);
};

View File

@@ -0,0 +1,24 @@
import { useContext } from "react";
// mobx store
import { StoreContext } from "@/lib/store-context";
// plane web hooks
import type { EPageStoreType } from "@/plane-web/hooks/store";
import { usePageStore } from "@/plane-web/hooks/store";
export type TArgs = {
pageId: string;
storeType: EPageStoreType;
};
export const usePage = (args: TArgs) => {
const { pageId, storeType } = args;
// context
const context = useContext(StoreContext);
// store hooks
const pageStore = usePageStore(storeType);
if (context === undefined) throw new Error("usePage must be used within StoreProvider");
if (!pageId) throw new Error("pageId is required");
return pageStore.getPageById(pageId);
};

View File

@@ -0,0 +1,41 @@
import { useCallback } from "react";
// plane editor
import type { TMentionSection } from "@plane/editor";
// plane types
import type { TSearchEntities, TSearchResponse } from "@plane/types";
export type TAdditionalEditorMentionHandlerArgs = {
response: TSearchResponse;
sections: TMentionSection[];
};
export type TAdditionalParseEditorContentArgs = {
id: string;
entityType: TSearchEntities;
};
export type TAdditionalParseEditorContentReturnType =
| {
redirectionPath: string;
textContent: string;
}
| undefined;
export const useAdditionalEditorMention = () => {
const updateAdditionalSections = useCallback((args: TAdditionalEditorMentionHandlerArgs) => {
const {} = args;
}, []);
const parseAdditionalEditorContent = useCallback(
(args: TAdditionalParseEditorContentArgs): TAdditionalParseEditorContentReturnType => {
const {} = args;
return undefined;
},
[]
);
return {
updateAdditionalSections,
parseAdditionalEditorContent,
};
};

View File

@@ -0,0 +1,26 @@
// plane imports
import type { IFavorite } from "@plane/types";
// components
import { getFavoriteItemIcon } from "@/components/workspace/sidebar/favorites/favorite-items/common";
export const useAdditionalFavoriteItemDetails = () => {
const getAdditionalFavoriteItemDetails = (_workspaceSlug: string, favorite: IFavorite) => {
const { entity_type: favoriteItemEntityType } = favorite;
const favoriteItemName = favorite?.entity_data?.name || favorite?.name;
let itemIcon;
let itemTitle;
switch (favoriteItemEntityType) {
default:
itemTitle = favoriteItemName;
itemIcon = getFavoriteItemIcon(favoriteItemEntityType);
break;
}
return { itemIcon, itemTitle };
};
return {
getAdditionalFavoriteItemDetails,
};
};

View File

@@ -0,0 +1 @@
export const useBulkOperationStatus = () => false;

View File

@@ -0,0 +1,12 @@
import type { TDeDupeIssue } from "@plane/types";
export const useDebouncedDuplicateIssues = (
workspaceSlug: string | undefined,
workspaceId: string | undefined,
projectId: string | undefined,
formData: { name: string | undefined; description_html?: string | undefined; issueId?: string | undefined }
) => {
const duplicateIssues: TDeDupeIssue[] = [];
return { duplicateIssues };
};

View File

@@ -0,0 +1,41 @@
// editor
import type { TExtensions } from "@plane/editor";
import type { EPageStoreType } from "@/plane-web/hooks/store";
export type TEditorFlaggingHookReturnType = {
document: {
disabled: TExtensions[];
flagged: TExtensions[];
};
liteText: {
disabled: TExtensions[];
flagged: TExtensions[];
};
richText: {
disabled: TExtensions[];
flagged: TExtensions[];
};
};
export type TEditorFlaggingHookProps = {
workspaceSlug: string;
storeType?: EPageStoreType;
};
/**
* @description extensions disabled in various editors
*/
export const useEditorFlagging = (_props: TEditorFlaggingHookProps): TEditorFlaggingHookReturnType => ({
document: {
disabled: ["ai", "collaboration-cursor"],
flagged: [],
},
liteText: {
disabled: ["ai", "collaboration-cursor"],
flagged: [],
},
richText: {
disabled: ["ai", "collaboration-cursor"],
flagged: [],
},
});

View File

@@ -0,0 +1,17 @@
// plane imports
import { MAX_FILE_SIZE } from "@plane/constants";
// hooks
import { useInstance } from "@/hooks/store/use-instance";
type TReturnProps = {
maxFileSize: number;
};
export const useFileSize = (): TReturnProps => {
// store hooks
const { config } = useInstance();
return {
maxFileSize: config?.file_size_limit ?? MAX_FILE_SIZE,
};
};

View File

@@ -0,0 +1,25 @@
// editor
import type { TEmbedConfig } from "@plane/editor";
// plane types
import type { TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
// plane web components
import { IssueEmbedUpgradeCard } from "@/plane-web/components/pages";
export type TIssueEmbedHookProps = {
fetchEmbedSuggestions?: (payload: TSearchEntityRequestPayload) => Promise<TSearchResponse>;
projectId?: string;
workspaceSlug?: string;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const useIssueEmbed = (props: TIssueEmbedHookProps) => {
const widgetCallback = () => <IssueEmbedUpgradeCard />;
const issueEmbedProps: TEmbedConfig["issue"] = {
widgetCallback,
};
return {
issueEmbedProps,
};
};

View File

@@ -0,0 +1,10 @@
import type { TIssueServiceType } from "@plane/types";
export const useWorkItemProperties = (
projectId: string | null | undefined,
workspaceSlug: string | null | undefined,
workItemId: string | null | undefined,
issueServiceType: TIssueServiceType
) => {
if (!projectId || !workspaceSlug || !workItemId) return;
};

View File

@@ -0,0 +1,25 @@
import type { IWorkItemPeekOverview } from "@plane/types";
import { EIssueServiceType } from "@plane/types";
import { IssuePeekOverview } from "@/components/issues/peek-overview";
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import type { TPeekIssue } from "@/store/issue/issue-details/root.store";
export type TNotificationPreview = {
isWorkItem: boolean;
PeekOverviewComponent: React.ComponentType<IWorkItemPeekOverview>;
setPeekWorkItem: (peekIssue: TPeekIssue | undefined) => void;
};
/**
* This function returns if the current active notification is related to work item or an epic.
* @returns isWorkItem: boolean, peekOverviewComponent: IWorkItemPeekOverview, setPeekWorkItem
*/
export const useNotificationPreview = (): TNotificationPreview => {
const { peekIssue, setPeekIssue } = useIssueDetail(EIssueServiceType.ISSUES);
return {
isWorkItem: Boolean(peekIssue),
PeekOverviewComponent: IssuePeekOverview,
setPeekWorkItem: setPeekIssue,
};
};

View File

@@ -0,0 +1,16 @@
export type TPageFlagHookArgs = {
workspaceSlug: string;
};
export type TPageFlagHookReturnType = {
isMovePageEnabled: boolean;
isPageSharingEnabled: boolean;
};
export const usePageFlag = (args: TPageFlagHookArgs): TPageFlagHookReturnType => {
const {} = args;
return {
isMovePageEnabled: false,
isPageSharingEnabled: false,
};
};

View File

@@ -0,0 +1,2 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const useWorkspaceIssuePropertiesExtended = (workspaceSlug: string | string[] | undefined) => {};

View File

@@ -0,0 +1,401 @@
import { useCallback, useMemo } from "react";
import {
AtSign,
Briefcase,
Calendar,
CalendarCheck2,
CalendarClock,
CircleUserRound,
SignalHigh,
Tag,
Users,
} from "lucide-react";
// plane imports
import {
CycleGroupIcon,
CycleIcon,
ModuleIcon,
DoubleCircleIcon,
PriorityIcon,
StateGroupIcon,
} from "@plane/propel/icons";
import type {
ICycle,
IState,
IUserLite,
TFilterConfig,
TFilterValue,
IIssueLabel,
IModule,
IProject,
TWorkItemFilterProperty,
} from "@plane/types";
import { Avatar, Logo } from "@plane/ui";
import {
getAssigneeFilterConfig,
getCreatedAtFilterConfig,
getCreatedByFilterConfig,
getCycleFilterConfig,
getFileURL,
getLabelFilterConfig,
getMentionFilterConfig,
getModuleFilterConfig,
getPriorityFilterConfig,
getProjectFilterConfig,
getStartDateFilterConfig,
getStateFilterConfig,
getStateGroupFilterConfig,
getSubscriberFilterConfig,
getTargetDateFilterConfig,
getUpdatedAtFilterConfig,
isLoaderReady,
} from "@plane/utils";
// store hooks
import { useCycle } from "@/hooks/store/use-cycle";
import { useLabel } from "@/hooks/store/use-label";
import { useMember } from "@/hooks/store/use-member";
import { useModule } from "@/hooks/store/use-module";
import { useProject } from "@/hooks/store/use-project";
import { useProjectState } from "@/hooks/store/use-project-state";
// plane web imports
import { useFiltersOperatorConfigs } from "@/plane-web/hooks/rich-filters/use-filters-operator-configs";
export type TWorkItemFiltersEntityProps = {
workspaceSlug: string;
cycleIds?: string[];
labelIds?: string[];
memberIds?: string[];
moduleIds?: string[];
projectId?: string;
projectIds?: string[];
stateIds?: string[];
};
export type TUseWorkItemFiltersConfigProps = {
allowedFilters: TWorkItemFilterProperty[];
} & TWorkItemFiltersEntityProps;
export type TWorkItemFiltersConfig = {
areAllConfigsInitialized: boolean;
configs: TFilterConfig<TWorkItemFilterProperty, TFilterValue>[];
configMap: {
[key in TWorkItemFilterProperty]?: TFilterConfig<TWorkItemFilterProperty, TFilterValue>;
};
isFilterEnabled: (key: TWorkItemFilterProperty) => boolean;
members: IUserLite[];
};
export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): TWorkItemFiltersConfig => {
const { allowedFilters, cycleIds, labelIds, memberIds, moduleIds, projectId, projectIds, stateIds, workspaceSlug } =
props;
// store hooks
const { loader: projectLoader, getProjectById } = useProject();
const { getCycleById } = useCycle();
const { getLabelById } = useLabel();
const { getModuleById } = useModule();
const { getStateById } = useProjectState();
const { getUserDetails } = useMember();
// derived values
const operatorConfigs = useFiltersOperatorConfigs({ workspaceSlug });
const filtersToShow = useMemo(() => new Set(allowedFilters), [allowedFilters]);
const project = useMemo(() => getProjectById(projectId), [projectId, getProjectById]);
const members: IUserLite[] | undefined = useMemo(
() =>
memberIds
? (memberIds.map((memberId) => getUserDetails(memberId)).filter((member) => member) as IUserLite[])
: undefined,
[memberIds, getUserDetails]
);
const workItemStates: IState[] | undefined = useMemo(
() =>
stateIds ? (stateIds.map((stateId) => getStateById(stateId)).filter((state) => state) as IState[]) : undefined,
[stateIds, getStateById]
);
const workItemLabels: IIssueLabel[] | undefined = useMemo(
() =>
labelIds
? (labelIds.map((labelId) => getLabelById(labelId)).filter((label) => label) as IIssueLabel[])
: undefined,
[labelIds, getLabelById]
);
const cycles = useMemo(
() => (cycleIds ? (cycleIds.map((cycleId) => getCycleById(cycleId)).filter((cycle) => cycle) as ICycle[]) : []),
[cycleIds, getCycleById]
);
const modules = useMemo(
() =>
moduleIds ? (moduleIds.map((moduleId) => getModuleById(moduleId)).filter((module) => module) as IModule[]) : [],
[moduleIds, getModuleById]
);
const projects = useMemo(
() =>
projectIds
? (projectIds.map((projectId) => getProjectById(projectId)).filter((project) => project) as IProject[])
: [],
[projectIds, getProjectById]
);
const areAllConfigsInitialized = useMemo(() => isLoaderReady(projectLoader), [projectLoader]);
/**
* Checks if a filter is enabled based on the filters to show.
* @param key - The filter key.
* @param level - The level of the filter.
* @returns True if the filter is enabled, false otherwise.
*/
const isFilterEnabled = useCallback((key: TWorkItemFilterProperty) => filtersToShow.has(key), [filtersToShow]);
// state group filter config
const stateGroupFilterConfig = useMemo(
() =>
getStateGroupFilterConfig<TWorkItemFilterProperty>("state_group")({
isEnabled: isFilterEnabled("state_group"),
filterIcon: DoubleCircleIcon,
getOptionIcon: (stateGroupKey) => <StateGroupIcon stateGroup={stateGroupKey} />,
...operatorConfigs,
}),
[isFilterEnabled, operatorConfigs]
);
// state filter config
const stateFilterConfig = useMemo(
() =>
getStateFilterConfig<TWorkItemFilterProperty>("state_id")({
isEnabled: isFilterEnabled("state_id") && workItemStates !== undefined,
filterIcon: DoubleCircleIcon,
getOptionIcon: (state) => <StateGroupIcon stateGroup={state.group} color={state.color} />,
states: workItemStates ?? [],
...operatorConfigs,
}),
[isFilterEnabled, workItemStates, operatorConfigs]
);
// label filter config
const labelFilterConfig = useMemo(
() =>
getLabelFilterConfig<TWorkItemFilterProperty>("label_id")({
isEnabled: isFilterEnabled("label_id") && workItemLabels !== undefined,
filterIcon: Tag,
labels: workItemLabels ?? [],
getOptionIcon: (color) => (
<span className="flex flex-shrink-0 size-2.5 rounded-full" style={{ backgroundColor: color }} />
),
...operatorConfigs,
}),
[isFilterEnabled, workItemLabels, operatorConfigs]
);
// cycle filter config
const cycleFilterConfig = useMemo(
() =>
getCycleFilterConfig<TWorkItemFilterProperty>("cycle_id")({
isEnabled: isFilterEnabled("cycle_id") && project?.cycle_view === true && cycles !== undefined,
filterIcon: CycleIcon,
getOptionIcon: (cycleGroup) => <CycleGroupIcon cycleGroup={cycleGroup} className="h-3.5 w-3.5 flex-shrink-0" />,
cycles: cycles ?? [],
...operatorConfigs,
}),
[isFilterEnabled, project?.cycle_view, cycles, operatorConfigs]
);
// module filter config
const moduleFilterConfig = useMemo(
() =>
getModuleFilterConfig<TWorkItemFilterProperty>("module_id")({
isEnabled: isFilterEnabled("module_id") && project?.module_view === true && modules !== undefined,
filterIcon: ModuleIcon,
getOptionIcon: () => <ModuleIcon className="h-3 w-3 flex-shrink-0" />,
modules: modules ?? [],
...operatorConfigs,
}),
[isFilterEnabled, project?.module_view, modules, operatorConfigs]
);
// assignee filter config
const assigneeFilterConfig = useMemo(
() =>
getAssigneeFilterConfig<TWorkItemFilterProperty>("assignee_id")({
isEnabled: isFilterEnabled("assignee_id") && members !== undefined,
filterIcon: Users,
members: members ?? [],
getOptionIcon: (memberDetails) => (
<Avatar
name={memberDetails.display_name}
src={getFileURL(memberDetails.avatar_url)}
showTooltip={false}
size="sm"
/>
),
...operatorConfigs,
}),
[isFilterEnabled, members, operatorConfigs]
);
// mention filter config
const mentionFilterConfig = useMemo(
() =>
getMentionFilterConfig<TWorkItemFilterProperty>("mention_id")({
isEnabled: isFilterEnabled("mention_id") && members !== undefined,
filterIcon: AtSign,
members: members ?? [],
getOptionIcon: (memberDetails) => (
<Avatar
name={memberDetails.display_name}
src={getFileURL(memberDetails.avatar_url)}
showTooltip={false}
size="sm"
/>
),
...operatorConfigs,
}),
[isFilterEnabled, members, operatorConfigs]
);
// created by filter config
const createdByFilterConfig = useMemo(
() =>
getCreatedByFilterConfig<TWorkItemFilterProperty>("created_by_id")({
isEnabled: isFilterEnabled("created_by_id") && members !== undefined,
filterIcon: CircleUserRound,
members: members ?? [],
getOptionIcon: (memberDetails) => (
<Avatar
name={memberDetails.display_name}
src={getFileURL(memberDetails.avatar_url)}
showTooltip={false}
size="sm"
/>
),
...operatorConfigs,
}),
[isFilterEnabled, members, operatorConfigs]
);
// subscriber filter config
const subscriberFilterConfig = useMemo(
() =>
getSubscriberFilterConfig<TWorkItemFilterProperty>("subscriber_id")({
isEnabled: isFilterEnabled("subscriber_id") && members !== undefined,
filterIcon: Users,
members: members ?? [],
getOptionIcon: (memberDetails) => (
<Avatar
name={memberDetails.display_name}
src={getFileURL(memberDetails.avatar_url)}
showTooltip={false}
size="sm"
/>
),
...operatorConfigs,
}),
[isFilterEnabled, members, operatorConfigs]
);
// priority filter config
const priorityFilterConfig = useMemo(
() =>
getPriorityFilterConfig<TWorkItemFilterProperty>("priority")({
isEnabled: isFilterEnabled("priority"),
filterIcon: SignalHigh,
getOptionIcon: (priority) => <PriorityIcon priority={priority} />,
...operatorConfigs,
}),
[isFilterEnabled, operatorConfigs]
);
// start date filter config
const startDateFilterConfig = useMemo(
() =>
getStartDateFilterConfig<TWorkItemFilterProperty>("start_date")({
isEnabled: true,
filterIcon: CalendarClock,
...operatorConfigs,
}),
[operatorConfigs]
);
// target date filter config
const targetDateFilterConfig = useMemo(
() =>
getTargetDateFilterConfig<TWorkItemFilterProperty>("target_date")({
isEnabled: true,
filterIcon: CalendarCheck2,
...operatorConfigs,
}),
[operatorConfigs]
);
// created at filter config
const createdAtFilterConfig = useMemo(
() =>
getCreatedAtFilterConfig<TWorkItemFilterProperty>("created_at")({
isEnabled: true,
filterIcon: Calendar,
...operatorConfigs,
}),
[operatorConfigs]
);
// updated at filter config
const updatedAtFilterConfig = useMemo(
() =>
getUpdatedAtFilterConfig<TWorkItemFilterProperty>("updated_at")({
isEnabled: true,
filterIcon: Calendar,
...operatorConfigs,
}),
[operatorConfigs]
);
// project filter config
const projectFilterConfig = useMemo(
() =>
getProjectFilterConfig<TWorkItemFilterProperty>("project_id")({
isEnabled: isFilterEnabled("project_id") && projects !== undefined,
filterIcon: Briefcase,
projects: projects,
getOptionIcon: (project) => <Logo logo={project.logo_props} size={12} />,
...operatorConfigs,
}),
[isFilterEnabled, projects, operatorConfigs]
);
return {
areAllConfigsInitialized,
configs: [
stateFilterConfig,
stateGroupFilterConfig,
assigneeFilterConfig,
priorityFilterConfig,
projectFilterConfig,
mentionFilterConfig,
labelFilterConfig,
cycleFilterConfig,
moduleFilterConfig,
startDateFilterConfig,
targetDateFilterConfig,
createdAtFilterConfig,
updatedAtFilterConfig,
createdByFilterConfig,
subscriberFilterConfig,
],
configMap: {
project_id: projectFilterConfig,
state_group: stateGroupFilterConfig,
state_id: stateFilterConfig,
label_id: labelFilterConfig,
cycle_id: cycleFilterConfig,
module_id: moduleFilterConfig,
assignee_id: assigneeFilterConfig,
mention_id: mentionFilterConfig,
created_by_id: createdByFilterConfig,
subscriber_id: subscriberFilterConfig,
priority: priorityFilterConfig,
start_date: startDateFilterConfig,
target_date: targetDateFilterConfig,
created_at: createdAtFilterConfig,
updated_at: updatedAtFilterConfig,
},
isFilterEnabled,
members: members ?? [],
};
};