chore: run fixes (#4993)
* chore: run fixes * fix: type, just use hocuspocusservercontext * fix: codemod * chore: run ee fixes --------- Co-authored-by: Palanikannan M <[email protected]>
This commit is contained in:
@@ -27,6 +27,7 @@ jobs:
|
||||
env:
|
||||
TURBO_SCM_BASE: ${{ github.event.pull_request.base.sha }}
|
||||
TURBO_SCM_HEAD: ${{ github.sha }}
|
||||
NODE_OPTIONS: --max-old-space-size=4096
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -45,15 +45,3 @@ prefer-frozen-lockfile = true
|
||||
|
||||
# Use isolated linker (best compatibility with Node ecosystem tools)
|
||||
node-linker = isolated
|
||||
|
||||
|
||||
# ------------------------------
|
||||
# Hoisting Strategy
|
||||
# ------------------------------
|
||||
|
||||
# Hoist commonly used tools to the root to prevent duplicates and speed up resolution
|
||||
public-hoist-pattern[] = typescript
|
||||
public-hoist-pattern[] = eslint
|
||||
public-hoist-pattern[] = *@plane/*
|
||||
public-hoist-pattern[] = vite
|
||||
public-hoist-pattern[] = turbo
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import type { FC } from "react";
|
||||
import { isEmpty } from "lodash-es";
|
||||
import { Smartphone } from "lucide-react";
|
||||
@@ -10,7 +8,7 @@ import { CodeBlock } from "@/components/common/code-block";
|
||||
import type { TCopyField } from "@/components/common/copy-field";
|
||||
import { CopyField } from "@/components/common/copy-field";
|
||||
|
||||
export const GithubMobileForm: FC = () => {
|
||||
export function GithubMobileForm() {
|
||||
const originURL = !isEmpty(API_BASE_URL) ? API_BASE_URL : typeof window !== "undefined" ? window.location.origin : "";
|
||||
|
||||
const GITHUB_MOBILE_SERVICE_DETAILS: TCopyField[] = [
|
||||
@@ -48,4 +46,4 @@ export const GithubMobileForm: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import type { FC } from "react";
|
||||
import { isEmpty } from "lodash-es";
|
||||
import { Smartphone } from "lucide-react";
|
||||
@@ -10,7 +8,7 @@ import { CodeBlock } from "@/components/common/code-block";
|
||||
import type { TCopyField } from "@/components/common/copy-field";
|
||||
import { CopyField } from "@/components/common/copy-field";
|
||||
|
||||
export const GoogleMobileForm: FC = () => {
|
||||
export function GoogleMobileForm() {
|
||||
const originURL = !isEmpty(API_BASE_URL) ? API_BASE_URL : typeof window !== "undefined" ? window.location.origin : "";
|
||||
|
||||
const GOOGLE_MOBILE_SERVICE_DETAILS: TCopyField[] = [
|
||||
@@ -48,4 +46,4 @@ export const GoogleMobileForm: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ type Props = {
|
||||
|
||||
type OIDCConfigFormValues = Record<TInstanceOIDCAuthenticationConfigurationKeys, string>;
|
||||
|
||||
export const InstanceOIDCConfigForm: FC<Props> = (props) => {
|
||||
export function InstanceOIDCConfigForm(props: Props) {
|
||||
const { config } = props;
|
||||
// states
|
||||
const [isDiscardChangesModalOpen, setIsDiscardChangesModalOpen] = useState(false);
|
||||
@@ -293,4 +293,4 @@ export const InstanceOIDCConfigForm: FC<Props> = (props) => {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import useSWR from "swr";
|
||||
@@ -19,7 +17,7 @@ import { useInstanceFlag } from "@/plane-admin/hooks/store/use-instance-flag";
|
||||
import type { Route } from "./+types/page";
|
||||
import { InstanceOIDCConfigForm } from "./form";
|
||||
|
||||
const InstanceOIDCAuthenticationPage = observer<React.FC<Route.ComponentProps>>(() => {
|
||||
const InstanceOIDCAuthenticationPage = observer(function InstanceOIDCAuthenticationPage(_props: Route.ComponentProps) {
|
||||
// state
|
||||
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||
// store
|
||||
|
||||
@@ -26,7 +26,7 @@ type Props = {
|
||||
|
||||
type SAMLConfigFormValues = Record<TInstanceSAMLAuthenticationConfigurationKeys, string>;
|
||||
|
||||
export const InstanceSAMLConfigForm: FC<Props> = (props) => {
|
||||
export function InstanceSAMLConfigForm(props: Props) {
|
||||
const { config } = props;
|
||||
// states
|
||||
const [isDiscardChangesModalOpen, setIsDiscardChangesModalOpen] = useState(false);
|
||||
@@ -301,4 +301,4 @@ export const InstanceSAMLConfigForm: FC<Props> = (props) => {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import useSWR from "swr";
|
||||
@@ -19,7 +17,7 @@ import { useInstanceFlag } from "@/plane-admin/hooks/store/use-instance-flag";
|
||||
import type { Route } from "./+types/page";
|
||||
import { InstanceSAMLConfigForm } from "./form";
|
||||
|
||||
const InstanceSAMLAuthenticationPage = observer<React.FC<Route.ComponentProps>>(() => {
|
||||
const InstanceSAMLAuthenticationPage = observer(function InstanceSAMLAuthenticationPage(_props: Route.ComponentProps) {
|
||||
// state
|
||||
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||
// store
|
||||
|
||||
@@ -11,7 +11,7 @@ import { cn } from "@plane/utils";
|
||||
// hooks
|
||||
import { useInstance, useTheme } from "@/hooks/store";
|
||||
// assets
|
||||
// eslint-disable-next-line import/order
|
||||
|
||||
import packageJson from "package.json";
|
||||
|
||||
const helpOptions = [
|
||||
|
||||
@@ -26,7 +26,7 @@ export enum EErrorAlertType {
|
||||
}
|
||||
|
||||
const errorCodeMessages: {
|
||||
[key in EAdminAuthErrorCodes]: { title: string; message: (email?: string | undefined) => React.ReactNode };
|
||||
[key in EAdminAuthErrorCodes]: { title: string; message: (email?: string) => React.ReactNode };
|
||||
} = {
|
||||
// admin
|
||||
[EAdminAuthErrorCodes.ADMIN_ALREADY_EXIST]: {
|
||||
@@ -79,14 +79,11 @@ const errorCodeMessages: {
|
||||
},
|
||||
[EAdminAuthErrorCodes.ADMIN_USER_DEACTIVATED]: {
|
||||
title: `User account deactivated`,
|
||||
message: () => `User account deactivated. Please contact ${!!SUPPORT_EMAIL ? SUPPORT_EMAIL : "administrator"}.`,
|
||||
message: () => `User account deactivated. Please contact ${SUPPORT_EMAIL ? SUPPORT_EMAIL : "administrator"}.`,
|
||||
},
|
||||
};
|
||||
|
||||
export const authErrorHandler = (
|
||||
errorCode: EAdminAuthErrorCodes,
|
||||
email?: string | undefined
|
||||
): TAdminAuthErrorInfo | undefined => {
|
||||
export const authErrorHandler = (errorCode: EAdminAuthErrorCodes, email?: string): TAdminAuthErrorInfo | undefined => {
|
||||
const bannerAlertErrorCodes = [
|
||||
EAdminAuthErrorCodes.ADMIN_ALREADY_EXIST,
|
||||
EAdminAuthErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/order */
|
||||
import * as Sentry from "@sentry/react-router";
|
||||
import { startTransition, StrictMode } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
|
||||
@@ -11,6 +11,7 @@ export function UpgradeButton() {
|
||||
href="https://plane.so/pricing?mode=self-hosted"
|
||||
target="_blank"
|
||||
className={cn(getButtonStyling("primary", "sm"))}
|
||||
rel="noreferrer"
|
||||
>
|
||||
Upgrade
|
||||
<SquareArrowOutUpRight className="h-3.5 w-3.5 p-0.5" />
|
||||
|
||||
@@ -24,6 +24,7 @@ export const WorkspaceListItem = observer(function WorkspaceListItem({ workspace
|
||||
href={`${WEB_BASE_URL}/${encodeURIComponent(workspace.slug)}`}
|
||||
target="_blank"
|
||||
className="group flex items-center justify-between p-4 gap-2.5 truncate border border-custom-border-200/70 hover:border-custom-border-200 hover:bg-custom-background-90 rounded-md"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<div className="flex items-start gap-4">
|
||||
<span
|
||||
|
||||
@@ -114,7 +114,7 @@ export const getAuthenticationModes: (props: TGetAuthenticationModeProps) => TIn
|
||||
},
|
||||
];
|
||||
|
||||
export const AuthenticationModes: React.FC<TAuthenticationModeProps> = observer((props) => {
|
||||
export const AuthenticationModes = observer(function AuthenticationModes(props: TAuthenticationModeProps) {
|
||||
const { disabled, updateConfig } = props;
|
||||
// next-themes
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
@@ -18,7 +16,7 @@ type Props = {
|
||||
updateConfig: (key: TInstanceEnterpriseAuthenticationMethodKeys, value: string) => void;
|
||||
};
|
||||
|
||||
export const OIDCConfiguration: React.FC<Props> = observer((props) => {
|
||||
export const OIDCConfiguration = observer(function OIDCConfiguration(props: Props) {
|
||||
const { disabled, updateConfig } = props;
|
||||
// store
|
||||
const { formattedConfig } = useInstance();
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
export const SAMLAttributeMappingTable = () => (
|
||||
<table className="table-auto border-collapse text-custom-text-200 text-sm w-full">
|
||||
<thead>
|
||||
<tr className="text-left border-b border-custom-border-200">
|
||||
<th className="py-2">IdP</th>
|
||||
<th className="py-2">Plane</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">Name ID format</td>
|
||||
<td className="py-2">emailAddress</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">first_name</td>
|
||||
<td className="py-2">user.firstName</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">last_name</td>
|
||||
<td className="py-2">user.lastName</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">email</td>
|
||||
<td className="py-2">user.email</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
export function SAMLAttributeMappingTable() {
|
||||
return (
|
||||
<table className="table-auto border-collapse text-custom-text-200 text-sm w-full">
|
||||
<thead>
|
||||
<tr className="text-left border-b border-custom-border-200">
|
||||
<th className="py-2">IdP</th>
|
||||
<th className="py-2">Plane</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">Name ID format</td>
|
||||
<td className="py-2">emailAddress</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">first_name</td>
|
||||
<td className="py-2">user.firstName</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">last_name</td>
|
||||
<td className="py-2">user.lastName</td>
|
||||
</tr>
|
||||
<tr className="border-b border-custom-border-200">
|
||||
<td className="py-2">email</td>
|
||||
<td className="py-2">user.email</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
@@ -18,7 +16,7 @@ type Props = {
|
||||
updateConfig: (key: TInstanceEnterpriseAuthenticationMethodKeys, value: string) => void;
|
||||
};
|
||||
|
||||
export const SAMLConfiguration: React.FC<Props> = observer((props) => {
|
||||
export const SAMLConfiguration = observer(function SAMLConfiguration(props: Props) {
|
||||
const { disabled, updateConfig } = props;
|
||||
// store
|
||||
const { formattedConfig } = useInstance();
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
// plane internal packages
|
||||
import { WEB_BASE_URL } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { AlertModalCore } from "@plane/ui";
|
||||
|
||||
export const UpgradeButton: React.FC = () => {
|
||||
export function UpgradeButton() {
|
||||
// states
|
||||
const [isActivationModalOpen, setIsActivationModalOpen] = React.useState(false);
|
||||
// derived values
|
||||
@@ -36,4 +34,4 @@ export const UpgradeButton: React.FC = () => {
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ export class AdminController {
|
||||
// Validate and map error code to ForceCloseReason
|
||||
let reason: ForceCloseReason;
|
||||
if (isValidForceCloseReason(errorCode)) {
|
||||
reason = errorCode as ForceCloseReason;
|
||||
reason = errorCode;
|
||||
} else {
|
||||
logger.warn(`[ADMIN] Invalid error code "${errorCode}", defaulting to ADMIN_REQUEST`);
|
||||
reason = ForceCloseReason.ADMIN_REQUEST;
|
||||
|
||||
@@ -168,7 +168,7 @@ export class BroadcastController {
|
||||
if (matchingEmbeds.length > 0) {
|
||||
matchingEmbeds.forEach(({ parent, indexInParent }) => {
|
||||
const newPageEmbedNode = new Y.XmlElement("pageEmbedComponent");
|
||||
newPageEmbedNode.setAttribute("entity_identifier", data.new_page_id as string);
|
||||
newPageEmbedNode.setAttribute("entity_identifier", data.new_page_id);
|
||||
newPageEmbedNode.setAttribute("entity_name", "sub_page");
|
||||
newPageEmbedNode.setAttribute("id", uuidv4());
|
||||
newPageEmbedNode.setAttribute("workspace_identifier", workspace_slug || "");
|
||||
|
||||
@@ -12,7 +12,7 @@ export class ForceCloseHandler implements Extension {
|
||||
priority = 999;
|
||||
|
||||
async onConfigure({ instance }: onConfigurePayload) {
|
||||
const redisExt = instance.configuration.extensions.find((ext) => ext instanceof Redis) as Redis | undefined;
|
||||
const redisExt = instance.configuration.extensions.find((ext) => ext instanceof Redis);
|
||||
|
||||
if (!redisExt) {
|
||||
logger.warn("[FORCE_CLOSE_HANDLER] Redis extension not found");
|
||||
@@ -149,7 +149,7 @@ export const forceCloseDocumentAcrossServers = async (
|
||||
logger.info(`[FORCE_CLOSE] Closed ${closedCount}/${connectionsBefore} local connections`);
|
||||
|
||||
// STEP 4: BROADCAST TO OTHER SERVERS
|
||||
const redisExt = instance.configuration.extensions.find((ext) => ext instanceof Redis) as Redis | undefined;
|
||||
const redisExt = instance.configuration.extensions.find((ext) => ext instanceof Redis);
|
||||
|
||||
if (redisExt) {
|
||||
const commandData: ForceCloseCommandData = {
|
||||
|
||||
@@ -34,24 +34,21 @@ function addSpacesToCheckboxes() {
|
||||
child.properties &&
|
||||
child.properties["data-type"] === "taskItem"
|
||||
) {
|
||||
const liElement = child as HASTElement;
|
||||
const liElement = child;
|
||||
|
||||
// Find the label and div elements
|
||||
const label = liElement.children?.find(
|
||||
(c) => c.type === "element" && (c as HASTElement).tagName === "label"
|
||||
) as HASTElement | undefined;
|
||||
const label = liElement.children?.find((c) => c.type === "element" && c.tagName === "label") as
|
||||
| HASTElement
|
||||
| undefined;
|
||||
|
||||
const contentDiv = liElement.children?.find(
|
||||
(c) => c.type === "element" && (c as HASTElement).tagName === "div"
|
||||
) as HASTElement | undefined;
|
||||
const contentDiv = liElement.children?.find((c) => c.type === "element" && c.tagName === "div") as
|
||||
| HASTElement
|
||||
| undefined;
|
||||
|
||||
if (label && contentDiv) {
|
||||
// Find the checkbox input
|
||||
const checkbox = label.children?.find(
|
||||
(c) =>
|
||||
c.type === "element" &&
|
||||
(c as HASTElement).tagName === "input" &&
|
||||
(c as HASTElement).properties?.type === "checkbox"
|
||||
(c) => c.type === "element" && c.tagName === "input" && c.properties?.type === "checkbox"
|
||||
) as HASTElement | undefined;
|
||||
|
||||
if (checkbox) {
|
||||
@@ -59,9 +56,9 @@ function addSpacesToCheckboxes() {
|
||||
const textContent: ElementContent[] = [];
|
||||
if (contentDiv.children) {
|
||||
for (const child of contentDiv.children) {
|
||||
if (child.type === "element" && (child as HASTElement).tagName === "p") {
|
||||
if (child.type === "element" && child.tagName === "p") {
|
||||
// Unwrap paragraph - add its children directly
|
||||
const pElement = child as HASTElement;
|
||||
const pElement = child;
|
||||
if (pElement.children) {
|
||||
textContent.push(...pElement.children);
|
||||
}
|
||||
@@ -81,7 +78,7 @@ function addSpacesToCheckboxes() {
|
||||
}
|
||||
}
|
||||
} else if (child && child.type === "element") {
|
||||
helper(child as HASTElement);
|
||||
helper(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import { serverAgentManager } from "@/agents/server-agent";
|
||||
* @param param0
|
||||
*/
|
||||
export const onStateless = async ({ payload, document, connection }: onStatelessPayload) => {
|
||||
const payloadStr = payload as string;
|
||||
const payloadStr = payload;
|
||||
|
||||
// Function to safely parse JSON without throwing exceptions
|
||||
const safeJsonParse = (str: string) => {
|
||||
@@ -26,7 +26,7 @@ export const onStateless = async ({ payload, document, connection }: onStateless
|
||||
const documentEvent = DocumentCollaborativeEvents[payload as TDocumentEventsServer]?.client;
|
||||
|
||||
if (documentEvent) {
|
||||
const eventType = documentEvent as keyof EventToPayloadMap;
|
||||
const eventType = documentEvent;
|
||||
|
||||
let eventData: Partial<EventToPayloadMap[typeof eventType]> = {
|
||||
user_id: connection.context.userId,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line import/order
|
||||
import { setupSentry } from "./instrument";
|
||||
setupSentry();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Hocuspocus } from "@hocuspocus/server";
|
||||
import { createRealtimeEvent } from "@plane/editor";
|
||||
import { logger } from "@plane/logger";
|
||||
import type { FetchPayloadWithContext, StorePayloadWithContext } from "@/types";
|
||||
import type { HocusPocusServerContext } from "@/types";
|
||||
import { broadcastMessageToPage } from "./broadcast-message";
|
||||
|
||||
// Helper to broadcast error to frontend
|
||||
@@ -10,7 +10,7 @@ export const broadcastError = async (
|
||||
pageId: string,
|
||||
errorMessage: string,
|
||||
errorType: "fetch" | "store",
|
||||
context: FetchPayloadWithContext["context"] | StorePayloadWithContext["context"],
|
||||
context: HocusPocusServerContext,
|
||||
errorCode?: "content_too_large" | "page_locked" | "page_archived",
|
||||
shouldDisconnect?: boolean
|
||||
) => {
|
||||
|
||||
@@ -130,5 +130,5 @@ export const getTransformedCustomFieldValues = (
|
||||
|
||||
export const getTransformedComments = (entities: AsanaEntity): Partial<ExIssueComment>[] => {
|
||||
const issueComments = entities.comments.map((comment) => transformComments(comment, entities.users));
|
||||
return issueComments.filter(Boolean) as Partial<ExIssueComment>[];
|
||||
return issueComments.filter(Boolean);
|
||||
};
|
||||
|
||||
@@ -131,7 +131,7 @@ export class ClickUpAdditionalDataMigrator extends TaskHandler {
|
||||
* Sometimes, we're getting multiple messages being injected for the same page.
|
||||
* We should lock the page to prevent same page being pulled multiple times.
|
||||
*/
|
||||
const lock = new Lock(this.store!, {
|
||||
const lock = new Lock(this.store, {
|
||||
type: "custom",
|
||||
lockKey: `clickup_pull_${job.id}_${job.config.team.id}_${job.config.folder.id}_${page}`,
|
||||
ttl: 15 * 60, // 15 minutes TTL
|
||||
|
||||
@@ -57,7 +57,7 @@ export class AppController {
|
||||
const { workspaceId } = req.params;
|
||||
try {
|
||||
const allConnections = await integrationConnectionHelper.getWorkspaceConnections({
|
||||
workspace_id: workspaceId as string,
|
||||
workspace_id: workspaceId,
|
||||
});
|
||||
|
||||
// Extract unique connection types
|
||||
|
||||
@@ -403,7 +403,7 @@ export default class GithubController {
|
||||
|
||||
const { github_code, encoded_github_state } = githubState;
|
||||
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(encoded_github_state as string, "base64").toString());
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(encoded_github_state, "base64").toString());
|
||||
let redirectUri = `${env.APP_BASE_URL}/${authState.workspace_slug}/settings/integrations/github/`;
|
||||
|
||||
if (authState.profile_redirect) {
|
||||
@@ -412,7 +412,7 @@ export default class GithubController {
|
||||
|
||||
try {
|
||||
const { response, state } = await githubAuthService.getUserAccessToken({
|
||||
code: github_code as string,
|
||||
code: github_code,
|
||||
state: authState,
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getConnDetailsForGithubToPlaneSync = async (props: {
|
||||
const { wsAdminCredentials: credentials, isEnterprise, type, repositoryId, planeProjectId } = props;
|
||||
// Get the workspace connection for the installation
|
||||
const workspaceConnection = await apiClient.workspaceConnection.listWorkspaceConnections({
|
||||
workspace_id: credentials.workspace_id!,
|
||||
workspace_id: credentials.workspace_id,
|
||||
credential_id: credentials.id,
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ export const getConnDetailsForGithubToPlaneSync = async (props: {
|
||||
}
|
||||
|
||||
const entityConnections = await apiClient.workspaceEntityConnection.listWorkspaceEntityConnections({
|
||||
workspace_id: credentials.workspace_id!,
|
||||
workspace_id: credentials.workspace_id,
|
||||
entity_type: isEnterprise ? E_INTEGRATION_KEYS.GITHUB_ENTERPRISE : E_INTEGRATION_KEYS.GITHUB,
|
||||
type: type,
|
||||
});
|
||||
@@ -87,9 +87,9 @@ export const getConnDetailsForPlaneToGithubSync = async (
|
||||
const credentials = await apiClient.workspaceCredential.getWorkspaceCredential(workspaceConnection.credential_id);
|
||||
|
||||
return {
|
||||
credentials: credentials as TWorkspaceCredential,
|
||||
entityConnection: entityConnection as TGithubEntityConnection,
|
||||
workspaceConnection: workspaceConnection as TGithubWorkspaceConnection,
|
||||
credentials: credentials,
|
||||
entityConnection: entityConnection,
|
||||
workspaceConnection: workspaceConnection,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ export const transformGitHubComment = async (
|
||||
githubService,
|
||||
});
|
||||
|
||||
comment_html = replaceIssueNumber(comment_html!, repository);
|
||||
comment_html = replaceIssueNumber(comment_html, repository);
|
||||
comment_html = replaceMentionedGhUsers(comment_html, workspaceSlug, userMap, planeUsers);
|
||||
|
||||
return {
|
||||
|
||||
@@ -15,7 +15,7 @@ type GithubWebhookInstallationDeleted = GithubWebhookPayload["webhook-installati
|
||||
export const handleInstallationEvents = async (action: string, data: unknown): Promise<boolean> => {
|
||||
switch (action) {
|
||||
case "deleted": {
|
||||
await handleInstallationDeletion(data as unknown as GithubWebhookInstallationDeleted);
|
||||
await handleInstallationDeletion(data as GithubWebhookInstallationDeleted);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
|
||||
@@ -71,7 +71,7 @@ export const syncCommentWithPlane = async (
|
||||
|
||||
const { workspaceConnection, entityConnectionForRepository: entityConnection } =
|
||||
await getConnDetailsForGithubToPlaneSync({
|
||||
wsAdminCredentials: wsAdminCredentials as TWorkspaceCredential,
|
||||
wsAdminCredentials: wsAdminCredentials,
|
||||
type: EGithubEntityConnectionType.PROJECT_ISSUE_SYNC,
|
||||
repositoryId: data.repository.id.toString(),
|
||||
isEnterprise: data.isEnterprise,
|
||||
@@ -91,11 +91,7 @@ export const syncCommentWithPlane = async (
|
||||
|
||||
let planeClient: PlaneClient = await getPlaneAPIClient(wsAdminCredentials, ghIntegrationKey);
|
||||
|
||||
const ghService = getGithubService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
data.installation?.id.toString(),
|
||||
data.isEnterprise
|
||||
);
|
||||
const ghService = getGithubService(workspaceConnection, data.installation?.id.toString(), data.isEnterprise);
|
||||
const commentHtml = await ghService.getCommentHtml(
|
||||
data.repository.owner.login,
|
||||
data.repository.name,
|
||||
|
||||
@@ -62,7 +62,7 @@ export const syncIssueWithPlane = async (store: Store, action: IssueWebhookActio
|
||||
|
||||
const { workspaceConnection, entityConnectionForRepository: entityConnection } =
|
||||
await getConnDetailsForGithubToPlaneSync({
|
||||
wsAdminCredentials: wsAdminCredentials as TWorkspaceCredential,
|
||||
wsAdminCredentials: wsAdminCredentials,
|
||||
isEnterprise: data.isEnterprise,
|
||||
type: EGithubEntityConnectionType.PROJECT_ISSUE_SYNC,
|
||||
repositoryId: data.repositoryId.toString(),
|
||||
@@ -77,11 +77,7 @@ export const syncIssueWithPlane = async (store: Store, action: IssueWebhookActio
|
||||
|
||||
let issue: ExIssue | null = null;
|
||||
|
||||
const ghService = getGithubService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
data.installationId.toString(),
|
||||
data.isEnterprise
|
||||
);
|
||||
const ghService = getGithubService(workspaceConnection, data.installationId.toString(), data.isEnterprise);
|
||||
const ghIssue = await ghService.getIssue(data.owner, data.repositoryName, Number(data.issueNumber));
|
||||
const bodyHtml = await ghService.getBodyHtml(data.owner, data.repositoryName, Number(data.issueNumber));
|
||||
// replace the issue body with the html body
|
||||
@@ -181,7 +177,7 @@ export const syncIssueWithPlane = async (store: Store, action: IssueWebhookActio
|
||||
return l.id;
|
||||
}
|
||||
})
|
||||
.filter((l) => l !== undefined) as string[];
|
||||
.filter((l) => l !== undefined);
|
||||
}
|
||||
|
||||
if (planeIssue.created_by) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { getPlaneAPIClient } from "@/helpers/plane-api-client";
|
||||
import { PullRequestBehaviour } from "@/lib/behaviours";
|
||||
|
||||
export const handlePullRequestEvents = async (action: PullRequestWebhookActions, data: unknown) => {
|
||||
await handlePullRequestOpened(data as unknown as GithubPullRequestDedupPayload);
|
||||
await handlePullRequestOpened(data as GithubPullRequestDedupPayload);
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ const handlePullRequestOpened = async (data: GithubPullRequestDedupPayload) => {
|
||||
// Get the workspace connection for the installation
|
||||
// get all entity connections for the installation and do pr automation on them
|
||||
const { workspaceConnection, allEntityConnections } = await getConnDetailsForGithubToPlaneSync({
|
||||
wsAdminCredentials: wsAdminCredentials as TWorkspaceCredential,
|
||||
wsAdminCredentials: wsAdminCredentials,
|
||||
type: EGithubEntityConnectionType.PROJECT_PR_AUTOMATION,
|
||||
isEnterprise: data.isEnterprise,
|
||||
});
|
||||
@@ -55,7 +55,7 @@ const handlePullRequestOpened = async (data: GithubPullRequestDedupPayload) => {
|
||||
// Create the pull request service based on the type of integration
|
||||
let pullRequestService: GithubIntegrationService;
|
||||
if (data.isEnterprise) {
|
||||
const appConfig = (workspaceConnection as TGithubWorkspaceConnection)?.connection_data?.appConfig;
|
||||
const appConfig = workspaceConnection?.connection_data?.appConfig;
|
||||
if (!appConfig) {
|
||||
logger.error("[PULL-REQUEST] GitHub Enterprise app config not found", {
|
||||
installationId: data.installationId,
|
||||
|
||||
@@ -107,11 +107,7 @@ const handleCommentSync = async (store: Store, payload: PlaneWebhookPayload) =>
|
||||
return;
|
||||
}
|
||||
|
||||
const githubService = getGithubService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
credentials.source_access_token,
|
||||
payload.isEnterprise
|
||||
);
|
||||
const githubService = getGithubService(workspaceConnection, credentials.source_access_token, payload.isEnterprise);
|
||||
|
||||
const comment = await planeClient.issueComment.getComment(
|
||||
entityConnection.workspace_slug,
|
||||
@@ -188,11 +184,7 @@ const createOrUpdateGitHubComment = async (
|
||||
let userGithubService = githubService;
|
||||
|
||||
if (userCredential?.source_access_token) {
|
||||
userGithubService = getGithubUserService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
userCredential.source_access_token,
|
||||
isEnterprise
|
||||
);
|
||||
userGithubService = getGithubUserService(workspaceConnection, userCredential.source_access_token, isEnterprise);
|
||||
}
|
||||
|
||||
if (comment.external_id && comment.external_source && comment.external_source === ghIntegrationKey) {
|
||||
|
||||
@@ -77,11 +77,7 @@ const handleIssueSync = async (store: Store, payload: PlaneWebhookPayload) => {
|
||||
const planeClient = await getPlaneAPIClient(credentials, ghIntegrationKey);
|
||||
|
||||
// Create or update issue in GitHub
|
||||
const githubService = getGithubService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
credentials.source_access_token,
|
||||
payload.isEnterprise
|
||||
);
|
||||
const githubService = getGithubService(workspaceConnection, credentials.source_access_token, payload.isEnterprise);
|
||||
|
||||
const issue = await planeClient.issue.getIssue(entityConnection.workspace_slug, payload.project, payload.id);
|
||||
|
||||
@@ -185,11 +181,7 @@ const createOrUpdateGitHubIssue = async (
|
||||
|
||||
// If the user has a credential, create a new github service for the user
|
||||
if (userCredential?.source_access_token) {
|
||||
githubUserService = getGithubUserService(
|
||||
workspaceConnection as TGithubWorkspaceConnection,
|
||||
userCredential.source_access_token,
|
||||
isEnterprise
|
||||
);
|
||||
githubUserService = getGithubUserService(workspaceConnection, userCredential.source_access_token, isEnterprise);
|
||||
}
|
||||
|
||||
// If the issue has already been created with the external source as GITHUB, update the issue
|
||||
|
||||
@@ -217,7 +217,7 @@ export default class GitlabEnterpriseController {
|
||||
});
|
||||
}
|
||||
|
||||
const appConfig = wsConnection.connection_data.appConfig as TGitlabAppConfig;
|
||||
const appConfig = wsConnection.connection_data.appConfig;
|
||||
|
||||
const gitlabClientService = await getGitlabClientService(
|
||||
entityConnection.workspace_id,
|
||||
|
||||
@@ -146,9 +146,7 @@ export default class GitlabController {
|
||||
|
||||
const { gitlab_code, encoded_gitlab_state } = gitlabState;
|
||||
|
||||
const gitlabAuthState: GitLabAuthorizeState = JSON.parse(
|
||||
Buffer.from(encoded_gitlab_state as string, "base64").toString()
|
||||
);
|
||||
const gitlabAuthState: GitLabAuthorizeState = JSON.parse(Buffer.from(encoded_gitlab_state, "base64").toString());
|
||||
const redirectUri = `${env.APP_BASE_URL}/${gitlabAuthState.workspace_slug}/settings/integrations/gitlab/`;
|
||||
|
||||
try {
|
||||
@@ -159,7 +157,7 @@ export default class GitlabController {
|
||||
});
|
||||
|
||||
const { response: token, state: authState } = await gitlabAuthService.getAccessToken({
|
||||
code: gitlab_code as string,
|
||||
code: gitlab_code,
|
||||
state: encoded_gitlab_state,
|
||||
});
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ export const handleMergeRequest = async (data: GitlabMergeRequestEvent) => {
|
||||
source_access_token: access_token,
|
||||
source_refresh_token: refresh_token,
|
||||
workspace_id: workspaceConnection.workspace_id,
|
||||
user_id: credentials.user_id!,
|
||||
user_id: credentials.user_id,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ async function fetchJiraResources(axiosInstance: AxiosInstance, credentials: TWo
|
||||
if (isRetry) {
|
||||
throw new JiraApiError("Invalid access token", 401);
|
||||
} else {
|
||||
return await refreshAndRetry(credentials.workspace_id!, credentials.user_id!, credentials, axiosInstance);
|
||||
return await refreshAndRetry(credentials.workspace_id, credentials.user_id, credentials, axiosInstance);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -119,7 +119,7 @@ export const createJiraClient = (
|
||||
isPAT: false,
|
||||
accessToken: credentials.source_access_token!,
|
||||
refreshToken: credentials.source_refresh_token!,
|
||||
cloudId: job.config?.resource.id as string,
|
||||
cloudId: job.config?.resource.id,
|
||||
refreshTokenFunc: jiraAuth.getRefreshToken.bind(jiraAuth),
|
||||
refreshTokenCallback: refreshTokenCallback,
|
||||
});
|
||||
@@ -129,9 +129,9 @@ export const createJiraClient = (
|
||||
}
|
||||
return new JiraService({
|
||||
isPAT: true,
|
||||
patToken: credentials.source_access_token!,
|
||||
patToken: credentials.source_access_token,
|
||||
hostname: credentials.source_hostname,
|
||||
userEmail: credentials.source_auth_email!,
|
||||
userEmail: credentials.source_auth_email,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ export const createJiraClient = (
|
||||
|
||||
return new JiraV2Service({
|
||||
email: credentials.source_auth_email,
|
||||
patToken: credentials.source_access_token!,
|
||||
patToken: credentials.source_access_token,
|
||||
hostname: credentials.source_hostname,
|
||||
authenticationType,
|
||||
});
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ export class JiraCyclesStep implements IStep {
|
||||
// Store mappings: sprint_external_id -> cycle_id
|
||||
const mappings = created
|
||||
?.map((c) => ({
|
||||
externalId: c.external_id!,
|
||||
externalId: c.external_id,
|
||||
planeId: c.id,
|
||||
}))
|
||||
.filter((m) => m.externalId && m.planeId);
|
||||
|
||||
+4
-4
@@ -273,7 +273,7 @@ export class JiraIssuePropertiesStep implements IStep {
|
||||
const mappings = properties
|
||||
.filter((prop) => prop.external_id && prop.id)
|
||||
.map((prop) => ({
|
||||
externalId: prop.external_id!,
|
||||
externalId: prop.external_id,
|
||||
planeId: prop.id!,
|
||||
}));
|
||||
|
||||
@@ -282,9 +282,9 @@ export class JiraIssuePropertiesStep implements IStep {
|
||||
// Store raw data including original Jira fields for options step
|
||||
const propertiesData: TIssuePropertiesData = properties.map((prop) => ({
|
||||
id: prop.id!,
|
||||
external_id: prop.external_id!,
|
||||
display_name: prop.display_name!,
|
||||
property_type: prop.property_type!,
|
||||
external_id: prop.external_id,
|
||||
display_name: prop.display_name,
|
||||
property_type: prop.property_type,
|
||||
relation_type: prop.relation_type,
|
||||
}));
|
||||
|
||||
|
||||
+2
-2
@@ -93,7 +93,7 @@ export class JiraIssuePropertyOptionsStep implements IStep {
|
||||
transformIssueFieldOptions({ resourceId, projectId: job.project_id, source: this.source }, option)
|
||||
) || []
|
||||
)
|
||||
.filter(Boolean) as Partial<ExIssuePropertyOption>[];
|
||||
.filter(Boolean);
|
||||
|
||||
logger.info(`[${job.id}] [${this.name}] Transformed options`, {
|
||||
jobId: job.id,
|
||||
@@ -245,7 +245,7 @@ export class JiraIssuePropertyOptionsStep implements IStep {
|
||||
const mappings = options
|
||||
.filter((option) => option.external_id && option.id)
|
||||
.map((option) => ({
|
||||
externalId: option.external_id!,
|
||||
externalId: option.external_id,
|
||||
planeId: option.id!,
|
||||
}));
|
||||
|
||||
|
||||
+2
-2
@@ -316,7 +316,7 @@ export class JiraIssueTypesStep implements IStep {
|
||||
// Store mappings: external_id -> issue_type_id
|
||||
const validIssueTypes = issueTypes.filter((type) => type.external_id && type.id);
|
||||
const mappings = validIssueTypes.map((type) => ({
|
||||
externalId: type.external_id!,
|
||||
externalId: type.external_id,
|
||||
planeId: type.id!,
|
||||
}));
|
||||
|
||||
@@ -325,7 +325,7 @@ export class JiraIssueTypesStep implements IStep {
|
||||
// Store raw issue types data for dependent steps
|
||||
const issueTypesData: TIssueTypesData = validIssueTypes.map((type) => ({
|
||||
id: type.id!,
|
||||
external_id: type.external_id!,
|
||||
external_id: type.external_id,
|
||||
name: type.name || "",
|
||||
is_default: type.is_default || false,
|
||||
is_epic: type.is_epic || false,
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ export class JiraModulesStep implements IStep {
|
||||
.filter((module) => module.external_id && module.id)
|
||||
.map((module) => ({
|
||||
externalId: module.external_id,
|
||||
planeId: module.id!,
|
||||
planeId: module.id,
|
||||
}));
|
||||
|
||||
await storage.storeMapping(job.id, this.name, mappings);
|
||||
|
||||
+2
-2
@@ -275,13 +275,13 @@ export class JiraUsersStep implements IStep {
|
||||
? [
|
||||
{
|
||||
externalId: email,
|
||||
planeId: user.id!,
|
||||
planeId: user.id,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
externalId: displayName,
|
||||
planeId: user.id!,
|
||||
planeId: user.id,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
@@ -136,7 +136,7 @@ export const getTransformedDocuments = async (
|
||||
userMap: userMap,
|
||||
};
|
||||
|
||||
const pages = await Promise.all(documents.map((document) => transformDocument(document as LinearDocument, options)));
|
||||
const pages = await Promise.all(documents.map((document) => transformDocument(document, options)));
|
||||
return pages;
|
||||
};
|
||||
|
||||
@@ -173,5 +173,5 @@ export const getTransformedProjects = (job: TImportJob<LinearConfig>, entities:
|
||||
};
|
||||
});
|
||||
|
||||
return modules as Partial<ExModule>[];
|
||||
return modules;
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ export abstract class NotionMigratorBase extends TaskHandler {
|
||||
return JSON.parse(credentials) as TWorkspaceCredential;
|
||||
}
|
||||
|
||||
const credentialsData = await getJobCredentials(job as TImportJob);
|
||||
const credentialsData = await getJobCredentials(job);
|
||||
this.store.set(credentialsKey, JSON.stringify(credentialsData), 60 * 60 * 4); // 4 hours
|
||||
return credentialsData;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export abstract class NotionMigratorBase extends TaskHandler {
|
||||
// Get the services required for the migration
|
||||
const zipManager = await this.getZipManager(fileId);
|
||||
const client = await this.getPlaneClient(job as TImportJob);
|
||||
const zipDriver = await this.getZipDriver(zipManager, type as EZipDriverType);
|
||||
const zipDriver = await this.getZipDriver(zipManager, type);
|
||||
|
||||
// Determine the current node to process
|
||||
let currentNode: TZipFileNode | undefined = data.node;
|
||||
@@ -233,7 +233,7 @@ export abstract class NotionMigratorBase extends TaskHandler {
|
||||
* @throws Error if access token is not available
|
||||
*/
|
||||
async getPlaneClient(job: TImportJob): Promise<Client> {
|
||||
const credentials = await this.getCachesJobCredentials(job as TImportJob);
|
||||
const credentials = await this.getCachesJobCredentials(job);
|
||||
if (!credentials?.target_access_token) {
|
||||
throw new Error(`Job ${job.id} has no target access token`);
|
||||
}
|
||||
|
||||
@@ -124,11 +124,11 @@ export class SentryAlertHandler implements ISentryTaskHandler {
|
||||
const state = sentryEventAlert.data.issue_alert.settings.find((setting) => setting.name === "state");
|
||||
|
||||
if (assigneeIds?.value && !Array.isArray(assigneeIds.value)) {
|
||||
assigneeIds.value = [assigneeIds.value as string];
|
||||
assigneeIds.value = [assigneeIds.value];
|
||||
}
|
||||
|
||||
if (labels?.value && !Array.isArray(labels.value)) {
|
||||
labels.value = [labels.value as string];
|
||||
labels.value = [labels.value];
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -275,9 +275,7 @@ export default class SlackController {
|
||||
|
||||
const { slack_code, encoded_slack_state } = slackState;
|
||||
|
||||
const authState = JSON.parse(
|
||||
Buffer.from(encoded_slack_state as string, "base64").toString("utf-8")
|
||||
) as SlackUserAuthState;
|
||||
const authState = JSON.parse(Buffer.from(encoded_slack_state, "base64").toString("utf-8")) as SlackUserAuthState;
|
||||
let redirectUri = `${env.APP_BASE_URL}/${authState.workspaceSlug}/settings/integrations/slack/`;
|
||||
if (authState.profileRedirect) {
|
||||
redirectUri = `${env.APP_BASE_URL}/${authState.workspaceSlug}/settings/account/connections/?workspaceId=${authState.workspaceId}`;
|
||||
@@ -285,7 +283,7 @@ export default class SlackController {
|
||||
|
||||
try {
|
||||
const { state, response } = await slackAuth.getUserAuthToken({
|
||||
code: slack_code as string,
|
||||
code: slack_code,
|
||||
state: authState,
|
||||
});
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ export const getConnectionDetails = async (
|
||||
// Create admin-based SlackService that we can use regardless of user credential state
|
||||
const refreshHandler = getRefreshCredentialHandler(
|
||||
workspaceConnection.workspace_id,
|
||||
adminCredentials.user_id as string,
|
||||
adminCredentials.target_access_token as string
|
||||
adminCredentials.user_id,
|
||||
adminCredentials.target_access_token
|
||||
);
|
||||
|
||||
const slackService = createSlackService(
|
||||
@@ -130,7 +130,7 @@ export const findPlaneUserId = async (
|
||||
slackUser: { id: string; email?: string }
|
||||
): Promise<string | null> => {
|
||||
// Check for the userId in the workspace connection map
|
||||
const config = workspaceConnection.config as TSlackWorkspaceConnectionConfig;
|
||||
const config = workspaceConnection.config;
|
||||
|
||||
let planeUser: string | null = null;
|
||||
|
||||
@@ -190,7 +190,7 @@ export const updateUserMap = async (
|
||||
slackUserId: string | null
|
||||
): Promise<void> => {
|
||||
const existingConfig = workspaceConnection.config || {};
|
||||
const existingUserMap = (existingConfig as TSlackWorkspaceConnectionConfig)?.userMap || [];
|
||||
const existingUserMap = existingConfig?.userMap || [];
|
||||
// If both IDs are null, no changes needed
|
||||
if (!planeUserId && !slackUserId) return;
|
||||
// Filter out any existing mappings that match either ID being removed
|
||||
|
||||
@@ -21,7 +21,6 @@ export type IssueModalViewFull = {
|
||||
};
|
||||
|
||||
export type IssueModalViewBlocks = (
|
||||
| StaticSelectInputBlock
|
||||
| StaticSelectInputBlock
|
||||
| PlainTextInputBlock
|
||||
| RichTextInputBlock
|
||||
|
||||
@@ -73,7 +73,7 @@ export const createCycles = async (
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
cycleId,
|
||||
cycleIssueIds.filter((issue: string | undefined) => issue !== undefined) as string[]
|
||||
cycleIssueIds.filter((issue: string | undefined) => issue !== undefined)
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error(`[${jobId.slice(0, 7)}] Error while adding issues to the cycle: ${cycle.name}`, error);
|
||||
|
||||
@@ -82,7 +82,7 @@ export const createOrUpdateIssueProperties = async (
|
||||
// Process all issue properties in batches of 5
|
||||
const createdUpdatedIssueProperties = await processBatchPromises(issueProperties, processIssueProperty, 2);
|
||||
|
||||
return createdUpdatedIssueProperties.filter((property) => property !== undefined) as ExIssueProperty[];
|
||||
return createdUpdatedIssueProperties.filter((property) => property !== undefined);
|
||||
};
|
||||
|
||||
export const createOrUpdateIssuePropertiesOptions = async (
|
||||
@@ -145,5 +145,5 @@ export const createOrUpdateIssuePropertiesOptions = async (
|
||||
2
|
||||
);
|
||||
|
||||
return createdUpdatedIssuePropertiesOptions.filter((option) => option !== undefined) as ExIssuePropertyOption[];
|
||||
return createdUpdatedIssuePropertiesOptions.filter((option) => option !== undefined);
|
||||
};
|
||||
|
||||
@@ -64,5 +64,5 @@ export const createOrUpdateIssueTypes = async (props: TCreateOrUpdateIssueTypes)
|
||||
|
||||
const createdUpdatedIssueTypes = await processBatchPromises(issueTypes, createOrUpdateIssueType, 2);
|
||||
|
||||
return createdUpdatedIssueTypes.filter((issueType) => issueType !== undefined) as ExIssueType[];
|
||||
return createdUpdatedIssueTypes.filter((issueType) => issueType !== undefined);
|
||||
};
|
||||
|
||||
@@ -61,13 +61,13 @@ export const createIssuesWithParent = async (payload: IssueWithParentPayload): P
|
||||
// If the parent issue is not found, then try to find the issue from
|
||||
// external id and source from the api
|
||||
try {
|
||||
const parent = (await protect(
|
||||
const parent = await protect(
|
||||
planeClient.issue.getIssueWithExternalId.bind(planeClient.issue),
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
issue.parent,
|
||||
issue.external_source
|
||||
)) as ExIssue;
|
||||
);
|
||||
issue.parent = parent.id;
|
||||
} catch (error) {
|
||||
logger.error("Error while fetching the parent issue", error);
|
||||
@@ -588,7 +588,7 @@ export const createOrUpdateIssue = async (
|
||||
logger.info(
|
||||
`[${issue.external_source}][${issue.external_id.slice(0, 5)}...][${meta.batchId}] Created Issue: ${issue.external_id.slice(0, 7)} ----------- [${issueProcessIndex} / ${meta.batch_end}][${meta.total.issues}]`
|
||||
);
|
||||
return createdIssue as ExIssue;
|
||||
return createdIssue;
|
||||
} catch (error) {
|
||||
if (AssertAPIErrorResponse(error)) {
|
||||
// Update the issue if the issue already exist
|
||||
@@ -959,7 +959,7 @@ const getPlaneIssueLabels = (issue: ExIssue, planeLabels: ExIssueLabel[]): strin
|
||||
return createdLabel.id;
|
||||
}
|
||||
})
|
||||
.filter((label) => label !== undefined) as string[];
|
||||
.filter((label) => label !== undefined);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
@@ -33,5 +33,5 @@ export const createLabelsForIssues = async (
|
||||
};
|
||||
|
||||
const createdLabels = await processBatchPromises(labels, createOrUpdateLabel, 2);
|
||||
return createdLabels.filter((label) => label !== undefined) as ExIssueLabel[];
|
||||
return createdLabels.filter((label) => label !== undefined);
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ export const createProjects = async (
|
||||
|
||||
const createdProjects = await processBatchPromises(projects, createProject, 2);
|
||||
|
||||
return createdProjects.filter((project) => project !== undefined) as ExProject[];
|
||||
return createdProjects.filter((project) => project !== undefined);
|
||||
};
|
||||
|
||||
export const enableIssueTypeForProject = async (
|
||||
|
||||
@@ -59,5 +59,5 @@ export const createStates = async (
|
||||
// batch the state creation
|
||||
const createdStates = await processBatchPromises(states, createState, 2);
|
||||
|
||||
return createdStates.filter((state) => state !== undefined) as TCreateState[];
|
||||
return createdStates.filter((state) => state !== undefined);
|
||||
};
|
||||
|
||||
@@ -75,6 +75,6 @@ export async function getConnectionDetails<T extends TWorkspaceConnection, Z ext
|
||||
return {
|
||||
workspaceConnection: workspaceConnection as T,
|
||||
entityConnection: entityConnection as Z,
|
||||
credential: credential as TWorkspaceCredential,
|
||||
credential: credential,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,5 +74,5 @@ export const getJobCredentials = async (job: TImportJob): Promise<TWorkspaceCred
|
||||
if (!credentials || credentials.length === 0) {
|
||||
throw new Error(`Credentials not available for job ${job.workspace_id}`);
|
||||
}
|
||||
return credentials[0] as TWorkspaceCredential;
|
||||
return credentials[0];
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ export const removeSpanAroundImg = (htmlContent: string): string => {
|
||||
const imgTags = root.querySelectorAll("img");
|
||||
|
||||
imgTags.forEach((img) => {
|
||||
const parent = img.parentNode as HTMLElement;
|
||||
const parent = img.parentNode;
|
||||
|
||||
// Check if the parent is a <span> tag
|
||||
if (parent && parent.tagName === "SPAN") {
|
||||
@@ -47,7 +47,7 @@ export const splitStringTillPart = (input: string, part: string): string => {
|
||||
return "/" + result;
|
||||
};
|
||||
|
||||
export const downloadFile = async (url: string, authToken?: string | undefined): Promise<Blob | undefined> => {
|
||||
export const downloadFile = async (url: string, authToken?: string): Promise<Blob | undefined> => {
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
|
||||
@@ -294,7 +294,7 @@ export class PullRequestBehaviour {
|
||||
prDetails.repository.owner,
|
||||
prDetails.repository.name,
|
||||
prDetails.number.toString()
|
||||
) as Promise<IGitComment[]>;
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/no-wrapper-object-types */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
||||
|
||||
import "reflect-metadata";
|
||||
// external middlewares
|
||||
import type { E_INTEGRATION_KEYS } from "@plane/types";
|
||||
|
||||
@@ -51,7 +51,7 @@ export class OptionFormFieldsService {
|
||||
const baseField = {
|
||||
id: `${issueTypeId}:${property.id}`,
|
||||
name: property.displayName ?? "",
|
||||
type: property.propertyType as PropertyTypeEnum,
|
||||
type: property.propertyType,
|
||||
required: property.isRequired ?? false,
|
||||
visible: property.isActive ?? true,
|
||||
order: property.sortOrder ?? 0,
|
||||
|
||||
@@ -368,7 +368,7 @@ export class OAuthController {
|
||||
client_id: planeAppClientId,
|
||||
client_secret: planeAppClientSecret,
|
||||
grant_type: EOAuthGrantType.AUTHORIZATION_CODE,
|
||||
code: planeOAuthCode as string,
|
||||
code: planeOAuthCode,
|
||||
redirect_uri: `${env.SILO_API_BASE_URL}${env.SILO_BASE_PATH}/api/oauth/${providerUrlSlug}/plane-oauth/callback`,
|
||||
app_installation_id: credential.target_identifier as string,
|
||||
user_id: authState.user_id,
|
||||
|
||||
@@ -16,7 +16,7 @@ export const convertProviderToIntegrationKey = (provider: string): E_INTEGRATION
|
||||
|
||||
export const convertIntegrationKeyToProvider = (integrationKey: E_INTEGRATION_KEYS): string => {
|
||||
// Validate if the integration key is a valid E_INTEGRATION_KEYS
|
||||
if (!Object.values(E_INTEGRATION_KEYS).includes(integrationKey as E_INTEGRATION_KEYS)) {
|
||||
if (!Object.values(E_INTEGRATION_KEYS).includes(integrationKey)) {
|
||||
throw new Error(`Invalid integration key: ${integrationKey}`);
|
||||
}
|
||||
// Convert "GITHUB" to "github"
|
||||
|
||||
@@ -47,7 +47,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
if (!state.config_key) {
|
||||
throw new Error(E_SILO_ERROR_CODES.INVALID_APP_CREDENTIALS.toString());
|
||||
}
|
||||
const githubAuthService = await this.getGithubAuthService(state.config_key as string);
|
||||
const githubAuthService = await this.getGithubAuthService(state.config_key);
|
||||
return githubAuthService.getAuthUrl(state);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
// add the config key to the state to be used in getUserAuthUrl and handleUserCallback
|
||||
state.config_key = configKey;
|
||||
|
||||
const githubAuthService = await this.getGithubAuthService(state.config_key as string);
|
||||
const githubAuthService = await this.getGithubAuthService(state.config_key);
|
||||
return githubAuthService.getUserAuthUrl(state);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
code: string,
|
||||
state: string
|
||||
): Promise<{ stateBuffer: string; redirectUri?: string }> {
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(state as string, "base64").toString());
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(state, "base64").toString());
|
||||
let redirectUri = `${env.APP_BASE_URL}/${authState.workspace_slug}/settings/integrations/github-enterprise/`;
|
||||
|
||||
if (authState.profile_redirect) {
|
||||
@@ -79,8 +79,8 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
}
|
||||
|
||||
const githubState: GithubPlaneOAuthState = {
|
||||
github_code: code as string,
|
||||
encoded_github_state: state as string,
|
||||
github_code: code,
|
||||
encoded_github_state: state,
|
||||
};
|
||||
|
||||
const stateBuffer = Buffer.from(JSON.stringify(githubState)).toString("base64");
|
||||
@@ -101,11 +101,11 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
throw new Error(E_SILO_ERROR_CODES.INVALID_INSTALLATION_ACCOUNT.toString());
|
||||
}
|
||||
|
||||
const authState: GithubAuthorizeState = JSON.parse(Buffer.from(state as string, "base64").toString());
|
||||
const authState: GithubAuthorizeState = JSON.parse(Buffer.from(state, "base64").toString());
|
||||
const redirectUri = `${env.APP_BASE_URL}/${authState.workspace_slug}/settings/integrations/github-enterprise/`;
|
||||
|
||||
// Create github service from the installation id
|
||||
const service = await this.getGithubService(installation_id as string, authState.config_key as string);
|
||||
const service = await this.getGithubService(installation_id, authState.config_key as string);
|
||||
|
||||
// Get the installation details
|
||||
const installation = await service.getInstallation(Number(installation_id));
|
||||
@@ -120,7 +120,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
response: {
|
||||
identifier: installation.data.account.id.toString(),
|
||||
authorization_type: ESourceAuthorizationType.TOKEN,
|
||||
access_token: installation_id as string,
|
||||
access_token: installation_id,
|
||||
connection_id: installation.data.account.id.toString(),
|
||||
// @ts-expect-error - Ignoring ts error for dynamic key assignment
|
||||
connection_slug: installation.data.account.login,
|
||||
@@ -144,13 +144,11 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
async handlePlaneOAuthCallback(
|
||||
encodedIntegrationState: string
|
||||
): Promise<{ response: OAuthTokenResponse; state: OAuthState; redirectUri?: string }> {
|
||||
const githubState: GithubPlaneOAuthState = JSON.parse(
|
||||
Buffer.from(encodedIntegrationState as string, "base64").toString()
|
||||
);
|
||||
const githubState: GithubPlaneOAuthState = JSON.parse(Buffer.from(encodedIntegrationState, "base64").toString());
|
||||
|
||||
const { github_code: code, encoded_github_state } = githubState;
|
||||
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(encoded_github_state as string, "base64").toString());
|
||||
const authState: GithubUserAuthState = JSON.parse(Buffer.from(encoded_github_state, "base64").toString());
|
||||
|
||||
let redirectUri = `${env.APP_BASE_URL}/${authState.workspace_slug}/settings/integrations/github-enterprise/`;
|
||||
|
||||
@@ -160,7 +158,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
|
||||
const githubAuthService = await this.getGithubAuthService(authState.config_key as string);
|
||||
const { response, state: githubUserState } = await githubAuthService.getUserAccessToken({
|
||||
code: code as string,
|
||||
code: code,
|
||||
state: authState,
|
||||
});
|
||||
|
||||
@@ -204,7 +202,7 @@ export class GithubEnterpriseStrategy implements OAuthStrategy {
|
||||
}
|
||||
const githubService = getGithubService(
|
||||
wsConnection as TGithubWorkspaceConnection,
|
||||
wsCredential.source_access_token as string,
|
||||
wsCredential.source_access_token,
|
||||
true
|
||||
);
|
||||
const installation = await githubService.getInstallation(Number(wsCredential.source_access_token));
|
||||
|
||||
@@ -43,7 +43,7 @@ export class GitlabEnterpriseStrategy implements OAuthStrategy {
|
||||
if (!state.config_key) {
|
||||
throw new Error(E_SILO_ERROR_CODES.INVALID_APP_CREDENTIALS.toString());
|
||||
}
|
||||
const gitlabAuthService = await this.getGitlabAuthService(state.config_key as string);
|
||||
const gitlabAuthService = await this.getGitlabAuthService(state.config_key);
|
||||
return gitlabAuthService.getAuthUrl(state);
|
||||
}
|
||||
|
||||
@@ -56,15 +56,15 @@ export class GitlabEnterpriseStrategy implements OAuthStrategy {
|
||||
throw new Error(E_SILO_ERROR_CODES.INVALID_INSTALLATION_ACCOUNT.toString());
|
||||
}
|
||||
|
||||
const authState: GitLabAuthorizeState = JSON.parse(Buffer.from(state as string, "base64").toString());
|
||||
const authState: GitLabAuthorizeState = JSON.parse(Buffer.from(state, "base64").toString());
|
||||
const redirectUri = getIntegrationPageUrl(authState.workspace_slug, this.integrationKey);
|
||||
|
||||
// Create gitlab auth service
|
||||
const gitlabAuthService = await this.getGitlabAuthService(authState.config_key as string);
|
||||
|
||||
const { response: tokenResponse } = await gitlabAuthService.getAccessToken({
|
||||
code: code as string,
|
||||
state: state as string,
|
||||
code: code,
|
||||
state: state,
|
||||
});
|
||||
|
||||
if (!tokenResponse || !tokenResponse.access_token) {
|
||||
|
||||
@@ -33,7 +33,7 @@ export class SentryOAuthStrategy implements OAuthStrategy {
|
||||
state: string,
|
||||
additionalParams: Record<string, string>
|
||||
): Promise<{ response: OAuthTokenResponse; state: OAuthState; redirectUri?: string }> {
|
||||
const sentryAuthState: SentryAuthState = JSON.parse(Buffer.from(state as string, "base64").toString());
|
||||
const sentryAuthState: SentryAuthState = JSON.parse(Buffer.from(state, "base64").toString());
|
||||
const installationId = additionalParams.installationId;
|
||||
const org = additionalParams.orgSlug;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/order */
|
||||
import * as Sentry from "@sentry/react-router";
|
||||
import { startTransition, StrictMode } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
// hooks
|
||||
import { usePublish } from "@/hooks/store/publish";
|
||||
import CreateIssueModal from "@/plane-web/components/intake/create/create-issue-modal";
|
||||
import type { Route } from "./+types/page";
|
||||
|
||||
const IssuesPage = observer((props: Route.ComponentProps) => {
|
||||
const IssuesPage = observer(function IssuesPage(props: Route.ComponentProps) {
|
||||
const { params } = props;
|
||||
const { anchor } = params;
|
||||
// params
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import CreateTypeFormModal from "@/plane-web/components/intake/create/create-type-form-modal";
|
||||
import { useIntake } from "@/plane-web/hooks/store/use-intake";
|
||||
import type { Route } from "./+types/page";
|
||||
|
||||
const TypeFormPage = observer((props: Route.ComponentProps) => {
|
||||
const TypeFormPage = observer(function TypeFormPage(props: Route.ComponentProps) {
|
||||
const { params } = props;
|
||||
const { anchor } = params;
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import useSWR from "swr";
|
||||
// hooks
|
||||
import { useMember } from "@/hooks/store/use-member";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams, useSearchParams } from "next/navigation";
|
||||
// components
|
||||
@@ -9,7 +7,7 @@ import { usePublish } from "@/hooks/store/publish";
|
||||
// plane-web
|
||||
import { ViewLayoutsRoot } from "@/plane-web/components/issue-layouts/root";
|
||||
|
||||
const ViewsPage = observer(() => {
|
||||
const ViewsPage = observer(function ViewsPage() {
|
||||
// params
|
||||
const params = useParams<{ anchor: string }>();
|
||||
const { anchor } = params;
|
||||
|
||||
@@ -11,7 +11,7 @@ interface Props {
|
||||
subGroupId: string | undefined,
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
}
|
||||
|
||||
export const IssueLayoutHOC = observer(function IssueLayoutHOC(props: Props) {
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface IKanBan {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||
showEmptyGroup?: boolean;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ interface IKanbanGroup {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface IKanBanSwimLanes {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
showEmptyGroup: boolean;
|
||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||
orderBy: TIssueOrderByOptions | undefined;
|
||||
@@ -163,7 +163,7 @@ interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ interface ISubGroup {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||
loadMoreIssues: (groupId?: string, subGroupId?: string) => void;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export interface IList {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
}
|
||||
|
||||
export const List = observer(function List(props: IList) {
|
||||
|
||||
@@ -32,7 +32,7 @@ interface Props {
|
||||
isSubGroupCumulative: boolean
|
||||
) => number | undefined;
|
||||
getPaginationData: (groupId: string | undefined, subGroupId: string | undefined) => TPaginationData | undefined;
|
||||
getIssueLoader: (groupId?: string | undefined, subGroupId?: string | undefined) => TLoader;
|
||||
getIssueLoader: (groupId?: string, subGroupId?: string) => TLoader;
|
||||
}
|
||||
|
||||
// List loader component
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
// plane ui
|
||||
import { StateGroupIcon } from "@plane/propel/icons";
|
||||
|
||||
@@ -41,7 +41,7 @@ export const getGroupByColumns = (
|
||||
case "labels":
|
||||
return getLabelsColumns(label) as any;
|
||||
case "assignees":
|
||||
return getAssigneeColumns(member) as any;
|
||||
return getAssigneeColumns(member);
|
||||
case "created_by":
|
||||
return getCreatedByColumns(member) as any;
|
||||
default:
|
||||
@@ -62,7 +62,7 @@ const getCycleColumns = (cycleStore: ICycleStore): IGroupByColumn[] | undefined
|
||||
cycleGroups.push({
|
||||
id: cycle.id,
|
||||
name: cycle.name,
|
||||
icon: <CycleGroupIcon cycleGroup={cycleStatus as TCycleGroups} className="h-3.5 w-3.5" />,
|
||||
icon: <CycleGroupIcon cycleGroup={cycleStatus} className="h-3.5 w-3.5" />,
|
||||
payload: { cycle_id: cycle.id },
|
||||
});
|
||||
}
|
||||
@@ -193,11 +193,8 @@ export const getDisplayPropertiesCount = (
|
||||
return count;
|
||||
};
|
||||
|
||||
export const getIssueBlockId = (
|
||||
issueId: string | undefined,
|
||||
groupId: string | undefined,
|
||||
subGroupId?: string | undefined
|
||||
) => `issue_${issueId}_${groupId}_${subGroupId}`;
|
||||
export const getIssueBlockId = (issueId: string | undefined, groupId: string | undefined, subGroupId?: string) =>
|
||||
`issue_${issueId}_${groupId}_${subGroupId}`;
|
||||
|
||||
/**
|
||||
* returns empty Array if groupId is None
|
||||
|
||||
@@ -6,7 +6,7 @@ const useClipboardWritePermission = () => {
|
||||
useEffect(() => {
|
||||
const checkClipboardWriteAccess = () => {
|
||||
navigator.permissions
|
||||
//eslint-disable-next-line no-undef
|
||||
|
||||
.query({ name: "clipboard-write" as PermissionName })
|
||||
.then((result) => {
|
||||
if (result.state === "granted") {
|
||||
|
||||
@@ -32,7 +32,6 @@ export const useIntersectionObserver = (
|
||||
observer.observe(elementRef);
|
||||
return () => {
|
||||
if (elementRef) {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
observer.unobserve(elementRef);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -105,15 +105,15 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
|
||||
|
||||
const allIssues = groupedIssueIds[ALL_ISSUES] ?? [];
|
||||
if (allIssues && Array.isArray(allIssues)) {
|
||||
return allIssues as string[];
|
||||
return allIssues;
|
||||
}
|
||||
|
||||
if (groupId && groupedIssueIds?.[groupId] && Array.isArray(groupedIssueIds[groupId])) {
|
||||
return (groupedIssueIds[groupId] ?? []) as string[];
|
||||
return groupedIssueIds[groupId] ?? [];
|
||||
}
|
||||
|
||||
if (groupId && subGroupId) {
|
||||
return ((groupedIssueIds as TSubGroupedIssues)[groupId]?.[subGroupId] ?? []) as string[];
|
||||
return (groupedIssueIds as TSubGroupedIssues)[groupId]?.[subGroupId] ?? [];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -445,7 +445,7 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
|
||||
// if groupedIssueIds is an array, update the `groupedIssueIds` store at the issuePath
|
||||
if (groupedIssueIds && Array.isArray(groupedIssueIds)) {
|
||||
update(this, ["groupedIssueIds", ...issuePath], (issueIds: string[] = []) =>
|
||||
uniq(concat(issueIds, groupedIssueIds as string[]))
|
||||
uniq(concat(issueIds, groupedIssueIds))
|
||||
);
|
||||
// return true to indicate the store has been updated
|
||||
return true;
|
||||
|
||||
@@ -8,7 +8,7 @@ export type TEditorMentionComponentProps = TCallbackMentionComponentProps & {
|
||||
getMentionDetails?: (mentionType: TEditorMentionType, entityId: string) => TEditorMentionItem | undefined;
|
||||
};
|
||||
|
||||
export const EditorAdditionalMentionsRoot: React.FC<TEditorMentionComponentProps> = (props) => {
|
||||
export function EditorAdditionalMentionsRoot(props: TEditorMentionComponentProps) {
|
||||
const { entity_name } = props;
|
||||
|
||||
switch (entity_name) {
|
||||
@@ -17,4 +17,4 @@ export const EditorAdditionalMentionsRoot: React.FC<TEditorMentionComponentProps
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ type Props = {
|
||||
workItemDetails: TEditorWorkItemMention;
|
||||
};
|
||||
|
||||
export const EditorWorkItemMentionContent: React.FC<Props> = observer((props) => {
|
||||
export const EditorWorkItemMentionContent = observer(function EditorWorkItemMentionContent(props: Props) {
|
||||
const { workItemDetails } = props;
|
||||
// derived values
|
||||
const trimmedName =
|
||||
|
||||
@@ -9,7 +9,7 @@ type Props = {
|
||||
stateGroup: TStateGroups;
|
||||
};
|
||||
|
||||
export const EditorWorkItemMentionLogo: React.FC<Props> = observer((props) => {
|
||||
export const EditorWorkItemMentionLogo = observer(function EditorWorkItemMentionLogo(props: Props) {
|
||||
const { className, stateColor, stateGroup } = props;
|
||||
|
||||
return <StateGroupIcon stateGroup={stateGroup} color={stateColor} className={className} />;
|
||||
|
||||
@@ -7,7 +7,7 @@ type Props = {
|
||||
workItemDetails: TEditorWorkItemMention;
|
||||
};
|
||||
|
||||
export const EditorWorkItemMentionPreview: React.FC<Props> = observer((props) => {
|
||||
export const EditorWorkItemMentionPreview = observer(function EditorWorkItemMentionPreview(props: Props) {
|
||||
const { workItemDetails } = props;
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { TEditorMentionComponentProps } from "../root";
|
||||
import { EditorWorkItemMentionContent } from "./content";
|
||||
import { EditorWorkItemMentionPreview } from "./preview";
|
||||
|
||||
export const EditorWorkItemMention: React.FC<TEditorMentionComponentProps> = observer((props) => {
|
||||
export const EditorWorkItemMention = observer(function EditorWorkItemMention(props: TEditorMentionComponentProps) {
|
||||
const { entity_identifier: workItemId, getMentionDetails } = props;
|
||||
// derived values
|
||||
const workItemDetails = getMentionDetails?.("issue_mention", workItemId);
|
||||
|
||||
@@ -18,7 +18,7 @@ export const EmbedHandler: React.FC<ExternalEmbedNodeViewProps> = memo(
|
||||
))
|
||||
);
|
||||
|
||||
const EmbedHandlerRender: React.FC<ExternalEmbedNodeViewProps> = observer((props) => {
|
||||
const EmbedHandlerRender = observer(function EmbedHandlerRender(props: ExternalEmbedNodeViewProps) {
|
||||
const { node } = props;
|
||||
const {
|
||||
src,
|
||||
|
||||
@@ -12,13 +12,13 @@ import type { ChartDataType, IGanttBlock } from "../types";
|
||||
|
||||
type Props = {
|
||||
blockId: string;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock | undefined;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType) => IGanttBlock | undefined;
|
||||
showAllBlocks: boolean;
|
||||
blockToRender: (data: any) => React.ReactNode;
|
||||
ganttContainerRef: React.RefObject<HTMLDivElement>;
|
||||
};
|
||||
|
||||
export const GanttChartBlock: React.FC<Props> = observer((props) => {
|
||||
export const GanttChartBlock = observer(function GanttChartBlock(props: Props) {
|
||||
const { blockId, getBlockById, showAllBlocks, blockToRender, ganttContainerRef } = props;
|
||||
// store hooks
|
||||
const { currentViewData, updateActiveBlockId, isBlockActive } = useGanttChart();
|
||||
|
||||
@@ -10,13 +10,13 @@ import { GanttChartBlock } from "./block";
|
||||
export type GanttChartBlocksProps = {
|
||||
itemsContainerWidth: number;
|
||||
blockIds: string[];
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock | undefined;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType) => IGanttBlock | undefined;
|
||||
blockToRender: (data: any) => React.ReactNode;
|
||||
ganttContainerRef: React.RefObject<HTMLDivElement>;
|
||||
showAllBlocks: boolean;
|
||||
};
|
||||
|
||||
export const GanttChartBlocksList: FC<GanttChartBlocksProps> = (props) => {
|
||||
export function GanttChartBlocksList(props: GanttChartBlocksProps) {
|
||||
const { itemsContainerWidth, blockIds, blockToRender, getBlockById, ganttContainerRef, showAllBlocks } = props;
|
||||
|
||||
return (
|
||||
@@ -39,4 +39,4 @@ export const GanttChartBlocksList: FC<GanttChartBlocksProps> = (props) => {
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ type Props = {
|
||||
toggleFullScreenMode: () => void;
|
||||
};
|
||||
|
||||
export const GanttChartHeader: React.FC<Props> = observer((props) => {
|
||||
export const GanttChartHeader = observer(function GanttChartHeader(props: Props) {
|
||||
const { fullScreenMode, handleToday, toggleFullScreenMode } = props;
|
||||
// chart hook
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useGanttChart } from "../hooks/use-gantt-chart";
|
||||
|
||||
type Props = {
|
||||
blockIds: string[];
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock | undefined;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType) => IGanttBlock | undefined;
|
||||
canLoadMoreBlocks?: boolean;
|
||||
loadMoreBlocks?: () => void;
|
||||
blockToRender: (data: any) => React.ReactNode;
|
||||
@@ -33,7 +33,7 @@ type Props = {
|
||||
updateCurrentViewRenderPayload: (direction: "left" | "right", currentView: TGanttViews) => void;
|
||||
};
|
||||
|
||||
export const GanttChartMainContent: React.FC<Props> = observer((props) => {
|
||||
export const GanttChartMainContent = observer(function GanttChartMainContent(props: Props) {
|
||||
const {
|
||||
blockIds,
|
||||
getBlockById,
|
||||
|
||||
@@ -20,12 +20,12 @@ type ChartViewRootProps = {
|
||||
sidebarToRender: (props: any) => React.ReactNode;
|
||||
bottomSpacing: boolean;
|
||||
showAllBlocks: boolean;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock | undefined;
|
||||
getBlockById: (id: string, currentViewData?: ChartDataType) => IGanttBlock | undefined;
|
||||
loadMoreBlocks?: () => void;
|
||||
canLoadMoreBlocks?: boolean;
|
||||
};
|
||||
|
||||
export const ChartViewRoot: FC<ChartViewRootProps> = observer((props) => {
|
||||
export const ChartViewRoot = observer(function ChartViewRoot(props: ChartViewRootProps) {
|
||||
const {
|
||||
border,
|
||||
title,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user