Compare commits

..
165 changed files with 1508 additions and 1840 deletions
+5 -7
View File
@@ -10,13 +10,11 @@ type Props = {
handleClose: () => void;
};
const ESendEmailSteps = {
SEND_EMAIL: "SEND_EMAIL",
SUCCESS: "SUCCESS",
FAILED: "FAILED",
} as const;
type ESendEmailSteps = typeof ESendEmailSteps[keyof typeof ESendEmailSteps];
enum ESendEmailSteps {
SEND_EMAIL = "SEND_EMAIL",
SUCCESS = "SUCCESS",
FAILED = "FAILED",
}
const instanceService = new InstanceService();
+9 -11
View File
@@ -16,16 +16,14 @@ import { Banner, PasswordStrengthMeter } from "@/components/common";
const authService = new AuthService();
// error codes
const EErrorCodes = {
INSTANCE_NOT_CONFIGURED: "INSTANCE_NOT_CONFIGURED",
ADMIN_ALREADY_EXIST: "ADMIN_ALREADY_EXIST",
REQUIRED_EMAIL_PASSWORD_FIRST_NAME: "REQUIRED_EMAIL_PASSWORD_FIRST_NAME",
INVALID_EMAIL: "INVALID_EMAIL",
INVALID_PASSWORD: "INVALID_PASSWORD",
USER_ALREADY_EXISTS: "USER_ALREADY_EXISTS",
} as const;
type EErrorCodes = typeof EErrorCodes[keyof typeof EErrorCodes];
enum EErrorCodes {
INSTANCE_NOT_CONFIGURED = "INSTANCE_NOT_CONFIGURED",
ADMIN_ALREADY_EXIST = "ADMIN_ALREADY_EXIST",
REQUIRED_EMAIL_PASSWORD_FIRST_NAME = "REQUIRED_EMAIL_PASSWORD_FIRST_NAME",
INVALID_EMAIL = "INVALID_EMAIL",
INVALID_PASSWORD = "INVALID_PASSWORD",
USER_ALREADY_EXISTS = "USER_ALREADY_EXISTS",
}
type TError = {
type: EErrorCodes | undefined;
@@ -146,7 +144,7 @@ export const InstanceSetupForm: FC = (props) => {
{errorData.type &&
errorData?.message &&
!([EErrorCodes.INVALID_EMAIL, EErrorCodes.INVALID_PASSWORD] as EErrorCodes[]).includes(errorData.type) && (
![EErrorCodes.INVALID_EMAIL, EErrorCodes.INVALID_PASSWORD].includes(errorData.type) && (
<Banner type="error" message={errorData?.message} />
)}
+7 -9
View File
@@ -18,15 +18,13 @@ import { AuthBanner } from "../authentication";
const authService = new AuthService();
// error codes
const EErrorCodes = {
INSTANCE_NOT_CONFIGURED: "INSTANCE_NOT_CONFIGURED",
REQUIRED_EMAIL_PASSWORD: "REQUIRED_EMAIL_PASSWORD",
INVALID_EMAIL: "INVALID_EMAIL",
USER_DOES_NOT_EXIST: "USER_DOES_NOT_EXIST",
AUTHENTICATION_FAILED: "AUTHENTICATION_FAILED",
} as const;
type EErrorCodes = typeof EErrorCodes[keyof typeof EErrorCodes];
enum EErrorCodes {
INSTANCE_NOT_CONFIGURED = "INSTANCE_NOT_CONFIGURED",
REQUIRED_EMAIL_PASSWORD = "REQUIRED_EMAIL_PASSWORD",
INVALID_EMAIL = "INVALID_EMAIL",
USER_DOES_NOT_EXIST = "USER_DOES_NOT_EXIST",
AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED",
}
type TError = {
type: EErrorCodes | undefined;
+7 -9
View File
@@ -20,15 +20,13 @@ import githubDarkModeImage from "@/public/logos/github-white.png";
import GitlabLogo from "@/public/logos/gitlab-logo.svg";
import GoogleLogo from "@/public/logos/google-logo.svg";
export const EErrorAlertType = {
BANNER_ALERT: "BANNER_ALERT",
INLINE_FIRST_NAME: "INLINE_FIRST_NAME",
INLINE_EMAIL: "INLINE_EMAIL",
INLINE_PASSWORD: "INLINE_PASSWORD",
INLINE_EMAIL_CODE: "INLINE_EMAIL_CODE",
} as const;
export type EErrorAlertType = typeof EErrorAlertType[keyof typeof EErrorAlertType];
export enum EErrorAlertType {
BANNER_ALERT = "BANNER_ALERT",
INLINE_FIRST_NAME = "INLINE_FIRST_NAME",
INLINE_EMAIL = "INLINE_EMAIL",
INLINE_PASSWORD = "INLINE_PASSWORD",
INLINE_EMAIL_CODE = "INLINE_EMAIL_CODE",
}
const errorCodeMessages: {
[key in EAdminAuthErrorCodes]: { title: string; message: (email?: string | undefined) => ReactNode };
+1 -1
View File
@@ -50,6 +50,6 @@
"@types/react-dom": "^18.2.18",
"@types/uuid": "^9.0.8",
"@types/zxcvbn": "^4.4.4",
"typescript": "5.8.3"
"typescript": "5.3.3"
}
}
+16 -4
View File
@@ -341,7 +341,10 @@ class ProjectViewSet(BaseViewSet):
except IntegrityError as e:
if "already exists" in str(e):
return Response(
{"name": "The project name is already taken"},
{
"name": "The project name is already taken",
"code": "PROJECT_NAME_ALREADY_EXIST",
},
status=status.HTTP_409_CONFLICT,
)
except Workspace.DoesNotExist:
@@ -350,7 +353,10 @@ class ProjectViewSet(BaseViewSet):
)
except serializers.ValidationError:
return Response(
{"identifier": "The project identifier is already taken"},
{
"identifier": "The project identifier is already taken",
"code": "PROJECT_IDENTIFIER_ALREADY_EXIST",
},
status=status.HTTP_409_CONFLICT,
)
@@ -419,7 +425,10 @@ class ProjectViewSet(BaseViewSet):
except IntegrityError as e:
if "already exists" in str(e):
return Response(
{"name": "The project name is already taken"},
{
"name": "The project name is already taken",
"code": "PROJECT_NAME_ALREADY_EXIST",
},
status=status.HTTP_409_CONFLICT,
)
except (Project.DoesNotExist, Workspace.DoesNotExist):
@@ -428,7 +437,10 @@ class ProjectViewSet(BaseViewSet):
)
except serializers.ValidationError:
return Response(
{"identifier": "The project identifier is already taken"},
{
"identifier": "The project identifier is already taken",
"code": "PROJECT_IDENTIFIER_ALREADY_EXIST",
},
status=status.HTTP_409_CONFLICT,
)
+1 -1
View File
@@ -9,4 +9,4 @@ factory-boy==3.3.0
freezegun==1.2.2
coverage==7.2.7
httpx==0.24.1
requests==2.32.4
requests==2.32.2
+1 -1
View File
@@ -58,6 +58,6 @@
"nodemon": "^3.1.7",
"ts-node": "^10.9.2",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "5.3.3"
}
}
+3 -5
View File
@@ -1,5 +1,3 @@
export const AI_EDITOR_TASKS = {
ASK_ANYTHING: "ASK_ANYTHING",
} as const;
export type AI_EDITOR_TASKS = typeof AI_EDITOR_TASKS[keyof typeof AI_EDITOR_TASKS];
export enum AI_EDITOR_TASKS {
ASK_ANYTHING = "ASK_ANYTHING",
}
+100 -116
View File
@@ -1,11 +1,9 @@
export const E_PASSWORD_STRENGTH = {
EMPTY: "empty",
LENGTH_NOT_VALID: "length_not_valid",
STRENGTH_NOT_VALID: "strength_not_valid",
STRENGTH_VALID: "strength_valid",
} as const;
export type E_PASSWORD_STRENGTH = typeof E_PASSWORD_STRENGTH[keyof typeof E_PASSWORD_STRENGTH];
export enum E_PASSWORD_STRENGTH {
EMPTY = "empty",
LENGTH_NOT_VALID = "length_not_valid",
STRENGTH_NOT_VALID = "strength_not_valid",
STRENGTH_VALID = "strength_valid",
}
export const PASSWORD_MIN_LENGTH = 8;
@@ -33,51 +31,41 @@ export const SPACE_PASSWORD_CRITERIA = [
// },
];
export const EAuthPageTypes = {
PUBLIC: "PUBLIC",
NON_AUTHENTICATED: "NON_AUTHENTICATED",
SET_PASSWORD: "SET_PASSWORD",
ONBOARDING: "ONBOARDING",
AUTHENTICATED: "AUTHENTICATED",
} as const;
export enum EAuthPageTypes {
PUBLIC = "PUBLIC",
NON_AUTHENTICATED = "NON_AUTHENTICATED",
SET_PASSWORD = "SET_PASSWORD",
ONBOARDING = "ONBOARDING",
AUTHENTICATED = "AUTHENTICATED",
}
export type EAuthPageTypes = typeof EAuthPageTypes[keyof typeof EAuthPageTypes];
export enum EPageTypes {
INIT = "INIT",
PUBLIC = "PUBLIC",
NON_AUTHENTICATED = "NON_AUTHENTICATED",
ONBOARDING = "ONBOARDING",
AUTHENTICATED = "AUTHENTICATED",
}
export const EPageTypes = {
INIT: "INIT",
PUBLIC: "PUBLIC",
NON_AUTHENTICATED: "NON_AUTHENTICATED",
ONBOARDING: "ONBOARDING",
AUTHENTICATED: "AUTHENTICATED",
} as const;
export enum EAuthModes {
SIGN_IN = "SIGN_IN",
SIGN_UP = "SIGN_UP",
}
export type EPageTypes = typeof EPageTypes[keyof typeof EPageTypes];
export enum EAuthSteps {
EMAIL = "EMAIL",
PASSWORD = "PASSWORD",
UNIQUE_CODE = "UNIQUE_CODE",
}
export const EAuthModes = {
SIGN_IN: "SIGN_IN",
SIGN_UP: "SIGN_UP",
} as const;
export type EAuthModes = typeof EAuthModes[keyof typeof EAuthModes];
export const EAuthSteps = {
EMAIL: "EMAIL",
PASSWORD: "PASSWORD",
UNIQUE_CODE: "UNIQUE_CODE",
} as const;
export type EAuthSteps = typeof EAuthSteps[keyof typeof EAuthSteps];
export const EErrorAlertType = {
BANNER_ALERT: "BANNER_ALERT",
TOAST_ALERT: "TOAST_ALERT",
INLINE_FIRST_NAME: "INLINE_FIRST_NAME",
INLINE_EMAIL: "INLINE_EMAIL",
INLINE_PASSWORD: "INLINE_PASSWORD",
INLINE_EMAIL_CODE: "INLINE_EMAIL_CODE",
} as const;
export type EErrorAlertType = typeof EErrorAlertType[keyof typeof EErrorAlertType];
export enum EErrorAlertType {
BANNER_ALERT = "BANNER_ALERT",
TOAST_ALERT = "TOAST_ALERT",
INLINE_FIRST_NAME = "INLINE_FIRST_NAME",
INLINE_EMAIL = "INLINE_EMAIL",
INLINE_PASSWORD = "INLINE_PASSWORD",
INLINE_EMAIL_CODE = "INLINE_EMAIL_CODE",
}
export type TAuthErrorInfo = {
type: EErrorAlertType;
@@ -86,83 +74,79 @@ export type TAuthErrorInfo = {
message: any;
};
export const EAdminAuthErrorCodes = {
export enum EAdminAuthErrorCodes {
// Admin
ADMIN_ALREADY_EXIST: "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME: "5155",
INVALID_ADMIN_EMAIL: "5160",
INVALID_ADMIN_PASSWORD: "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD: "5170",
ADMIN_AUTHENTICATION_FAILED: "5175",
ADMIN_USER_ALREADY_EXIST: "5180",
ADMIN_USER_DOES_NOT_EXIST: "5185",
ADMIN_USER_DEACTIVATED: "5190",
} as const;
ADMIN_ALREADY_EXIST = "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME = "5155",
INVALID_ADMIN_EMAIL = "5160",
INVALID_ADMIN_PASSWORD = "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD = "5170",
ADMIN_AUTHENTICATION_FAILED = "5175",
ADMIN_USER_ALREADY_EXIST = "5180",
ADMIN_USER_DOES_NOT_EXIST = "5185",
ADMIN_USER_DEACTIVATED = "5190",
}
export type EAdminAuthErrorCodes = typeof EAdminAuthErrorCodes[keyof typeof EAdminAuthErrorCodes];
export const EAuthErrorCodes = {
export enum EAuthErrorCodes {
// Global
INSTANCE_NOT_CONFIGURED: "5000",
INVALID_EMAIL: "5005",
EMAIL_REQUIRED: "5010",
SIGNUP_DISABLED: "5015",
MAGIC_LINK_LOGIN_DISABLED: "5016",
PASSWORD_LOGIN_DISABLED: "5018",
USER_ACCOUNT_DEACTIVATED: "5019",
INSTANCE_NOT_CONFIGURED = "5000",
INVALID_EMAIL = "5005",
EMAIL_REQUIRED = "5010",
SIGNUP_DISABLED = "5015",
MAGIC_LINK_LOGIN_DISABLED = "5016",
PASSWORD_LOGIN_DISABLED = "5018",
USER_ACCOUNT_DEACTIVATED = "5019",
// Password strength
INVALID_PASSWORD: "5020",
SMTP_NOT_CONFIGURED: "5025",
INVALID_PASSWORD = "5020",
SMTP_NOT_CONFIGURED = "5025",
// Sign Up
USER_ALREADY_EXIST: "5030",
AUTHENTICATION_FAILED_SIGN_UP: "5035",
REQUIRED_EMAIL_PASSWORD_SIGN_UP: "5040",
INVALID_EMAIL_SIGN_UP: "5045",
INVALID_EMAIL_MAGIC_SIGN_UP: "5050",
MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED: "5055",
USER_ALREADY_EXIST = "5030",
AUTHENTICATION_FAILED_SIGN_UP = "5035",
REQUIRED_EMAIL_PASSWORD_SIGN_UP = "5040",
INVALID_EMAIL_SIGN_UP = "5045",
INVALID_EMAIL_MAGIC_SIGN_UP = "5050",
MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED = "5055",
// Sign In
USER_DOES_NOT_EXIST: "5060",
AUTHENTICATION_FAILED_SIGN_IN: "5065",
REQUIRED_EMAIL_PASSWORD_SIGN_IN: "5070",
INVALID_EMAIL_SIGN_IN: "5075",
INVALID_EMAIL_MAGIC_SIGN_IN: "5080",
MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED: "5085",
USER_DOES_NOT_EXIST = "5060",
AUTHENTICATION_FAILED_SIGN_IN = "5065",
REQUIRED_EMAIL_PASSWORD_SIGN_IN = "5070",
INVALID_EMAIL_SIGN_IN = "5075",
INVALID_EMAIL_MAGIC_SIGN_IN = "5080",
MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED = "5085",
// Both Sign in and Sign up for magic
INVALID_MAGIC_CODE_SIGN_IN: "5090",
INVALID_MAGIC_CODE_SIGN_UP: "5092",
EXPIRED_MAGIC_CODE_SIGN_IN: "5095",
EXPIRED_MAGIC_CODE_SIGN_UP: "5097",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN: "5100",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP: "5102",
INVALID_MAGIC_CODE_SIGN_IN = "5090",
INVALID_MAGIC_CODE_SIGN_UP = "5092",
EXPIRED_MAGIC_CODE_SIGN_IN = "5095",
EXPIRED_MAGIC_CODE_SIGN_UP = "5097",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN = "5100",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP = "5102",
// Oauth
OAUTH_NOT_CONFIGURED: "5104",
GOOGLE_NOT_CONFIGURED: "5105",
GITHUB_NOT_CONFIGURED: "5110",
GITLAB_NOT_CONFIGURED: "5111",
GOOGLE_OAUTH_PROVIDER_ERROR: "5115",
GITHUB_OAUTH_PROVIDER_ERROR: "5120",
GITLAB_OAUTH_PROVIDER_ERROR: "5121",
OAUTH_NOT_CONFIGURED = "5104",
GOOGLE_NOT_CONFIGURED = "5105",
GITHUB_NOT_CONFIGURED = "5110",
GITLAB_NOT_CONFIGURED = "5111",
GOOGLE_OAUTH_PROVIDER_ERROR = "5115",
GITHUB_OAUTH_PROVIDER_ERROR = "5120",
GITLAB_OAUTH_PROVIDER_ERROR = "5121",
// Reset Password
INVALID_PASSWORD_TOKEN: "5125",
EXPIRED_PASSWORD_TOKEN: "5130",
INVALID_PASSWORD_TOKEN = "5125",
EXPIRED_PASSWORD_TOKEN = "5130",
// Change password
INCORRECT_OLD_PASSWORD: "5135",
MISSING_PASSWORD: "5138",
INVALID_NEW_PASSWORD: "5140",
INCORRECT_OLD_PASSWORD = "5135",
MISSING_PASSWORD = "5138",
INVALID_NEW_PASSWORD = "5140",
// set password
PASSWORD_ALREADY_SET: "5145",
PASSWORD_ALREADY_SET = "5145",
// Admin
ADMIN_ALREADY_EXIST: "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME: "5155",
INVALID_ADMIN_EMAIL: "5160",
INVALID_ADMIN_PASSWORD: "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD: "5170",
ADMIN_AUTHENTICATION_FAILED: "5175",
ADMIN_USER_ALREADY_EXIST: "5180",
ADMIN_USER_DOES_NOT_EXIST: "5185",
ADMIN_USER_DEACTIVATED: "5190",
ADMIN_ALREADY_EXIST = "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME = "5155",
INVALID_ADMIN_EMAIL = "5160",
INVALID_ADMIN_PASSWORD = "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD = "5170",
ADMIN_AUTHENTICATION_FAILED = "5175",
ADMIN_USER_ALREADY_EXIST = "5180",
ADMIN_USER_DOES_NOT_EXIST = "5185",
ADMIN_USER_DEACTIVATED = "5190",
// Rate limit
RATE_LIMIT_EXCEEDED: "5900",
} as const;
export type EAuthErrorCodes = typeof EAuthErrorCodes[keyof typeof EAuthErrorCodes];
RATE_LIMIT_EXCEEDED = "5900",
}
+42 -50
View File
@@ -4,49 +4,43 @@ export const LABEL_CLASSNAME = "uppercase text-custom-text-300/60 text-sm tracki
export const AXIS_LABEL_CLASSNAME = "uppercase text-custom-text-300/60 text-sm tracking-wide";
export const ChartXAxisProperty = {
STATES: "STATES",
STATE_GROUPS: "STATE_GROUPS",
LABELS: "LABELS",
ASSIGNEES: "ASSIGNEES",
ESTIMATE_POINTS: "ESTIMATE_POINTS",
CYCLES: "CYCLES",
MODULES: "MODULES",
PRIORITY: "PRIORITY",
START_DATE: "START_DATE",
TARGET_DATE: "TARGET_DATE",
CREATED_AT: "CREATED_AT",
COMPLETED_AT: "COMPLETED_AT",
CREATED_BY: "CREATED_BY",
WORK_ITEM_TYPES: "WORK_ITEM_TYPES",
PROJECTS: "PROJECTS",
EPICS: "EPICS",
} as const;
export enum ChartXAxisProperty {
STATES = "STATES",
STATE_GROUPS = "STATE_GROUPS",
LABELS = "LABELS",
ASSIGNEES = "ASSIGNEES",
ESTIMATE_POINTS = "ESTIMATE_POINTS",
CYCLES = "CYCLES",
MODULES = "MODULES",
PRIORITY = "PRIORITY",
START_DATE = "START_DATE",
TARGET_DATE = "TARGET_DATE",
CREATED_AT = "CREATED_AT",
COMPLETED_AT = "COMPLETED_AT",
CREATED_BY = "CREATED_BY",
WORK_ITEM_TYPES = "WORK_ITEM_TYPES",
PROJECTS = "PROJECTS",
EPICS = "EPICS",
}
export type ChartXAxisProperty = typeof ChartXAxisProperty[keyof typeof ChartXAxisProperty];
export const ChartYAxisMetric = {
WORK_ITEM_COUNT: "WORK_ITEM_COUNT",
ESTIMATE_POINT_COUNT: "ESTIMATE_POINT_COUNT",
PENDING_WORK_ITEM_COUNT: "PENDING_WORK_ITEM_COUNT",
COMPLETED_WORK_ITEM_COUNT: "COMPLETED_WORK_ITEM_COUNT",
IN_PROGRESS_WORK_ITEM_COUNT: "IN_PROGRESS_WORK_ITEM_COUNT",
WORK_ITEM_DUE_THIS_WEEK_COUNT: "WORK_ITEM_DUE_THIS_WEEK_COUNT",
WORK_ITEM_DUE_TODAY_COUNT: "WORK_ITEM_DUE_TODAY_COUNT",
BLOCKED_WORK_ITEM_COUNT: "BLOCKED_WORK_ITEM_COUNT",
} as const;
export type ChartYAxisMetric = typeof ChartYAxisMetric[keyof typeof ChartYAxisMetric];
export enum ChartYAxisMetric {
WORK_ITEM_COUNT = "WORK_ITEM_COUNT",
ESTIMATE_POINT_COUNT = "ESTIMATE_POINT_COUNT",
PENDING_WORK_ITEM_COUNT = "PENDING_WORK_ITEM_COUNT",
COMPLETED_WORK_ITEM_COUNT = "COMPLETED_WORK_ITEM_COUNT",
IN_PROGRESS_WORK_ITEM_COUNT = "IN_PROGRESS_WORK_ITEM_COUNT",
WORK_ITEM_DUE_THIS_WEEK_COUNT = "WORK_ITEM_DUE_THIS_WEEK_COUNT",
WORK_ITEM_DUE_TODAY_COUNT = "WORK_ITEM_DUE_TODAY_COUNT",
BLOCKED_WORK_ITEM_COUNT = "BLOCKED_WORK_ITEM_COUNT",
}
export const ChartXAxisDateGrouping = {
DAY: "DAY",
WEEK: "WEEK",
MONTH: "MONTH",
YEAR: "YEAR",
} as const;
export type ChartXAxisDateGrouping = typeof ChartXAxisDateGrouping[keyof typeof ChartXAxisDateGrouping];
export enum ChartXAxisDateGrouping {
DAY = "DAY",
WEEK = "WEEK",
MONTH = "MONTH",
YEAR = "YEAR",
}
export const TO_CAPITALIZE_PROPERTIES: ChartXAxisProperty[] = [
ChartXAxisProperty.PRIORITY,
@@ -61,16 +55,14 @@ export const CHART_X_AXIS_DATE_PROPERTIES: ChartXAxisProperty[] = [
];
export const EChartModels = {
BASIC: "BASIC",
STACKED: "STACKED",
GROUPED: "GROUPED",
MULTI_LINE: "MULTI_LINE",
COMPARISON: "COMPARISON",
PROGRESS: "PROGRESS",
} as const;
export type EChartModels = typeof EChartModels[keyof typeof EChartModels];
export enum EChartModels {
BASIC = "BASIC",
STACKED = "STACKED",
GROUPED = "GROUPED",
MULTI_LINE = "MULTI_LINE",
COMPARISON = "COMPARISON",
PROGRESS = "PROGRESS",
}
export const CHART_COLOR_PALETTES: {
key: TChartColorScheme;
+8 -10
View File
@@ -1,16 +1,14 @@
// types
import { TIssuesListTypes } from "@plane/types";
export const EDurationFilters = {
NONE: "none",
TODAY: "today",
THIS_WEEK: "this_week",
THIS_MONTH: "this_month",
THIS_YEAR: "this_year",
CUSTOM: "custom",
} as const;
export type EDurationFilters = typeof EDurationFilters[keyof typeof EDurationFilters];
export enum EDurationFilters {
NONE = "none",
TODAY = "today",
THIS_WEEK = "this_week",
THIS_MONTH = "this_month",
THIS_YEAR = "this_year",
CUSTOM = "custom",
}
// filter duration options
export const DURATION_FILTER_OPTIONS: {
+4 -6
View File
@@ -1,9 +1,7 @@
export const E_SORT_ORDER = {
ASC: "asc",
DESC: "desc",
} as const;
export type E_SORT_ORDER = typeof E_SORT_ORDER[keyof typeof E_SORT_ORDER];
export enum E_SORT_ORDER {
ASC = "asc",
DESC = "desc",
}
export const DATE_AFTER_FILTER_OPTIONS = [
{
name: "1 week from now",
+7 -9
View File
@@ -1,9 +1,7 @@
export const EIconSize = {
XS: "xs",
SM: "sm",
MD: "md",
LG: "lg",
XL: "xl",
} as const;
export type EIconSize = typeof EIconSize[keyof typeof EIconSize];
export enum EIconSize {
XS = "xs",
SM = "sm",
MD = "md",
LG = "lg",
XL = "xl",
}
+16 -22
View File
@@ -1,29 +1,23 @@
import { TInboxDuplicateIssueDetails, TIssue } from "@plane/types";
export const EInboxIssueCurrentTab = {
OPEN: "open",
CLOSED: "closed",
} as const;
export enum EInboxIssueCurrentTab {
OPEN = "open",
CLOSED = "closed",
}
export type EInboxIssueCurrentTab = typeof EInboxIssueCurrentTab[keyof typeof EInboxIssueCurrentTab];
export enum EInboxIssueStatus {
PENDING = -2,
DECLINED = -1,
SNOOZED = 0,
ACCEPTED = 1,
DUPLICATE = 2,
}
export const EInboxIssueStatus = {
PENDING: -2,
DECLINED: -1,
SNOOZED: 0,
ACCEPTED: 1,
DUPLICATE: 2,
} as const;
export type EInboxIssueStatus = typeof EInboxIssueStatus[keyof typeof EInboxIssueStatus];
export const EInboxIssueSource = {
IN_APP: "IN_APP",
FORMS: "FORMS",
EMAIL: "EMAIL",
} as const;
export type EInboxIssueSource = typeof EInboxIssueSource[keyof typeof EInboxIssueSource];
export enum EInboxIssueSource {
IN_APP = "IN_APP",
FORMS = "FORMS",
EMAIL = "EMAIL",
}
export type TInboxIssueCurrentTab = EInboxIssueCurrentTab;
export type TInboxIssueStatus = EInboxIssueStatus;
+4 -6
View File
@@ -1,9 +1,7 @@
export const EInstanceStatus = {
ERROR: "ERROR",
NOT_YET_READY: "NOT_YET_READY",
} as const;
export type EInstanceStatus = typeof EInstanceStatus[keyof typeof EInstanceStatus];
export enum EInstanceStatus {
ERROR = "ERROR",
NOT_YET_READY = "NOT_YET_READY",
}
export type TInstanceStatus = {
status: EInstanceStatus | undefined;
+63 -75
View File
@@ -17,78 +17,66 @@ export type TIssueFilterPriorityObject = {
icon: string;
};
export const EIssueGroupByToServerOptions = {
"state": "state_id",
"priority": "priority",
"labels": "labels__id",
"state_detail.group": "state__group",
"assignees": "assignees__id",
"cycle": "cycle_id",
"module": "issue_module__module_id",
"target_date": "target_date",
"project": "project_id",
"created_by": "created_by",
"team_project": "project_id",
} as const;
export enum EIssueGroupByToServerOptions {
"state" = "state_id",
"priority" = "priority",
"labels" = "labels__id",
"state_detail.group" = "state__group",
"assignees" = "assignees__id",
"cycle" = "cycle_id",
"module" = "issue_module__module_id",
"target_date" = "target_date",
"project" = "project_id",
"created_by" = "created_by",
"team_project" = "project_id",
}
export type EIssueGroupByToServerOptions = typeof EIssueGroupByToServerOptions[keyof typeof EIssueGroupByToServerOptions];
export enum EIssueGroupBYServerToProperty {
"state_id" = "state_id",
"priority" = "priority",
"labels__id" = "label_ids",
"state__group" = "state__group",
"assignees__id" = "assignee_ids",
"cycle_id" = "cycle_id",
"issue_module__module_id" = "module_ids",
"target_date" = "target_date",
"project_id" = "project_id",
"created_by" = "created_by",
}
export const EIssueGroupBYServerToProperty = {
"state_id": "state_id",
"priority": "priority",
"labels__id": "label_ids",
"state__group": "state__group",
"assignees__id": "assignee_ids",
"cycle_id": "cycle_id",
"issue_module__module_id": "module_ids",
"target_date": "target_date",
"project_id": "project_id",
"created_by": "created_by",
} as const;
export enum EIssueServiceType {
ISSUES = "issues",
EPICS = "epics",
WORK_ITEMS = "work-items",
}
export type EIssueGroupBYServerToProperty = typeof EIssueGroupBYServerToProperty[keyof typeof EIssueGroupBYServerToProperty];
export enum EIssuesStoreType {
GLOBAL = "GLOBAL",
PROFILE = "PROFILE",
TEAM = "TEAM",
PROJECT = "PROJECT",
CYCLE = "CYCLE",
MODULE = "MODULE",
TEAM_VIEW = "TEAM_VIEW",
PROJECT_VIEW = "PROJECT_VIEW",
ARCHIVED = "ARCHIVED",
DRAFT = "DRAFT",
DEFAULT = "DEFAULT",
WORKSPACE_DRAFT = "WORKSPACE_DRAFT",
EPIC = "EPIC",
}
export const EIssueServiceType = {
ISSUES: "issues",
EPICS: "epics",
WORK_ITEMS: "work-items",
} as const;
export enum EIssueCommentAccessSpecifier {
EXTERNAL = "EXTERNAL",
INTERNAL = "INTERNAL",
}
export type EIssueServiceType = typeof EIssueServiceType[keyof typeof EIssueServiceType];
export const EIssuesStoreType = {
GLOBAL: "GLOBAL",
PROFILE: "PROFILE",
TEAM: "TEAM",
PROJECT: "PROJECT",
CYCLE: "CYCLE",
MODULE: "MODULE",
TEAM_VIEW: "TEAM_VIEW",
PROJECT_VIEW: "PROJECT_VIEW",
ARCHIVED: "ARCHIVED",
DRAFT: "DRAFT",
DEFAULT: "DEFAULT",
WORKSPACE_DRAFT: "WORKSPACE_DRAFT",
EPIC: "EPIC",
} as const;
export type EIssuesStoreType = typeof EIssuesStoreType[keyof typeof EIssuesStoreType];
export const EIssueCommentAccessSpecifier = {
EXTERNAL: "EXTERNAL",
INTERNAL: "INTERNAL",
} as const;
export type EIssueCommentAccessSpecifier = typeof EIssueCommentAccessSpecifier[keyof typeof EIssueCommentAccessSpecifier];
export const EIssueListRow = {
HEADER: "HEADER",
ISSUE: "ISSUE",
NO_ISSUES: "NO_ISSUES",
QUICK_ADD: "QUICK_ADD",
} as const;
export type EIssueListRow = typeof EIssueListRow[keyof typeof EIssueListRow];
export enum EIssueListRow {
HEADER = "HEADER",
ISSUE = "ISSUE",
NO_ISSUES = "NO_ISSUES",
QUICK_ADD = "QUICK_ADD",
}
export const ISSUE_PRIORITIES: {
key: TIssuePriorities;
@@ -126,14 +114,14 @@ export const DRAG_ALLOWED_GROUPS: TIssueGroupByOptions[] = [
];
export type TCreateModalStoreTypes =
| typeof EIssuesStoreType.TEAM
| typeof EIssuesStoreType.PROJECT
| typeof EIssuesStoreType.TEAM_VIEW
| typeof EIssuesStoreType.PROJECT_VIEW
| typeof EIssuesStoreType.PROFILE
| typeof EIssuesStoreType.CYCLE
| typeof EIssuesStoreType.MODULE
| typeof EIssuesStoreType.EPIC;
| EIssuesStoreType.TEAM
| EIssuesStoreType.PROJECT
| EIssuesStoreType.TEAM_VIEW
| EIssuesStoreType.PROJECT_VIEW
| EIssuesStoreType.PROFILE
| EIssuesStoreType.CYCLE
| EIssuesStoreType.MODULE
| EIssuesStoreType.EPIC;
export const ISSUE_GROUP_BY_OPTIONS: {
key: TIssueGroupByOptions;
+61 -29
View File
@@ -10,29 +10,25 @@ import { TIssueLayout } from "./layout";
export type TIssueFilterKeys = "priority" | "state" | "labels";
export const EServerGroupByToFilterOptions = {
"state_id": "state",
"priority": "priority",
"labels__id": "labels",
"state__group": "state_group",
"assignees__id": "assignees",
"cycle_id": "cycle",
"issue_module__module_id": "module",
"target_date": "target_date",
"project_id": "project",
"created_by": "created_by",
} as const;
export enum EServerGroupByToFilterOptions {
"state_id" = "state",
"priority" = "priority",
"labels__id" = "labels",
"state__group" = "state_group",
"assignees__id" = "assignees",
"cycle_id" = "cycle",
"issue_module__module_id" = "module",
"target_date" = "target_date",
"project_id" = "project",
"created_by" = "created_by",
}
export type EServerGroupByToFilterOptions = typeof EServerGroupByToFilterOptions[keyof typeof EServerGroupByToFilterOptions];
export const EIssueFilterType = {
FILTERS: "filters",
DISPLAY_FILTERS: "display_filters",
DISPLAY_PROPERTIES: "display_properties",
KANBAN_FILTERS: "kanban_filters",
} as const;
export type EIssueFilterType = typeof EIssueFilterType[keyof typeof EIssueFilterType];
export enum EIssueFilterType {
FILTERS = "filters",
DISPLAY_FILTERS = "display_filters",
DISPLAY_PROPERTIES = "display_properties",
KANBAN_FILTERS = "kanban_filters",
}
export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
[key in TIssueLayout]: Record<"filters", TIssueFilterKeys[]>;
@@ -140,7 +136,45 @@ export const ISSUE_DISPLAY_FILTERS_BY_PAGE: TIssueFiltersToDisplayByPageType = {
],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: {
group_by: ["state", "cycle", "module", "priority", "labels", "assignees", "created_by", null],
group_by: [
"state",
"cycle",
"module",
"state_detail.group",
"priority",
"labels",
"assignees",
"created_by",
null,
],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"],
},
extra_options: {
access: true,
values: ["show_empty_groups"],
},
},
},
draft_issues: {
list: {
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: {
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels", null],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"],
},
extra_options: {
access: true,
values: ["show_empty_groups"],
},
},
kanban: {
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
display_properties: ISSUE_DISPLAY_PROPERTIES_KEYS,
display_filters: {
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels"],
order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "-priority"],
type: [null, "active", "backlog"],
},
@@ -338,12 +372,10 @@ export const ISSUE_STORE_TO_FILTERS_MAP: Partial<Record<EIssuesStoreType, TFilte
[EIssuesStoreType.PROJECT]: ISSUE_DISPLAY_FILTERS_BY_PAGE.issues,
};
export const EActivityFilterType = {
ACTIVITY: "ACTIVITY",
COMMENT: "COMMENT",
} as const;
export type EActivityFilterType = typeof EActivityFilterType[keyof typeof EActivityFilterType];
export enum EActivityFilterType {
ACTIVITY = "ACTIVITY",
COMMENT = "COMMENT",
}
export type TActivityFilters = EActivityFilterType;
+7 -9
View File
@@ -5,15 +5,13 @@ export type TIssueLayout =
| "spreadsheet"
| "gantt";
export const EIssueLayoutTypes = {
LIST: "list",
KANBAN: "kanban",
CALENDAR: "calendar",
GANTT: "gantt_chart",
SPREADSHEET: "spreadsheet",
} as const;
export type EIssueLayoutTypes = typeof EIssueLayoutTypes[keyof typeof EIssueLayoutTypes];
export enum EIssueLayoutTypes {
LIST = "list",
KANBAN = "kanban",
CALENDAR = "calendar",
GANTT = "gantt_chart",
SPREADSHEET = "spreadsheet",
}
export type TIssueLayoutMap = Record<
EIssueLayoutTypes,
+11 -18
View File
@@ -1,16 +1,9 @@
// types
import { TModuleLayoutOptions, TModuleOrderByOptions, TModuleStatus } from "@plane/types";
export const MODULE_STATUS_COLORS: {
[key in TModuleStatus]: string;
} = {
backlog: "#a3a3a2",
planned: "#3f76ff",
paused: "#525252",
completed: "#16a34a",
cancelled: "#ef4444",
"in-progress": "#f39e1f",
};
import {
TModuleLayoutOptions,
TModuleOrderByOptions,
TModuleStatus,
} from "@plane/types";
export const MODULE_STATUS: {
i18n_label: string;
@@ -22,42 +15,42 @@ export const MODULE_STATUS: {
{
i18n_label: "project_modules.status.backlog",
value: "backlog",
color: MODULE_STATUS_COLORS.backlog,
color: "#a3a3a2",
textColor: "text-custom-text-400",
bgColor: "bg-custom-background-80",
},
{
i18n_label: "project_modules.status.planned",
value: "planned",
color: MODULE_STATUS_COLORS.planned,
color: "#3f76ff",
textColor: "text-blue-500",
bgColor: "bg-indigo-50",
},
{
i18n_label: "project_modules.status.in_progress",
value: "in-progress",
color: MODULE_STATUS_COLORS["in-progress"],
color: "#f39e1f",
textColor: "text-amber-500",
bgColor: "bg-amber-50",
},
{
i18n_label: "project_modules.status.paused",
value: "paused",
color: MODULE_STATUS_COLORS.paused,
color: "#525252",
textColor: "text-custom-text-300",
bgColor: "bg-custom-background-90",
},
{
i18n_label: "project_modules.status.completed",
value: "completed",
color: MODULE_STATUS_COLORS.completed,
color: "#16a34a",
textColor: "text-green-600",
bgColor: "bg-green-100",
},
{
i18n_label: "project_modules.status.cancelled",
value: "cancelled",
color: MODULE_STATUS_COLORS.cancelled,
color: "#ef4444",
textColor: "text-red-500",
bgColor: "bg-red-50",
},
+22 -30
View File
@@ -1,39 +1,31 @@
import { TUnreadNotificationsCount } from "@plane/types";
export const ENotificationTab = {
ALL: "all",
MENTIONS: "mentions",
} as const;
export enum ENotificationTab {
ALL = "all",
MENTIONS = "mentions",
}
export type ENotificationTab = typeof ENotificationTab[keyof typeof ENotificationTab];
export enum ENotificationFilterType {
CREATED = "created",
ASSIGNED = "assigned",
SUBSCRIBED = "subscribed",
}
export const ENotificationFilterType = {
CREATED: "created",
ASSIGNED: "assigned",
SUBSCRIBED: "subscribed",
} as const;
export enum ENotificationLoader {
INIT_LOADER = "init-loader",
MUTATION_LOADER = "mutation-loader",
PAGINATION_LOADER = "pagination-loader",
REFRESH = "refresh",
MARK_ALL_AS_READY = "mark-all-as-read",
}
export type ENotificationFilterType = typeof ENotificationFilterType[keyof typeof ENotificationFilterType];
export enum ENotificationQueryParamType {
INIT = "init",
CURRENT = "current",
NEXT = "next",
}
export const ENotificationLoader = {
INIT_LOADER: "init-loader",
MUTATION_LOADER: "mutation-loader",
PAGINATION_LOADER: "pagination-loader",
REFRESH: "refresh",
MARK_ALL_AS_READY: "mark-all-as-read",
} as const;
export type ENotificationLoader = typeof ENotificationLoader[keyof typeof ENotificationLoader];
export const ENotificationQueryParamType = {
INIT: "init",
CURRENT: "current",
NEXT: "next",
} as const;
export type ENotificationQueryParamType = typeof ENotificationQueryParamType[keyof typeof ENotificationQueryParamType];
export type TNotificationTab = typeof ENotificationTab.ALL | typeof ENotificationTab.MENTIONS;
export type TNotificationTab = ENotificationTab.ALL | ENotificationTab.MENTIONS;
export const NOTIFICATION_TABS = [
{
+4 -6
View File
@@ -1,9 +1,7 @@
export const EPageAccess = {
PUBLIC: 0,
PRIVATE: 1,
} as const;
export type EPageAccess = typeof EPageAccess[keyof typeof EPageAccess];
export enum EPageAccess {
PUBLIC = 0,
PRIVATE = 1,
}
export type TCreatePageModal = {
isOpen: boolean;
+8 -10
View File
@@ -3,15 +3,13 @@ import { IPaymentProduct, TBillingFrequency, TProductBillingFrequency } from "@p
/**
* Enum representing different product subscription types
*/
export const EProductSubscriptionEnum = {
FREE: "FREE",
ONE: "ONE",
PRO: "PRO",
BUSINESS: "BUSINESS",
ENTERPRISE: "ENTERPRISE",
} as const;
export type EProductSubscriptionEnum = typeof EProductSubscriptionEnum[keyof typeof EProductSubscriptionEnum];
export enum EProductSubscriptionEnum {
FREE = "FREE",
ONE = "ONE",
PRO = "PRO",
BUSINESS = "BUSINESS",
ENTERPRISE = "ENTERPRISE",
}
/**
* Default billing frequency for each product subscription type
@@ -31,7 +29,7 @@ export const SUBSCRIPTION_WITH_BILLING_FREQUENCY = [
EProductSubscriptionEnum.PRO,
EProductSubscriptionEnum.BUSINESS,
EProductSubscriptionEnum.ENTERPRISE,
] as EProductSubscriptionEnum[];
];
/**
* Mapping of product subscription types to their respective payment product details
+9 -11
View File
@@ -107,17 +107,15 @@ export const PREFERENCE_OPTIONS: {
* @description The start of the week for the user
* @enum {number}
*/
export const EStartOfTheWeek = {
SUNDAY: 0,
MONDAY: 1,
TUESDAY: 2,
WEDNESDAY: 3,
THURSDAY: 4,
FRIDAY: 5,
SATURDAY: 6,
} as const;
export type EStartOfTheWeek = typeof EStartOfTheWeek[keyof typeof EStartOfTheWeek];
export enum EStartOfTheWeek {
SUNDAY = 0,
MONDAY = 1,
TUESDAY = 2,
WEDNESDAY = 3,
THURSDAY = 4,
FRIDAY = 5,
SATURDAY = 6,
}
/**
* @description The options for the start of the week
+12 -18
View File
@@ -1,26 +1,20 @@
import { PROFILE_SETTINGS } from ".";
import { WORKSPACE_SETTINGS } from "./workspace";
export const WORKSPACE_SETTINGS_CATEGORY = {
ADMINISTRATION: "administration",
FEATURES: "features",
DEVELOPER: "developer",
} as const;
export enum WORKSPACE_SETTINGS_CATEGORY {
ADMINISTRATION = "administration",
FEATURES = "features",
DEVELOPER = "developer",
}
export type WORKSPACE_SETTINGS_CATEGORY = typeof WORKSPACE_SETTINGS_CATEGORY[keyof typeof WORKSPACE_SETTINGS_CATEGORY];
export enum PROFILE_SETTINGS_CATEGORY {
YOUR_PROFILE = "your profile",
DEVELOPER = "developer",
}
export const PROFILE_SETTINGS_CATEGORY = {
YOUR_PROFILE: "your profile",
DEVELOPER: "developer",
} as const;
export type PROFILE_SETTINGS_CATEGORY = typeof PROFILE_SETTINGS_CATEGORY[keyof typeof PROFILE_SETTINGS_CATEGORY];
export const PROJECT_SETTINGS_CATEGORY = {
PROJECTS: "projects",
} as const;
export type PROJECT_SETTINGS_CATEGORY = typeof PROJECT_SETTINGS_CATEGORY[keyof typeof PROJECT_SETTINGS_CATEGORY];
export enum PROJECT_SETTINGS_CATEGORY {
PROJECTS = "projects",
}
export const WORKSPACE_SETTINGS_CATEGORIES = [
WORKSPACE_SETTINGS_CATEGORY.ADMINISTRATION,
+10 -12
View File
@@ -89,18 +89,16 @@ export const PROJECT_PAGE_TAB_INDICES = [
"submit",
];
export const ETabIndices = {
ISSUE_FORM: "issue-form",
INTAKE_ISSUE_FORM: "intake-issue-form",
CREATE_LABEL: "create-label",
PROJECT_CREATE: "project-create",
PROJECT_CYCLE: "project-cycle",
PROJECT_MODULE: "project-module",
PROJECT_VIEW: "project-view",
PROJECT_PAGE: "project-page",
} as const;
export type ETabIndices = typeof ETabIndices[keyof typeof ETabIndices];
export enum ETabIndices {
ISSUE_FORM = "issue-form",
INTAKE_ISSUE_FORM = "intake-issue-form",
CREATE_LABEL = "create-label",
PROJECT_CREATE = "project-create",
PROJECT_CYCLE = "project-cycle",
PROJECT_MODULE = "project-module",
PROJECT_VIEW = "project-view",
PROJECT_PAGE = "project-page",
}
export const TAB_INDEX_MAP: Record<ETabIndices, string[]> = {
[ETabIndices.ISSUE_FORM]: ISSUE_FORM_TAB_INDICES,
+33 -47
View File
@@ -1,63 +1,49 @@
export const EAuthenticationPageType = {
STATIC: "STATIC",
NOT_AUTHENTICATED: "NOT_AUTHENTICATED",
AUTHENTICATED: "AUTHENTICATED",
} as const;
export enum EAuthenticationPageType {
STATIC = "STATIC",
NOT_AUTHENTICATED = "NOT_AUTHENTICATED",
AUTHENTICATED = "AUTHENTICATED",
}
export type EAuthenticationPageType = typeof EAuthenticationPageType[keyof typeof EAuthenticationPageType];
export enum EInstancePageType {
PRE_SETUP = "PRE_SETUP",
POST_SETUP = "POST_SETUP",
}
export const EInstancePageType = {
PRE_SETUP: "PRE_SETUP",
POST_SETUP: "POST_SETUP",
} as const;
export type EInstancePageType = typeof EInstancePageType[keyof typeof EInstancePageType];
export const EUserStatus = {
ERROR: "ERROR",
AUTHENTICATION_NOT_DONE: "AUTHENTICATION_NOT_DONE",
NOT_YET_READY: "NOT_YET_READY",
} as const;
export type EUserStatus = typeof EUserStatus[keyof typeof EUserStatus];
export enum EUserStatus {
ERROR = "ERROR",
AUTHENTICATION_NOT_DONE = "AUTHENTICATION_NOT_DONE",
NOT_YET_READY = "NOT_YET_READY",
}
export type TUserStatus = {
status: EUserStatus | undefined;
message?: string;
};
export const EUserPermissionsLevel = {
WORKSPACE: "WORKSPACE",
PROJECT: "PROJECT",
} as const;
export enum EUserPermissionsLevel {
WORKSPACE = "WORKSPACE",
PROJECT = "PROJECT",
}
export type EUserPermissionsLevel = typeof EUserPermissionsLevel[keyof typeof EUserPermissionsLevel];
export enum EUserWorkspaceRoles {
ADMIN = 20,
MEMBER = 15,
GUEST = 5,
}
export const EUserWorkspaceRoles = {
ADMIN: 20,
MEMBER: 15,
GUEST: 5,
} as const;
export type EUserWorkspaceRoles = typeof EUserWorkspaceRoles[keyof typeof EUserWorkspaceRoles];
export const EUserProjectRoles = {
ADMIN: 20,
MEMBER: 15,
GUEST: 5,
} as const;
export type EUserProjectRoles = typeof EUserProjectRoles[keyof typeof EUserProjectRoles];
export enum EUserProjectRoles {
ADMIN = 20,
MEMBER = 15,
GUEST = 5,
}
export type TUserPermissionsLevel = EUserPermissionsLevel;
export const EUserPermissions = {
ADMIN: 20,
MEMBER: 15,
GUEST: 5,
} as const;
export type EUserPermissions = typeof EUserPermissions[keyof typeof EUserPermissions];
export enum EUserPermissions {
ADMIN = 20,
MEMBER = 15,
GUEST = 5,
}
export type TUserPermissions = EUserPermissions;
export type TUserAllowedPermissionsObject = {
+4 -6
View File
@@ -1,9 +1,7 @@
export const EViewAccess = {
PRIVATE: 0,
PUBLIC: 1,
} as const;
export type EViewAccess = typeof EViewAccess[keyof typeof EViewAccess];
export enum EViewAccess {
PRIVATE,
PUBLIC,
}
export const VIEW_ACCESS_SPECIFIERS: {
key: EViewAccess;
+6 -8
View File
@@ -1,8 +1,6 @@
export const EDraftIssuePaginationType = {
INIT: "INIT",
NEXT: "NEXT",
PREV: "PREV",
CURRENT: "CURRENT",
} as const;
export type EDraftIssuePaginationType = typeof EDraftIssuePaginationType[keyof typeof EDraftIssuePaginationType];
export enum EDraftIssuePaginationType {
INIT = "INIT",
NEXT = "NEXT",
PREV = "PREV",
CURRENT = "CURRENT",
}
+1 -1
View File
@@ -118,7 +118,7 @@ export const WORKSPACE_SETTINGS = {
export const WORKSPACE_SETTINGS_ACCESS = Object.fromEntries(
Object.entries(WORKSPACE_SETTINGS).map(([_, { href, access }]) => [href, access])
) as Record<string, EUserWorkspaceRoles[]>;
);
export const WORKSPACE_SETTINGS_LINKS: {
key: string;
+1 -1
View File
@@ -28,7 +28,7 @@
"@types/reflect-metadata": "^0.1.0",
"@types/ws": "^8.5.10",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "^5.3.3"
},
"peerDependencies": {
"express": ">=4.21.2",
+1 -1
View File
@@ -82,7 +82,7 @@
"@types/react-dom": "^18.2.18",
"postcss": "^8.4.38",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "5.3.3"
},
"keywords": [
"editor",
+44 -46
View File
@@ -1,46 +1,44 @@
export const CORE_EXTENSIONS = {
BLOCKQUOTE: "blockquote",
BOLD: "bold",
BULLET_LIST: "bulletList",
CALLOUT: "calloutComponent",
CHARACTER_COUNT: "characterCount",
CODE_BLOCK: "codeBlock",
CODE_INLINE: "code",
CUSTOM_COLOR: "customColor",
CUSTOM_IMAGE: "imageComponent",
CUSTOM_LINK: "link",
DOCUMENT: "doc",
DROP_CURSOR: "dropCursor",
ENTER_KEY: "enterKey",
GAP_CURSOR: "gapCursor",
HARD_BREAK: "hardBreak",
HEADING: "heading",
HEADINGS_LIST: "headingsList",
HISTORY: "history",
HORIZONTAL_RULE: "horizontalRule",
IMAGE: "image",
ITALIC: "italic",
LIST_ITEM: "listItem",
MARKDOWN_CLIPBOARD: "markdownClipboard",
MENTION: "mention",
ORDERED_LIST: "orderedList",
PARAGRAPH: "paragraph",
PLACEHOLDER: "placeholder",
SIDE_MENU: "editorSideMenu",
SLASH_COMMANDS: "slash-command",
STRIKETHROUGH: "strike",
TABLE: "table",
TABLE_CELL: "tableCell",
TABLE_HEADER: "tableHeader",
TABLE_ROW: "tableRow",
TASK_ITEM: "taskItem",
TASK_LIST: "taskList",
TEXT_ALIGN: "textAlign",
TEXT_STYLE: "textStyle",
TYPOGRAPHY: "typography",
UNDERLINE: "underline",
UTILITY: "utility",
WORK_ITEM_EMBED: "issue-embed-component",
} as const;
export type CORE_EXTENSIONS = typeof CORE_EXTENSIONS[keyof typeof CORE_EXTENSIONS];
export enum CORE_EXTENSIONS {
BLOCKQUOTE = "blockquote",
BOLD = "bold",
BULLET_LIST = "bulletList",
CALLOUT = "calloutComponent",
CHARACTER_COUNT = "characterCount",
CODE_BLOCK = "codeBlock",
CODE_INLINE = "code",
CUSTOM_COLOR = "customColor",
CUSTOM_IMAGE = "imageComponent",
CUSTOM_LINK = "link",
DOCUMENT = "doc",
DROP_CURSOR = "dropCursor",
ENTER_KEY = "enterKey",
GAP_CURSOR = "gapCursor",
HARD_BREAK = "hardBreak",
HEADING = "heading",
HEADINGS_LIST = "headingsList",
HISTORY = "history",
HORIZONTAL_RULE = "horizontalRule",
IMAGE = "image",
ITALIC = "italic",
LIST_ITEM = "listItem",
MARKDOWN_CLIPBOARD = "markdownClipboard",
MENTION = "mention",
ORDERED_LIST = "orderedList",
PARAGRAPH = "paragraph",
PLACEHOLDER = "placeholder",
SIDE_MENU = "editorSideMenu",
SLASH_COMMANDS = "slash-command",
STRIKETHROUGH = "strike",
TABLE = "table",
TABLE_CELL = "tableCell",
TABLE_HEADER = "tableHeader",
TABLE_ROW = "tableRow",
TASK_ITEM = "taskItem",
TASK_LIST = "taskList",
TEXT_ALIGN = "textAlign",
TEXT_STYLE = "textStyle",
TYPOGRAPHY = "typography",
UNDERLINE = "underline",
UTILITY = "utility",
WORK_ITEM_EMBED = "issue-embed-component",
}
+3 -5
View File
@@ -1,5 +1,3 @@
export const CORE_EDITOR_META = {
SKIP_FILE_DELETION: "skipFileDeletion",
} as const;
export type CORE_EDITOR_META = typeof CORE_EDITOR_META[keyof typeof CORE_EDITOR_META];
export enum CORE_EDITOR_META {
SKIP_FILE_DELETION = "skipFileDeletion",
}
@@ -1,14 +1,12 @@
export const EAttributeNames = {
ICON_COLOR: "data-icon-color",
ICON_NAME: "data-icon-name",
EMOJI_UNICODE: "data-emoji-unicode",
EMOJI_URL: "data-emoji-url",
LOGO_IN_USE: "data-logo-in-use",
BACKGROUND: "data-background",
BLOCK_TYPE: "data-block-type",
} as const;
export type EAttributeNames = typeof EAttributeNames[keyof typeof EAttributeNames];
export enum EAttributeNames {
ICON_COLOR = "data-icon-color",
ICON_NAME = "data-icon-name",
EMOJI_UNICODE = "data-emoji-unicode",
EMOJI_URL = "data-emoji-url",
LOGO_IN_USE = "data-logo-in-use",
BACKGROUND = "data-background",
BLOCK_TYPE = "data-block-type",
}
export type TCalloutBlockIconAttributes = {
[EAttributeNames.ICON_COLOR]: string | undefined;
@@ -1,13 +1,11 @@
// plane types
import { TSearchEntities } from "@plane/types";
export const EMentionComponentAttributeNames = {
ID: "id",
ENTITY_IDENTIFIER: "entity_identifier",
ENTITY_NAME: "entity_name",
} as const;
export type EMentionComponentAttributeNames = typeof EMentionComponentAttributeNames[keyof typeof EMentionComponentAttributeNames];
export enum EMentionComponentAttributeNames {
ID = "id",
ENTITY_IDENTIFIER = "entity_identifier",
ENTITY_NAME = "entity_name",
}
export type TMentionComponentAttributes = {
[EMentionComponentAttributeNames.ID]: string | null;
+5 -7
View File
@@ -1,10 +1,8 @@
export const EFileError = {
INVALID_FILE_TYPE: "INVALID_FILE_TYPE",
FILE_SIZE_TOO_LARGE: "FILE_SIZE_TOO_LARGE",
NO_FILE_SELECTED: "NO_FILE_SELECTED",
} as const;
export type EFileError = typeof EFileError[keyof typeof EFileError];
export enum EFileError {
INVALID_FILE_TYPE = "INVALID_FILE_TYPE",
FILE_SIZE_TOO_LARGE = "FILE_SIZE_TOO_LARGE",
NO_FILE_SELECTED = "NO_FILE_SELECTED",
}
type TArgs = {
acceptedMimeTypes: string[];
+1 -1
View File
@@ -18,6 +18,6 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^5.2.0",
"typescript": "5.8.3"
"typescript": "5.3.3"
}
}
+1 -1
View File
@@ -23,6 +23,6 @@
"@types/node": "^22.5.4",
"@types/react": "^18.3.11",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
+1 -1
View File
@@ -17,6 +17,6 @@
"devDependencies": {
"@plane/eslint-config": "*",
"@types/node": "^22.5.4",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
+5 -7
View File
@@ -28,12 +28,10 @@ export const SUPPORTED_LANGUAGES: ILanguageOption[] = [
* Enum for translation file names
* These are the JSON files that contain translations each category
*/
export const ETranslationFiles = {
TRANSLATIONS: "translations",
ACCESSIBILITY: "accessibility",
EDITOR: "editor",
} as const;
export type ETranslationFiles = typeof ETranslationFiles[keyof typeof ETranslationFiles];
export enum ETranslationFiles {
TRANSLATIONS = "translations",
ACCESSIBILITY = "accessibility",
EDITOR = "editor",
}
export const LANGUAGE_STORAGE_KEY = "userLanguage";
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Nepodařilo se odstranit projekt z oblíbených. Zkuste to prosím znovu.",
"project_created_successfully": "Projekt úspěšně vytvořen",
"project_created_successfully_description": "Projekt byl úspěšně vytvořen. Nyní můžete začít přidávat pracovní položky.",
"project_name_already_taken": "Název projektu už je zabraný.",
"project_identifier_already_taken": "Identifikátor projektu už je zabraný.",
"project_cover_image_alt": "Úvodní obrázek projektu",
"name_is_required": "Název je povinný",
"title_should_be_less_than_255_characters": "Název by měl být kratší než 255 znaků",
@@ -872,15 +874,13 @@
"guests": "Hosté",
"on_track": "Na správné cestě",
"off_track": "Mimo plán",
"at_risk": "V ohrožení",
"timeline": "Časová osa",
"completion": "Dokončení",
"upcoming": "Nadcházející",
"completed": "Dokončeno",
"in_progress": "Probíhá",
"planned": "Plánováno",
"paused": "Pozastaveno",
"no_of": "Počet {entity}"
"paused": "Pozastaveno"
},
"chart": {
"x_axis": "Osa X",
@@ -2469,4 +2469,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane se nespustil. To může být způsobeno tím, že se jeden nebo více služeb Plane nepodařilo spustit.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Vyberte View Logs z setup.sh a Docker logů, abyste si byli jisti."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Projekt konnte nicht aus den Favoriten entfernt werden. Bitte versuchen Sie es erneut.",
"project_created_successfully": "Projekt erfolgreich erstellt",
"project_created_successfully_description": "Das Projekt wurde erfolgreich erstellt. Sie können nun Arbeitselemente hinzufügen.",
"project_name_already_taken": "Der Projektname ist bereits vergeben.",
"project_identifier_already_taken": "Der Projekt-Identifier ist bereits vergeben.",
"project_cover_image_alt": "Titelbild des Projekts",
"name_is_required": "Name ist erforderlich",
"title_should_be_less_than_255_characters": "Der Titel sollte weniger als 255 Zeichen enthalten",
@@ -872,15 +874,13 @@
"guests": "Gäste",
"on_track": "Im Plan",
"off_track": "Außer Plan",
"at_risk": "Gefährdet",
"timeline": "Zeitleiste",
"completion": "Fertigstellung",
"upcoming": "Bevorstehend",
"completed": "Abgeschlossen",
"in_progress": "In Bearbeitung",
"planned": "Geplant",
"paused": "Pausiert",
"no_of": "Anzahl {entity}"
"paused": "Pausiert"
},
"chart": {
"x_axis": "X-Achse",
@@ -2468,4 +2468,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane ist nicht gestartet. Dies könnte daran liegen, dass einer oder mehrere Plane-Services nicht starten konnten.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Wählen Sie View Logs aus setup.sh und Docker-Logs, um sicherzugehen."
}
}
}
@@ -153,6 +153,8 @@
"failed_to_remove_project_from_favorites": "Couldn't remove the project from favorites. Please try again.",
"project_created_successfully": "Project created successfully",
"project_created_successfully_description": "Project created successfully. You can now start adding work items to it.",
"project_name_already_taken": "The project name is already taken.",
"project_identifier_already_taken": "The project identifier is already taken.",
"project_cover_image_alt": "Project cover image",
"name_is_required": "Name is required",
"title_should_be_less_than_255_characters": "Title should be less than 255 characters",
@@ -617,7 +619,6 @@
"click_to_add_description": "Click to add description",
"on_track": "On-Track",
"off_track": "Off-Track",
"at_risk": "At risk",
"timeline": "Timeline",
"completion": "Completion",
"upcoming": "Upcoming",
@@ -722,8 +723,7 @@
"deactivated_user": "Deactivated user",
"apply": "Apply",
"applying": "Applying",
"overview": "Overview",
"no_of": "No. of {entity}"
"overview": "Overview"
},
"chart": {
"x_axis": "X-axis",
@@ -2345,4 +2345,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane didn't start up. This could be because one or more Plane services failed to start.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Choose View Logs from setup.sh and Docker logs to be sure."
}
}
}
@@ -318,6 +318,8 @@
"failed_to_remove_project_from_favorites": "No se pudo eliminar el proyecto de favoritos. Por favor, inténtalo de nuevo.",
"project_created_successfully": "Proyecto creado exitosamente",
"project_created_successfully_description": "Proyecto creado exitosamente. Ahora puedes comenzar a agregar elementos de trabajo.",
"project_name_already_taken": "El nombre del proyecto ya está en uso.",
"project_identifier_already_taken": "El identificador del proyecto ya está en uso.",
"project_cover_image_alt": "Imagen de portada del proyecto",
"name_is_required": "El nombre es requerido",
"title_should_be_less_than_255_characters": "El título debe tener menos de 255 caracteres",
@@ -875,15 +877,13 @@
"guests": "Invitados",
"on_track": "En camino",
"off_track": "Fuera de camino",
"at_risk": "En riesgo",
"timeline": "Cronograma",
"completion": "Finalización",
"upcoming": "Próximo",
"completed": "Completado",
"in_progress": "En progreso",
"planned": "Planificado",
"paused": "Pausado",
"no_of": "N.º de {entity}"
"paused": "Pausado"
},
"chart": {
"x_axis": "Eje X",
@@ -2471,4 +2471,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane no se inició. Esto podría deberse a que uno o más servicios de Plane fallaron al iniciar.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Selecciona View Logs desde setup.sh y los logs de Docker para estar seguro."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Impossible de supprimer le projet des favoris. Veuillez réessayer.",
"project_created_successfully": "Projet créé avec succès",
"project_created_successfully_description": "Projet créé avec succès. Vous pouvez maintenant commencer à ajouter des éléments de travail.",
"project_name_already_taken": "Le nom du projet est déjà pris.",
"project_identifier_already_taken": "Lidentifiant du projet est déjà pris.",
"project_cover_image_alt": "Image de couverture du projet",
"name_is_required": "Le nom est requis",
"title_should_be_less_than_255_characters": "Le titre doit faire moins de 255 caractères",
@@ -873,15 +875,13 @@
"guests": "Invités",
"on_track": "Sur la bonne voie",
"off_track": "Hors de la bonne voie",
"at_risk": "À risque",
"timeline": "Chronologie",
"completion": "Achèvement",
"upcoming": "À venir",
"completed": "Terminé",
"in_progress": "En cours",
"planned": "Planifié",
"paused": "En pause",
"no_of": "Nº de {entity}"
"paused": "En pause"
},
"chart": {
"x_axis": "Axe X",
@@ -2469,4 +2469,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane n&apos;a pas démarré. Cela pourrait être dû au fait qu&apos;un ou plusieurs services Plane ont échoué à démarrer.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Choisissez View Logs depuis setup.sh et les logs Docker pour en être sûr."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Tidak dapat menghapus proyek dari favorit. Silakan coba lagi.",
"project_created_successfully": "Proyek berhasil dibuat",
"project_created_successfully_description": "Proyek berhasil dibuat. Anda sekarang dapat mulai menambahkan item kerja ke dalamnya.",
"project_name_already_taken": "Nama project sudah digunakan.",
"project_identifier_already_taken": "Identifier project sudah digunakan.",
"project_cover_image_alt": "Gambar sampul proyek",
"name_is_required": "Nama diperlukan",
"title_should_be_less_than_255_characters": "Judul harus kurang dari 255 karakter",
@@ -872,15 +874,13 @@
"guests": "Tamu",
"on_track": "Sesuai Jalur",
"off_track": "Menyimpang",
"at_risk": "Dalam risiko",
"timeline": "Linimasa",
"completion": "Penyelesaian",
"upcoming": "Mendatang",
"completed": "Selesai",
"in_progress": "Sedang berlangsung",
"planned": "Direncanakan",
"paused": "Dijedaikan",
"no_of": "Jumlah {entity}"
"paused": "Dijedaikan"
},
"chart": {
"x_axis": "Sumbu-X",
@@ -2462,6 +2462,5 @@
"self_hosted_maintenance_message": {
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane tidak berhasil dimulai. Ini bisa karena satu atau lebih layanan Plane gagal untuk dimulai.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Pilih View Logs dari setup.sh dan log Docker untuk memastikan."
},
"no_of": "Jumlah {entity}"
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Impossibile rimuovere il progetto dai preferiti. Per favore, riprova.",
"project_created_successfully": "Progetto creato con successo",
"project_created_successfully_description": "Progetto creato con successo. Ora puoi iniziare ad aggiungere elementi di lavoro.",
"project_name_already_taken": "Il nome del progetto è già stato utilizzato.",
"project_identifier_already_taken": "L'identificatore del progetto è già stato utilizzato.",
"project_cover_image_alt": "Immagine di copertina del progetto",
"name_is_required": "Il nome è obbligatorio",
"title_should_be_less_than_255_characters": "Il titolo deve contenere meno di 255 caratteri",
@@ -871,15 +873,13 @@
"guests": "Ospiti",
"on_track": "In linea",
"off_track": "Fuori rotta",
"at_risk": "A rischio",
"timeline": "Cronologia",
"completion": "Completamento",
"upcoming": "In arrivo",
"completed": "Completato",
"in_progress": "In corso",
"planned": "Pianificato",
"paused": "In pausa",
"no_of": "N. di {entity}"
"paused": "In pausa"
},
"chart": {
"x_axis": "Asse X",
@@ -2468,4 +2468,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane non si è avviato. Questo potrebbe essere dovuto al fatto che uno o più servizi Plane non sono riusciti ad avviarsi.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Scegli View Logs da setup.sh e dai log Docker per essere sicuro."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "プロジェクトをお気に入りから削除できませんでした。もう一度お試しください。",
"project_created_successfully": "プロジェクトが正常に作成されました",
"project_created_successfully_description": "プロジェクトが正常に作成されました。作業項目を追加できるようになりました。",
"project_name_already_taken": "プロジェクト名は既に使用されています。",
"project_identifier_already_taken": "プロジェクト識別子は既に使用されています。",
"project_cover_image_alt": "プロジェクトのカバー画像",
"name_is_required": "名前は必須です",
"title_should_be_less_than_255_characters": "タイトルは255文字未満である必要があります",
@@ -873,15 +875,13 @@
"guests": "ゲスト",
"on_track": "順調",
"off_track": "遅れ",
"at_risk": "リスクあり",
"timeline": "タイムライン",
"completion": "完了",
"upcoming": "今後の予定",
"completed": "完了",
"in_progress": "進行中",
"planned": "計画済み",
"paused": "一時停止",
"no_of": "{entity} の数"
"paused": "一時停止"
},
"chart": {
"x_axis": "エックス アクシス",
@@ -2469,4 +2469,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Planeが起動しませんでした。これは1つまたは複数のPlaneサービスの起動に失敗したことが原因である可能性があります。",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "setup.shとDockerログからView Logsを選択して確認してください。"
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "프로젝트를 즐겨찾기에서 제거하지 못했습니다. 다시 시도해주세요.",
"project_created_successfully": "프로젝트가 성공적으로 생성되었습니다",
"project_created_successfully_description": "프로젝트가 성공적으로 생성되었습니다. 이제 작업 항목을 추가할 수 있습니다.",
"project_name_already_taken": "프로젝트 이름이 이미 사용 중입니다.",
"project_identifier_already_taken": "프로젝트 식별자가 이미 사용 중입니다.",
"project_cover_image_alt": "프로젝트 커버 이미지",
"name_is_required": "이름이 필요합니다",
"title_should_be_less_than_255_characters": "제목은 255자 미만이어야 합니다",
@@ -874,15 +876,13 @@
"guests": "게스트",
"on_track": "계획대로 진행 중",
"off_track": "계획 이탈",
"at_risk": "위험",
"timeline": "타임라인",
"completion": "완료",
"upcoming": "예정된",
"completed": "완료됨",
"in_progress": "진행 중",
"planned": "계획된",
"paused": "일시 중지됨",
"no_of": "{entity} 수"
"paused": "일시 중지됨"
},
"chart": {
"x_axis": "X축",
@@ -2471,4 +2471,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane이 시작되지 않았습니다. 이는 하나 이상의 Plane 서비스가 시작에 실패했기 때문일 수 있습니다.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "확실히 하려면 setup.sh와 Docker 로그에서 View Logs를 선택하세요."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Nie udało się usunąć projektu z ulubionych. Spróbuj ponownie.",
"project_created_successfully": "Projekt utworzono pomyślnie",
"project_created_successfully_description": "Projekt został pomyślnie utworzony. Teraz możesz dodawać elementy pracy.",
"project_name_already_taken": "Nazwa projektu jest już zajęta.",
"project_identifier_already_taken": "Identyfikator projektu jest już zajęty.",
"project_cover_image_alt": "Obraz w tle projektu",
"name_is_required": "Nazwa jest wymagana",
"title_should_be_less_than_255_characters": "Nazwa musi mieć mniej niż 255 znaków",
@@ -874,15 +876,13 @@
"guests": "Goście",
"on_track": "Na dobrej drodze",
"off_track": "Poza planem",
"at_risk": "W zagrożeniu",
"timeline": "Oś czasu",
"completion": "Zakończenie",
"upcoming": "Nadchodzące",
"completed": "Zakończone",
"in_progress": "W trakcie",
"planned": "Zaplanowane",
"paused": "Wstrzymane",
"no_of": "Liczba {entity}"
"paused": "Wstrzymane"
},
"chart": {
"x_axis": "Oś X",
@@ -2470,4 +2470,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane nie uruchomił się. Może to być spowodowane tym, że jedna lub więcej usług Plane nie mogła się uruchomić.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Wybierz View Logs z setup.sh i logów Docker, aby mieć pewność."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Não foi possível remover o projeto dos favoritos. Por favor, tente novamente.",
"project_created_successfully": "Projeto criado com sucesso",
"project_created_successfully_description": "Projeto criado com sucesso. Agora você pode começar a adicionar itens de trabalho a ele.",
"project_name_already_taken": "O nome do projeto já está em uso.",
"project_identifier_already_taken": "O identificador do projeto já está em uso.",
"project_cover_image_alt": "Imagem de capa do projeto",
"name_is_required": "Nome é obrigatório",
"title_should_be_less_than_255_characters": "O título deve ter menos de 255 caracteres",
@@ -874,15 +876,13 @@
"guests": "Convidados",
"on_track": "No caminho certo",
"off_track": "Fora do caminho",
"at_risk": "Em risco",
"timeline": "Linha do tempo",
"completion": "Conclusão",
"upcoming": "Próximo",
"completed": "Concluído",
"in_progress": "Em andamento",
"planned": "Planejado",
"paused": "Pausado",
"no_of": "Nº de {entity}"
"paused": "Pausado"
},
"chart": {
"x_axis": "Eixo X",
@@ -2465,4 +2465,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "O Plane não inicializou. Isso pode ser porque um ou mais serviços do Plane falharam ao iniciar.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Escolha View Logs do setup.sh e logs do Docker para ter certeza."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Nu s-a putut elimina proiectul din favorite. Încearcă din nou.",
"project_created_successfully": "Proiect creat cu succes",
"project_created_successfully_description": "Proiect creat cu succes. Poți începe să adaugi activități în el.",
"project_name_already_taken": "Numele proiectului este deja folosit.",
"project_identifier_already_taken": "Identificatorul proiectului este deja folosit.",
"project_cover_image_alt": "Coperta proiectului",
"name_is_required": "Numele este obligatoriu",
"title_should_be_less_than_255_characters": "Titlul trebuie să conțină mai puțin de 255 de caractere",
@@ -872,15 +874,13 @@
"guests": "Invitați",
"on_track": "Pe drumul cel bun",
"off_track": "În afara traiectoriei",
"at_risk": "În pericol",
"timeline": "Cronologie",
"completion": "Finalizare",
"upcoming": "Viitor",
"completed": "Finalizat",
"in_progress": "În desfășurare",
"planned": "Planificat",
"paused": "Pauzat",
"no_of": "Nr. de {entity}"
"paused": "Pauzat"
},
"chart": {
"x_axis": "axa-X",
@@ -2463,4 +2463,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane nu a pornit. Aceasta ar putea fi din cauza că unul sau mai multe servicii Plane au eșuat să pornească.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Alegeți View Logs din setup.sh și logurile Docker pentru a fi siguri."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Не удалось удалить проект из избранного. Попробуйте снова.",
"project_created_successfully": "Проект успешно создан",
"project_created_successfully_description": "Проект успешно создан. Теперь вы можете добавлять рабочие элементы.",
"project_name_already_taken": "Имя проекта уже используется.",
"project_identifier_already_taken": "Идентификатор проекта уже используется.",
"project_cover_image_alt": "Обложка проекта",
"name_is_required": "Требуется имя",
"title_should_be_less_than_255_characters": "Заголовок должен быть короче 255 символов",
@@ -874,7 +876,6 @@
"guests": "Гости",
"on_track": "По плану",
"off_track": "Отклонение от плана",
"at_risk": "Под угрозой",
"timeline": "Хронология",
"completion": "Завершение",
"upcoming": "Предстоящие",
@@ -2469,6 +2470,5 @@
"self_hosted_maintenance_message": {
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane не запустился. Это может быть из-за того, что один или несколько сервисов Plane не смогли запуститься.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Выберите View Logs из setup.sh и логов Docker, чтобы убедиться."
},
"no_of": "Количество {entity}"
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Nepodarilo sa odstrániť projekt z obľúbených. Skúste to prosím znova.",
"project_created_successfully": "Projekt bol úspešne vytvorený",
"project_created_successfully_description": "Projekt bol úspešne vytvorený. Teraz môžete začať pridávať pracovné položky.",
"project_name_already_taken": "Názov projektu je už použitý.",
"project_identifier_already_taken": "Identifikátor projektu je už použitý.",
"project_cover_image_alt": "Úvodný obrázok projektu",
"name_is_required": "Názov je povinný",
"title_should_be_less_than_255_characters": "Názov by mal byť kratší ako 255 znakov",
@@ -874,15 +876,13 @@
"guests": "Hostia",
"on_track": "Na správnej ceste",
"off_track": "Mimo plán",
"at_risk": "V ohrození",
"timeline": "Časová os",
"completion": "Dokončenie",
"upcoming": "Nadchádzajúce",
"completed": "Dokončené",
"in_progress": "Prebieha",
"planned": "Plánované",
"paused": "Pozastavené",
"no_of": "Počet {entity}"
"paused": "Pozastavené"
},
"chart": {
"x_axis": "Os X",
@@ -2470,4 +2470,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane sa nespustil. Toto môže byť spôsobené tým, že sa jedna alebo viac služieb Plane nepodarilo spustiť.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Vyberte View Logs z setup.sh a Docker logov, aby ste si boli istí."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Proje favorilerden kaldırılamadı. Lütfen tekrar deneyin.",
"project_created_successfully": "Proje başarıyla oluşturuldu",
"project_created_successfully_description": "Proje başarıyla oluşturuldu. Artık iş öğeleri eklemeye başlayabilirsiniz.",
"project_name_already_taken": "Proje ismi zaten kullanılıyor.",
"project_identifier_already_taken": "Proje kimliği zaten kullanılıyor.",
"project_cover_image_alt": "Proje kapak resmi",
"name_is_required": "Ad gereklidir",
"title_should_be_less_than_255_characters": "Başlık 255 karakterden az olmalı",
@@ -875,15 +877,13 @@
"guests": "Misafirler",
"on_track": "Yolunda",
"off_track": "Yolunda değil",
"at_risk": "Risk altında",
"timeline": "Zaman çizelgesi",
"completion": "Tamamlama",
"upcoming": "Yaklaşan",
"completed": "Tamamlandı",
"in_progress": "Devam ediyor",
"planned": "Planlandı",
"paused": "Durduruldu",
"no_of": "{entity} sayısı"
"paused": "Durduruldu"
},
"chart": {
"x_axis": "X ekseni",
@@ -2449,4 +2449,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane başlatılamadı. Bu, bir veya daha fazla Plane servisinin başlatılamaması nedeniyle olabilir.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Emin olmak için setup.sh ve Docker loglarından View Logs&apos;u seçin."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Не вдалося видалити проєкт із вибраного. Спробуйте ще раз.",
"project_created_successfully": "Проєкт успішно створено",
"project_created_successfully_description": "Проєкт успішно створений. Тепер ви можете почати додавати робочі одиниці.",
"project_name_already_taken": "Назва проекту вже використовується.",
"project_identifier_already_taken": "Ідентифікатор проекту вже використовується.",
"project_cover_image_alt": "Обкладинка проєкту",
"name_is_required": "Назва є обов’язковою",
"title_should_be_less_than_255_characters": "Назва має бути коротшою за 255 символів",
@@ -874,15 +876,13 @@
"guests": "Гості",
"on_track": "У межах графіку",
"off_track": "Поза графіком",
"at_risk": "Під загрозою",
"timeline": "Хронологія",
"completion": "Завершення",
"upcoming": "Майбутнє",
"completed": "Завершено",
"in_progress": "В процесі",
"planned": "Заплановано",
"paused": "Призупинено",
"no_of": "Кількість {entity}"
"paused": "Призупинено"
},
"chart": {
"x_axis": "Вісь X",
@@ -2470,4 +2470,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane не запустився. Це може бути через те, що один або декілька сервісів Plane не змогли запуститися.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Виберіть View Logs з setup.sh та логів Docker, щоб переконатися."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "Không thể xóa dự án khỏi mục yêu thích. Vui lòng thử lại.",
"project_created_successfully": "Dự án đã được tạo thành công",
"project_created_successfully_description": "Dự án đã được tạo thành công. Bây giờ bạn có thể bắt đầu thêm mục công việc.",
"project_name_already_taken": "Tên project đã được sử dụng.",
"project_identifier_already_taken": "Identifier project đã được sử dụng.",
"project_cover_image_alt": "Ảnh bìa dự án",
"name_is_required": "Tên là bắt buộc",
"title_should_be_less_than_255_characters": "Tiêu đề phải ít hơn 255 ký tự",
@@ -873,15 +875,13 @@
"guests": "Khách",
"on_track": "Đúng tiến độ",
"off_track": "Chệch hướng",
"at_risk": "Có nguy cơ",
"timeline": "Dòng thời gian",
"completion": "Hoàn thành",
"upcoming": "Sắp tới",
"completed": "Đã hoàn thành",
"in_progress": "Đang tiến hành",
"planned": "Đã lên kế hoạch",
"paused": "Tạm dừng",
"no_of": "Số lượng {entity}"
"paused": "Tạm dừng"
},
"chart": {
"x_axis": "Trục X",
@@ -2468,4 +2468,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane không khởi động được. Điều này có thể do một hoặc nhiều dịch vụ Plane không khởi động được.",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "Chọn View Logs từ setup.sh và log Docker để chắc chắn."
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "无法从收藏中移除项目。请重试。",
"project_created_successfully": "项目创建成功",
"project_created_successfully_description": "项目创建成功。您现在可以开始添加工作项了。",
"project_name_already_taken": "项目名称已被使用。",
"project_identifier_already_taken": "项目标识符已被使用。",
"project_cover_image_alt": "项目封面图片",
"name_is_required": "名称为必填项",
"title_should_be_less_than_255_characters": "标题应少于255个字符",
@@ -873,15 +875,13 @@
"guests": "访客",
"on_track": "进展顺利",
"off_track": "偏离轨道",
"at_risk": "有风险",
"timeline": "时间轴",
"completion": "完成",
"upcoming": "即将发生",
"completed": "已完成",
"in_progress": "进行中",
"planned": "已计划",
"paused": "暂停",
"no_of": "{entity} 的数量"
"paused": "暂停"
},
"chart": {
"x_axis": "X轴",
@@ -2450,4 +2450,4 @@
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane 未能启动。这可能是因为一个或多个 Plane 服务启动失败。",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "请选择“查看日志”来查看 setup.sh 和 Docker 日志,以确认问题。"
}
}
}
@@ -316,6 +316,8 @@
"failed_to_remove_project_from_favorites": "無法從我的最愛移除專案。請再試一次。",
"project_created_successfully": "專案建立成功",
"project_created_successfully_description": "專案建立成功。您現在可以開始新增工作事項。",
"project_name_already_taken": "專案名稱已被使用。",
"project_identifier_already_taken": "專案識別碼已被使用。",
"project_cover_image_alt": "專案封面圖片",
"name_is_required": "名稱為必填",
"title_should_be_less_than_255_characters": "標題不應超過 255 個字元",
@@ -880,9 +882,7 @@
"completed": "已完成",
"in_progress": "進行中",
"planned": "已計劃",
"paused": "暫停",
"at_risk": "有風險",
"no_of": "{entity} 的數量"
"paused": "暫停"
},
"chart": {
"x_axis": "X 軸",
@@ -2467,8 +2467,9 @@
"previously_edited_by": "先前編輯者",
"edited_by": "編輯者"
},
"self_hosted_maintenance_message": {
"plane_didnt_start_up_this_could_be_because_one_or_more_plane_services_failed_to_start": "Plane 未能啟動。這可能是因為一個或多個 Plane 服務啟動失敗。",
"choose_view_logs_from_setup_sh_and_docker_logs_to_be_sure": "從 setup.sh 和 Docker 日誌中選擇 View Logs 來確認。"
}
}
}
+3
View File
@@ -3,4 +3,7 @@ module.exports = {
root: true,
extends: ["@plane/eslint-config/library.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
};
+4 -12
View File
@@ -4,18 +4,11 @@
"license": "AGPL-3.0",
"description": "Logger shared across multiple apps internally",
"private": true,
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist/**"
],
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"lint": "eslint src --ext .ts,.tsx",
"lint:errors": "eslint src --ext .ts,.tsx --quiet",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
"lint:errors": "eslint src --ext .ts,.tsx --quiet"
},
"dependencies": {
"winston": "^3.17.0",
@@ -24,7 +17,6 @@
"devDependencies": {
"@plane/eslint-config": "*",
"@types/node": "^22.5.4",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
-12
View File
@@ -1,12 +0,0 @@
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
splitting: false,
sourcemap: true,
clean: true,
external: ["winston", "winston-daily-rotate-file"],
treeshake: true,
});
+1 -1
View File
@@ -29,6 +29,6 @@
"@plane/typescript-config": "*",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
@@ -122,7 +122,7 @@ export const LineChart = React.memo(<K extends string, T extends string>(props:
angle: -90,
position: "bottom",
offset: -24,
dx: yAxis.dx ?? -16,
dx: -16,
className: AXIS_LABEL_CLASSNAME,
}
}
@@ -27,6 +27,7 @@ export const ScatterChart = React.memo(<K extends string, T extends string>(prop
margin,
xAxis,
yAxis,
className,
tickCount = {
x: undefined,
@@ -34,7 +35,6 @@ export const ScatterChart = React.memo(<K extends string, T extends string>(prop
},
legend,
showTooltip = true,
customTooltipContent,
} = props;
// states
const [activePoint, setActivePoint] = useState<string | null>(null);
@@ -107,7 +107,7 @@ export const ScatterChart = React.memo(<K extends string, T extends string>(prop
angle: -90,
position: "bottom",
offset: -24,
dx: yAxis.dx ?? -16,
dx: -16,
className: AXIS_LABEL_CLASSNAME,
}
}
@@ -133,21 +133,17 @@ export const ScatterChart = React.memo(<K extends string, T extends string>(prop
wrapperStyle={{
pointerEvents: "auto",
}}
content={({ active, label, payload }) =>
customTooltipContent ? (
customTooltipContent({ active, label, payload })
) : (
<CustomTooltip
active={active}
activeKey={activePoint}
label={label}
payload={payload}
itemKeys={itemKeys}
itemLabels={itemLabels}
itemDotColors={itemDotColors}
/>
)
}
content={({ active, label, payload }) => (
<CustomTooltip
active={active}
activeKey={activePoint}
label={label}
payload={payload}
itemKeys={itemKeys}
itemLabels={itemLabels}
itemDotColors={itemDotColors}
/>
)}
/>
)}
{renderPoints}
@@ -156,4 +152,4 @@ export const ScatterChart = React.memo(<K extends string, T extends string>(prop
</div>
);
});
ScatterChart.displayName = "ScatterChart";
ScatterChart.displayName = "ScatterChart";
+1 -1
View File
@@ -16,6 +16,6 @@
"devDependencies": {
"@plane/eslint-config": "*",
"@types/node": "^22.5.4",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
+7 -8
View File
@@ -1,6 +1,5 @@
import { ChartXAxisProperty, ChartYAxisMetric } from "@plane/constants";
import { TChartData } from "./charts";
import { Row } from "@tanstack/react-table";
export type TAnalyticsTabsBase = "overview" | "work-items";
export type TAnalyticsGraphsBase = "projects" | "work-items" | "custom-work-items";
@@ -21,6 +20,12 @@ export interface IAnalyticsResponseFields {
filter_count: number;
}
export interface IAnalyticsRadarEntity {
key: string;
name: string;
count: number;
}
// chart types
export interface IChartResponse {
@@ -38,7 +43,7 @@ export interface WorkItemInsightColumns {
backlog_work_items: number;
un_started_work_items: number;
started_work_items: number;
// incase of peek view, we will display the display_name instead of project__name
// because of the peek view, we will display the name of the project instead of project__name
display_name?: string;
avatar_url?: string;
assignee_id?: string;
@@ -53,9 +58,3 @@ export interface IAnalyticsParams {
y_axis: ChartYAxisMetric;
group_by?: ChartXAxisProperty;
}
export type ExportConfig<T> = {
key: string;
value: (row: Row<T>) => string | number;
label?: string;
};
+15 -14
View File
@@ -1,5 +1,7 @@
// ============================================================
// Chart Base
// Chart Base
// ============================================================
export * from "./common";
export type TChartLegend = {
@@ -46,11 +48,10 @@ type TChartProps<K extends string, T extends string> = {
y?: number;
};
showTooltip?: boolean;
customTooltipContent?: (props: { active?: boolean; label: string; payload: any }) => React.ReactNode;
};
// ============================================================
// Bar Chart
// Bar Chart
// ============================================================
export type TBarItem<T extends string> = {
@@ -70,7 +71,7 @@ export type TBarChartProps<K extends string, T extends string> = TChartProps<K,
};
// ============================================================
// Line Chart
// Line Chart
// ============================================================
export type TLineItem<T extends string> = {
@@ -89,7 +90,7 @@ export type TLineChartProps<K extends string, T extends string> = TChartProps<K,
};
// ============================================================
// Scatter Chart
// Scatter Chart
// ============================================================
export type TScatterPointItem<T extends string> = {
@@ -104,7 +105,7 @@ export type TScatterChartProps<K extends string, T extends string> = TChartProps
};
// ============================================================
// Area Chart
// Area Chart
// ============================================================
export type TAreaItem<T extends string> = {
@@ -129,7 +130,7 @@ export type TAreaChartProps<K extends string, T extends string> = TChartProps<K,
};
// ============================================================
// Pie Chart
// Pie Chart
// ============================================================
export type TCellItem<T extends string> = {
@@ -160,7 +161,7 @@ export type TPieChartProps<K extends string, T extends string> = Pick<
};
// ============================================================
// Tree Map
// Tree Map
// ============================================================
export type TreeMapItem = {
@@ -170,13 +171,13 @@ export type TreeMapItem = {
textClassName?: string;
icon?: React.ReactElement;
} & (
| {
| {
fillColor: string;
}
| {
| {
fillClassName: string;
}
);
);
export type TreeMapChartProps = {
data: TreeMapItem[];
@@ -216,8 +217,8 @@ export type TRadarItem<T extends string> = {
dot?: {
r: number;
fillOpacity: number;
};
};
}
}
export type TRadarChartProps<K extends string, T extends string> = Pick<
TChartProps<K, T>,
@@ -230,4 +231,4 @@ export type TRadarChartProps<K extends string, T extends string> = Pick<
label?: string;
strokeColor?: string;
};
};
}
+61 -81
View File
@@ -1,95 +1,75 @@
export const EUserPermissions = {
ADMIN: 20,
MEMBER: 15,
GUEST: 5,
} as const;
export enum EUserPermissions {
ADMIN = 20,
MEMBER = 15,
GUEST = 5,
}
export type EUserPermissions = typeof EUserPermissions[keyof typeof EUserPermissions];
export type TUserPermissions = EUserPermissions;
export type TUserPermissions = EUserPermissions.ADMIN | EUserPermissions.MEMBER | EUserPermissions.GUEST;
// project network
export const EProjectNetwork = {
PRIVATE: 0,
PUBLIC: 2,
} as const;
export type EProjectNetwork = typeof EProjectNetwork[keyof typeof EProjectNetwork];
export enum EProjectNetwork {
PRIVATE = 0,
PUBLIC = 2,
}
// project pages
export const EPageAccess = {
PUBLIC: 0,
PRIVATE: 1,
} as const;
export enum EPageAccess {
PUBLIC = 0,
PRIVATE = 1,
}
export type EPageAccess = typeof EPageAccess[keyof typeof EPageAccess];
export enum EDurationFilters {
NONE = "none",
TODAY = "today",
THIS_WEEK = "this_week",
THIS_MONTH = "this_month",
THIS_YEAR = "this_year",
CUSTOM = "custom",
}
export const EDurationFilters = {
NONE: "none",
TODAY: "today",
THIS_WEEK: "this_week",
THIS_MONTH: "this_month",
THIS_YEAR: "this_year",
CUSTOM: "custom",
} as const;
export type EDurationFilters = typeof EDurationFilters[keyof typeof EDurationFilters];
export const EIssueCommentAccessSpecifier = {
EXTERNAL: "EXTERNAL",
INTERNAL: "INTERNAL",
} as const;
export type EIssueCommentAccessSpecifier = typeof EIssueCommentAccessSpecifier[keyof typeof EIssueCommentAccessSpecifier];
export enum EIssueCommentAccessSpecifier {
EXTERNAL = "EXTERNAL",
INTERNAL = "INTERNAL",
}
// estimates
export const EEstimateSystem = {
POINTS: "points",
CATEGORIES: "categories",
TIME: "time",
} as const;
export enum EEstimateSystem {
POINTS = "points",
CATEGORIES = "categories",
TIME = "time",
}
export type EEstimateSystem = typeof EEstimateSystem[keyof typeof EEstimateSystem];
export const EEstimateUpdateStages = {
CREATE: "create",
EDIT: "edit",
SWITCH: "switch",
} as const;
export type EEstimateUpdateStages = typeof EEstimateUpdateStages[keyof typeof EEstimateUpdateStages];
export enum EEstimateUpdateStages {
CREATE = "create",
EDIT = "edit",
SWITCH = "switch",
}
// workspace notifications
export const ENotificationFilterType = {
CREATED: "created",
ASSIGNED: "assigned",
SUBSCRIBED: "subscribed",
} as const;
export enum ENotificationFilterType {
CREATED = "created",
ASSIGNED = "assigned",
SUBSCRIBED = "subscribed",
}
export type ENotificationFilterType = typeof ENotificationFilterType[keyof typeof ENotificationFilterType];
export enum EFileAssetType {
COMMENT_DESCRIPTION = "COMMENT_DESCRIPTION",
ISSUE_ATTACHMENT = "ISSUE_ATTACHMENT",
ISSUE_DESCRIPTION = "ISSUE_DESCRIPTION",
DRAFT_ISSUE_DESCRIPTION = "DRAFT_ISSUE_DESCRIPTION",
PAGE_DESCRIPTION = "PAGE_DESCRIPTION",
PROJECT_COVER = "PROJECT_COVER",
USER_AVATAR = "USER_AVATAR",
USER_COVER = "USER_COVER",
WORKSPACE_LOGO = "WORKSPACE_LOGO",
TEAM_SPACE_DESCRIPTION = "TEAM_SPACE_DESCRIPTION",
INITIATIVE_DESCRIPTION = "INITIATIVE_DESCRIPTION",
PROJECT_DESCRIPTION = "PROJECT_DESCRIPTION",
TEAM_SPACE_COMMENT_DESCRIPTION = "TEAM_SPACE_COMMENT_DESCRIPTION",
}
export const EFileAssetType = {
COMMENT_DESCRIPTION: "COMMENT_DESCRIPTION",
ISSUE_ATTACHMENT: "ISSUE_ATTACHMENT",
ISSUE_DESCRIPTION: "ISSUE_DESCRIPTION",
DRAFT_ISSUE_DESCRIPTION: "DRAFT_ISSUE_DESCRIPTION",
PAGE_DESCRIPTION: "PAGE_DESCRIPTION",
PROJECT_COVER: "PROJECT_COVER",
USER_AVATAR: "USER_AVATAR",
USER_COVER: "USER_COVER",
WORKSPACE_LOGO: "WORKSPACE_LOGO",
TEAM_SPACE_DESCRIPTION: "TEAM_SPACE_DESCRIPTION",
INITIATIVE_DESCRIPTION: "INITIATIVE_DESCRIPTION",
PROJECT_DESCRIPTION: "PROJECT_DESCRIPTION",
TEAM_SPACE_COMMENT_DESCRIPTION: "TEAM_SPACE_COMMENT_DESCRIPTION",
} as const;
export type EFileAssetType = typeof EFileAssetType[keyof typeof EFileAssetType];
export const EUpdateStatus = {
OFF_TRACK: "OFF-TRACK",
ON_TRACK: "ON-TRACK",
AT_RISK: "AT-RISK",
} as const;
export type EUpdateStatus = typeof EUpdateStatus[keyof typeof EUpdateStatus];
export enum EUpdateStatus {
OFF_TRACK = "OFF-TRACK",
ON_TRACK = "ON-TRACK",
AT_RISK = "AT-RISK",
}
+2 -2
View File
@@ -16,7 +16,7 @@ export interface IWorkspace {
readonly updated_by: string;
organization_size: string;
total_projects?: number;
role: EUserWorkspaceRoles;
role: number;
}
export interface IWorkspaceLite {
@@ -83,7 +83,7 @@ export interface IWorkspaceMemberMe {
default_props: IWorkspaceViewProps;
id: string;
member: string;
role: EUserWorkspaceRoles;
role: TUserPermissions | EUserWorkspaceRoles;
updated_at: Date;
updated_by: string;
view_props: IWorkspaceViewProps;
+1 -1
View File
@@ -72,6 +72,6 @@
"postcss-nested": "^6.0.1",
"storybook": "^8.1.1",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "5.3.3"
}
}
+15 -12
View File
@@ -25,19 +25,22 @@ export interface IBadgeStyling {
};
}
const badgeSizeStyling = {
sm: `px-2.5 py-1 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
md: `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
lg: `px-4 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
xl: `px-5 py-3 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
} as const;
// TODO: convert them to objects instead of enums
enum badgeSizeStyling {
sm = `px-2.5 py-1 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
md = `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
lg = `px-4 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
xl = `px-5 py-3 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
}
const badgeIconStyling = {
sm: "h-3 w-3 flex justify-center items-center overflow-hidden flex-shrink-0",
md: "h-3.5 w-3.5 flex justify-center items-center overflow-hidden flex-shrink-0",
lg: "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
xl: "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
} as const;
// TODO: convert them to objects instead of enums
enum badgeIconStyling {
sm = "h-3 w-3 flex justify-center items-center overflow-hidden flex-shrink-0",
md = "h-3.5 w-3.5 flex justify-center items-center overflow-hidden flex-shrink-0",
lg = "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
xl = "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
}
export const badgeStyling: IBadgeStyling = {
primary: {
+12 -12
View File
@@ -22,19 +22,19 @@ export interface IButtonStyling {
};
}
const buttonSizeStyling = {
sm: `px-3 py-1.5 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
md: `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
lg: `px-5 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
xl: `px-5 py-3.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
} as const;
enum buttonSizeStyling {
sm = `px-3 py-1.5 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
md = `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
lg = `px-5 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
xl = `px-5 py-3.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center`,
}
const buttonIconStyling = {
sm: "h-3 w-3 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
md: "h-3.5 w-3.5 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
lg: "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
xl: "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0 ",
} as const;
enum buttonIconStyling {
sm = "h-3 w-3 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
md = "h-3.5 w-3.5 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
lg = "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
xl = "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0 ",
}
export const buttonStyling: IButtonStyling = {
primary: {
+21 -26
View File
@@ -1,39 +1,34 @@
export const ECardVariant = {
WITHOUT_SHADOW: "without-shadow",
WITH_SHADOW: "with-shadow",
} as const;
export enum ECardVariant {
WITHOUT_SHADOW = "without-shadow",
WITH_SHADOW = "with-shadow",
}
export enum ECardDirection {
ROW = "row",
COLUMN = "column",
}
export enum ECardSpacing {
SM = "sm",
LG = "lg",
}
export type TCardVariant = ECardVariant.WITHOUT_SHADOW | ECardVariant.WITH_SHADOW;
export type TCardDirection = ECardDirection.ROW | ECardDirection.COLUMN;
export type TCardSpacing = ECardSpacing.SM | ECardSpacing.LG;
export type ECardVariant = typeof ECardVariant[keyof typeof ECardVariant];
export const ECardDirection = {
ROW: "row",
COLUMN: "column",
} as const;
export type ECardDirection = typeof ECardDirection[keyof typeof ECardDirection];
export const ECardSpacing = {
SM: "sm",
LG: "lg",
} as const;
export type ECardSpacing = typeof ECardSpacing[keyof typeof ECardSpacing];
export type TCardVariant = typeof ECardVariant.WITHOUT_SHADOW | typeof ECardVariant.WITH_SHADOW;
export type TCardDirection = typeof ECardDirection.ROW | typeof ECardDirection.COLUMN;
export type TCardSpacing = typeof ECardSpacing.SM | typeof ECardSpacing.LG;
export interface ICardProperties {
[key: string]: string;
}
const DEFAULT_STYLE =
"bg-custom-background-100 rounded-lg border-[0.5px] border-custom-border-200 w-full flex flex-col";
export const containerStyle: Record<ECardVariant, string> = {
export const containerStyle: ICardProperties = {
[ECardVariant.WITHOUT_SHADOW]: "",
[ECardVariant.WITH_SHADOW]: "hover:shadow-custom-shadow-4xl duration-300",
};
export const spacings: Record<ECardSpacing, string> = {
export const spacings = {
[ECardSpacing.SM]: "p-4",
[ECardSpacing.LG]: "p-6",
};
export const directions: Record<ECardDirection, string> = {
export const directions = {
[ECardDirection.ROW]: "flex-row space-x-3",
[ECardDirection.COLUMN]: "flex-col space-y-3",
};
+6 -8
View File
@@ -1,12 +1,10 @@
import { Placement } from "@popperjs/core";
import { EmojiClickData, Theme } from "emoji-picker-react";
export const EmojiIconPickerTypes = {
EMOJI: "emoji",
ICON: "icon",
} as const;
export type EmojiIconPickerTypes = typeof EmojiIconPickerTypes[keyof typeof EmojiIconPickerTypes];
export enum EmojiIconPickerTypes {
EMOJI = "emoji",
ICON = "icon",
}
export const TABS_LIST = [
{
@@ -21,11 +19,11 @@ export const TABS_LIST = [
export type TChangeHandlerProps =
| {
type: typeof EmojiIconPickerTypes.EMOJI;
type: EmojiIconPickerTypes.EMOJI;
value: EmojiClickData;
}
| {
type: typeof EmojiIconPickerTypes.ICON;
type: EmojiIconPickerTypes.ICON;
value: {
name: string;
color: string;
+6 -9
View File
@@ -1,12 +1,9 @@
export const EHeaderVariant = {
PRIMARY: "primary",
SECONDARY: "secondary",
TERNARY: "ternary",
} as const;
export type EHeaderVariant = typeof EHeaderVariant[keyof typeof EHeaderVariant];
export type THeaderVariant = typeof EHeaderVariant.PRIMARY | typeof EHeaderVariant.SECONDARY | typeof EHeaderVariant.TERNARY;
export enum EHeaderVariant {
PRIMARY = "primary",
SECONDARY = "secondary",
TERNARY = "ternary",
}
export type THeaderVariant = EHeaderVariant.PRIMARY | EHeaderVariant.SECONDARY | EHeaderVariant.TERNARY;
export interface IHeaderProperties {
[key: string]: string;
-9
View File
@@ -16,12 +16,3 @@ export const CYCLE_GROUP_COLORS: {
completed: "#16A34A",
draft: "#525252",
};
export const CYCLE_GROUP_I18N_LABELS: {
[key in TCycleGroups]: string;
} = {
current: "current",
upcoming: "common.upcoming",
completed: "common.completed",
draft: "project_cycles.status.draft",
};
-1
View File
@@ -3,4 +3,3 @@ export * from "./circle-dot-full-icon";
export * from "./contrast-icon";
export * from "./circle-dot-full-icon";
export * from "./cycle-group-icon";
export * from "./helper";
+16 -20
View File
@@ -1,21 +1,17 @@
export const EModalPosition = {
TOP: "flex items-center justify-center text-center mx-4 my-10 md:my-20",
CENTER: "flex items-end sm:items-center justify-center p-4 min-h-full",
} as const;
export enum EModalPosition {
TOP = "flex items-center justify-center text-center mx-4 my-10 md:my-20",
CENTER = "flex items-end sm:items-center justify-center p-4 min-h-full",
}
export type EModalPosition = typeof EModalPosition[keyof typeof EModalPosition];
export const EModalWidth = {
SM: "sm:max-w-sm",
MD: "sm:max-w-md",
LG: "sm:max-w-lg",
XL: "sm:max-w-xl",
XXL: "sm:max-w-2xl",
XXXL: "sm:max-w-3xl",
XXXXL: "sm:max-w-4xl",
VXL: "sm:max-w-5xl",
VIXL: "sm:max-w-6xl",
VIIXL: "sm:max-w-7xl",
} as const;
export type EModalWidth = typeof EModalWidth[keyof typeof EModalWidth];
export enum EModalWidth {
SM = "sm:max-w-sm",
MD = "sm:max-w-md",
LG = "sm:max-w-lg",
XL = "sm:max-w-xl",
XXL = "sm:max-w-2xl",
XXXL = "sm:max-w-3xl",
XXXXL = "sm:max-w-4xl",
VXL = "sm:max-w-5xl",
VIXL = "sm:max-w-6xl",
VIIXL = "sm:max-w-7xl",
}
+5 -8
View File
@@ -1,11 +1,8 @@
export const ERowVariant = {
REGULAR: "regular",
HUGGING: "hugging",
} as const;
export type ERowVariant = typeof ERowVariant[keyof typeof ERowVariant];
export type TRowVariant = typeof ERowVariant.REGULAR | typeof ERowVariant.HUGGING;
export enum ERowVariant {
REGULAR = "regular",
HUGGING = "hugging",
}
export type TRowVariant = ERowVariant.REGULAR | ERowVariant.HUGGING;
export interface IRowProperties {
[key: string]: string;
}
+9 -15
View File
@@ -1,19 +1,13 @@
export const ETagVariant = {
OUTLINED: "outlined",
} as const;
export enum ETagVariant {
OUTLINED = "outlined",
}
export enum ETagSize {
SM = "sm",
LG = "lg",
}
export type TTagVariant = ETagVariant.OUTLINED;
export type ETagVariant = typeof ETagVariant[keyof typeof ETagVariant];
export const ETagSize = {
SM: "sm",
LG: "lg",
} as const;
export type ETagSize = typeof ETagSize[keyof typeof ETagSize];
export type TTagVariant = typeof ETagVariant.OUTLINED;
export type TTagSize = typeof ETagSize.SM | typeof ETagSize.LG;
export type TTagSize = ETagSize.SM | ETagSize.LG;
export interface ITagProperties {
[key: string]: string;
}
+9 -11
View File
@@ -7,24 +7,22 @@ import { CircularBarSpinner } from "../spinners";
// helper
import { cn } from "../../helpers";
export const TOAST_TYPE = {
SUCCESS: "success",
ERROR: "error",
INFO: "info",
WARNING: "warning",
LOADING: "loading",
} as const;
export type TOAST_TYPE = (typeof TOAST_TYPE)[keyof typeof TOAST_TYPE];
export enum TOAST_TYPE {
SUCCESS = "success",
ERROR = "error",
INFO = "info",
WARNING = "warning",
LOADING = "loading",
}
type SetToastProps =
| {
type: typeof TOAST_TYPE.LOADING;
type: TOAST_TYPE.LOADING;
title?: string;
}
| {
id?: string | number;
type: Exclude<TOAST_TYPE, typeof TOAST_TYPE.LOADING>;
type: Exclude<TOAST_TYPE, TOAST_TYPE.LOADING>;
title: string;
message?: string;
actionItems?: React.ReactNode;
+1 -1
View File
@@ -30,6 +30,6 @@
"@types/react": "^18.3.11",
"@types/zxcvbn": "^4.4.5",
"tsup": "8.4.0",
"typescript": "5.8.3"
"typescript": "^5.3.3"
}
}
+8 -14
View File
@@ -11,15 +11,13 @@ import {
/**
* @description Password strength levels
*/
export const PasswordStrength = {
EMPTY: "empty",
WEAK: "weak",
FAIR: "fair",
GOOD: "good",
STRONG: "strong",
} as const;
export type PasswordStrength = typeof PasswordStrength[keyof typeof PasswordStrength];
export enum PasswordStrength {
EMPTY = "empty",
WEAK = "weak",
FAIR = "fair",
GOOD = "good",
STRONG = "strong",
}
/**
* @description Password strength criteria type
@@ -375,11 +373,7 @@ export const authErrorHandler = (
EAuthErrorCodes.ADMIN_USER_ALREADY_EXIST,
EAuthErrorCodes.ADMIN_USER_DOES_NOT_EXIST,
EAuthErrorCodes.USER_ACCOUNT_DEACTIVATED,
EAuthErrorCodes.MAGIC_LINK_LOGIN_DISABLED,
EAuthErrorCodes.PASSWORD_LOGIN_DISABLED,
EAuthErrorCodes.ADMIN_USER_DEACTIVATED,
EAuthErrorCodes.RATE_LIMIT_EXCEEDED,
] as EAuthErrorCodes[];
];
if (bannerAlertErrorCodes.includes(errorCode))
return {
@@ -58,21 +58,21 @@ export const AuthRoot: FC = observer(() => {
setAuthStep(EAuthSteps.PASSWORD);
}
if (
([
[
EAuthenticationErrorCodes.INVALID_MAGIC_CODE_SIGN_IN,
EAuthenticationErrorCodes.EXPIRED_MAGIC_CODE_SIGN_IN,
EAuthenticationErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN,
] as EAuthenticationErrorCodes[]).includes(errorhandler.code)
].includes(errorhandler.code)
) {
setAuthMode(EAuthModes.SIGN_IN);
setAuthStep(EAuthSteps.UNIQUE_CODE);
}
if (
([
[
EAuthenticationErrorCodes.INVALID_MAGIC_CODE_SIGN_UP,
EAuthenticationErrorCodes.EXPIRED_MAGIC_CODE_SIGN_UP,
EAuthenticationErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP,
] as EAuthenticationErrorCodes[]).includes(errorhandler.code)
].includes(errorhandler.code)
) {
setAuthMode(EAuthModes.SIGN_UP);
setAuthStep(EAuthSteps.UNIQUE_CODE);
@@ -40,7 +40,7 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
const isButtonDisabled = email.length === 0 || Boolean(emailError?.email) || isSubmitting;
const [isFocused, setIsFocused] = useState(true);
const [isFocused, setIsFocused] = useState(true)
const inputRef = useRef<HTMLInputElement>(null);
return (
@@ -54,12 +54,9 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
`relative flex items-center rounded-md bg-onboarding-background-200 border`,
!isFocused && Boolean(emailError?.email) ? `border-red-500` : `border-onboarding-border-100`
)}
onFocus={() => {
setIsFocused(true);
}}
onBlur={() => {
setIsFocused(false);
}}
tabIndex={-1}
onFocus={() => {setIsFocused(true)}}
onBlur={() => {setIsFocused(false)}}
>
<Input
id="email"
@@ -73,18 +70,14 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
autoFocus
ref={inputRef}
/>
{email.length > 0 && (
<button
type="button"
aria-label="Clear email"
{email.length > 0 && (
<XCircle
className="h-[46px] w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs"
onClick={() => {
setEmail("");
inputRef.current?.focus();
}}
tabIndex={-1}
>
<XCircle className="h-[46px] w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs" />
</button>
/>
)}
</div>
{emailError?.email && !isFocused && (
@@ -99,4 +92,4 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
</Button>
</form>
);
});
});
@@ -27,13 +27,11 @@ import { CoreRootStore } from "../root.store";
export type TIssueDisplayFilterOptions = Exclude<TIssueGroupByOptions, null | "team_project"> | "target_date";
export const EIssueGroupedAction = {
ADD: "ADD",
DELETE: "DELETE",
REORDER: "REORDER",
} as const;
export type EIssueGroupedAction = typeof EIssueGroupedAction[keyof typeof EIssueGroupedAction];
export enum EIssueGroupedAction {
ADD = "ADD",
DELETE = "DELETE",
REORDER = "REORDER",
}
export interface IBaseIssuesStore {
// observable
+9 -13
View File
@@ -1,17 +1,13 @@
export const EAuthModes = {
SIGN_IN: "SIGN_IN",
SIGN_UP: "SIGN_UP",
} as const;
export enum EAuthModes {
SIGN_IN = "SIGN_IN",
SIGN_UP = "SIGN_UP",
}
export type EAuthModes = typeof EAuthModes[keyof typeof EAuthModes];
export const EAuthSteps = {
EMAIL: "EMAIL",
PASSWORD: "PASSWORD",
UNIQUE_CODE: "UNIQUE_CODE",
} as const;
export type EAuthSteps = typeof EAuthSteps[keyof typeof EAuthSteps];
export enum EAuthSteps {
EMAIL = "EMAIL",
PASSWORD = "PASSWORD",
UNIQUE_CODE = "UNIQUE_CODE",
}
export interface ICsrfTokenData {
csrf_token: string;
+64 -70
View File
@@ -3,87 +3,81 @@ import Link from "next/link";
// helpers
import { SUPPORT_EMAIL } from "./common.helper";
export const EPageTypes = {
INIT: "INIT",
PUBLIC: "PUBLIC",
NON_AUTHENTICATED: "NON_AUTHENTICATED",
ONBOARDING: "ONBOARDING",
AUTHENTICATED: "AUTHENTICATED",
} as const;
export enum EPageTypes {
INIT = "INIT",
PUBLIC = "PUBLIC",
NON_AUTHENTICATED = "NON_AUTHENTICATED",
ONBOARDING = "ONBOARDING",
AUTHENTICATED = "AUTHENTICATED",
}
export type EPageTypes = typeof EPageTypes[keyof typeof EPageTypes];
export enum EErrorAlertType {
BANNER_ALERT = "BANNER_ALERT",
TOAST_ALERT = "TOAST_ALERT",
INLINE_FIRST_NAME = "INLINE_FIRST_NAME",
INLINE_EMAIL = "INLINE_EMAIL",
INLINE_PASSWORD = "INLINE_PASSWORD",
INLINE_EMAIL_CODE = "INLINE_EMAIL_CODE",
}
export const EErrorAlertType = {
BANNER_ALERT: "BANNER_ALERT",
TOAST_ALERT: "TOAST_ALERT",
INLINE_FIRST_NAME: "INLINE_FIRST_NAME",
INLINE_EMAIL: "INLINE_EMAIL",
INLINE_PASSWORD: "INLINE_PASSWORD",
INLINE_EMAIL_CODE: "INLINE_EMAIL_CODE",
} as const;
export type EErrorAlertType = typeof EErrorAlertType[keyof typeof EErrorAlertType];
export const EAuthenticationErrorCodes = {
export enum EAuthenticationErrorCodes {
// Global
INSTANCE_NOT_CONFIGURED: "5000",
INVALID_EMAIL: "5005",
EMAIL_REQUIRED: "5010",
SIGNUP_DISABLED: "5015",
INSTANCE_NOT_CONFIGURED = "5000",
INVALID_EMAIL = "5005",
EMAIL_REQUIRED = "5010",
SIGNUP_DISABLED = "5015",
// Password strength
INVALID_PASSWORD: "5020",
SMTP_NOT_CONFIGURED: "5025",
INVALID_PASSWORD = "5020",
SMTP_NOT_CONFIGURED = "5025",
// Sign Up
USER_ALREADY_EXIST: "5030",
AUTHENTICATION_FAILED_SIGN_UP: "5035",
REQUIRED_EMAIL_PASSWORD_SIGN_UP: "5040",
INVALID_EMAIL_SIGN_UP: "5045",
INVALID_EMAIL_MAGIC_SIGN_UP: "5050",
MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED: "5055",
USER_ALREADY_EXIST = "5030",
AUTHENTICATION_FAILED_SIGN_UP = "5035",
REQUIRED_EMAIL_PASSWORD_SIGN_UP = "5040",
INVALID_EMAIL_SIGN_UP = "5045",
INVALID_EMAIL_MAGIC_SIGN_UP = "5050",
MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED = "5055",
// Sign In
USER_ACCOUNT_DEACTIVATED: "5019",
USER_DOES_NOT_EXIST: "5060",
AUTHENTICATION_FAILED_SIGN_IN: "5065",
REQUIRED_EMAIL_PASSWORD_SIGN_IN: "5070",
INVALID_EMAIL_SIGN_IN: "5075",
INVALID_EMAIL_MAGIC_SIGN_IN: "5080",
MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED: "5085",
USER_ACCOUNT_DEACTIVATED = "5019",
USER_DOES_NOT_EXIST = "5060",
AUTHENTICATION_FAILED_SIGN_IN = "5065",
REQUIRED_EMAIL_PASSWORD_SIGN_IN = "5070",
INVALID_EMAIL_SIGN_IN = "5075",
INVALID_EMAIL_MAGIC_SIGN_IN = "5080",
MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED = "5085",
// Both Sign in and Sign up for magic
INVALID_MAGIC_CODE_SIGN_IN: "5090",
INVALID_MAGIC_CODE_SIGN_UP: "5092",
EXPIRED_MAGIC_CODE_SIGN_IN: "5095",
EXPIRED_MAGIC_CODE_SIGN_UP: "5097",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN: "5100",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP: "5102",
INVALID_MAGIC_CODE_SIGN_IN = "5090",
INVALID_MAGIC_CODE_SIGN_UP = "5092",
EXPIRED_MAGIC_CODE_SIGN_IN = "5095",
EXPIRED_MAGIC_CODE_SIGN_UP = "5097",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN = "5100",
EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP = "5102",
// Oauth
OAUTH_NOT_CONFIGURED: "5104",
GOOGLE_NOT_CONFIGURED: "5105",
GITHUB_NOT_CONFIGURED: "5110",
GITLAB_NOT_CONFIGURED: "5111",
GOOGLE_OAUTH_PROVIDER_ERROR: "5115",
GITHUB_OAUTH_PROVIDER_ERROR: "5120",
GITLAB_OAUTH_PROVIDER_ERROR: "5121",
OAUTH_NOT_CONFIGURED = "5104",
GOOGLE_NOT_CONFIGURED = "5105",
GITHUB_NOT_CONFIGURED = "5110",
GITLAB_NOT_CONFIGURED = "5111",
GOOGLE_OAUTH_PROVIDER_ERROR = "5115",
GITHUB_OAUTH_PROVIDER_ERROR = "5120",
GITLAB_OAUTH_PROVIDER_ERROR = "5121",
// Reset Password
INVALID_PASSWORD_TOKEN: "5125",
EXPIRED_PASSWORD_TOKEN: "5130",
INVALID_PASSWORD_TOKEN = "5125",
EXPIRED_PASSWORD_TOKEN = "5130",
// Change password
INCORRECT_OLD_PASSWORD: "5135",
MISSING_PASSWORD: "5138",
INVALID_NEW_PASSWORD: "5140",
INCORRECT_OLD_PASSWORD = "5135",
MISSING_PASSWORD = "5138",
INVALID_NEW_PASSWORD = "5140",
// set passowrd
PASSWORD_ALREADY_SET: "5145",
PASSWORD_ALREADY_SET = "5145",
// Admin
ADMIN_ALREADY_EXIST: "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME: "5155",
INVALID_ADMIN_EMAIL: "5160",
INVALID_ADMIN_PASSWORD: "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD: "5170",
ADMIN_AUTHENTICATION_FAILED: "5175",
ADMIN_USER_ALREADY_EXIST: "5180",
ADMIN_USER_DOES_NOT_EXIST: "5185",
} as const;
export type EAuthenticationErrorCodes = typeof EAuthenticationErrorCodes[keyof typeof EAuthenticationErrorCodes];
ADMIN_ALREADY_EXIST = "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME = "5155",
INVALID_ADMIN_EMAIL = "5160",
INVALID_ADMIN_PASSWORD = "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD = "5170",
ADMIN_AUTHENTICATION_FAILED = "5175",
ADMIN_USER_ALREADY_EXIST = "5180",
ADMIN_USER_DOES_NOT_EXIST = "5185",
}
export type TAuthErrorInfo = {
type: EErrorAlertType;
@@ -389,7 +383,7 @@ export const authErrorHandler = (
EAuthenticationErrorCodes.ADMIN_USER_ALREADY_EXIST,
EAuthenticationErrorCodes.ADMIN_USER_DOES_NOT_EXIST,
EAuthenticationErrorCodes.USER_ACCOUNT_DEACTIVATED,
] as EAuthenticationErrorCodes[];
];
if (bannerAlertErrorCodes.includes(errorCode))
return {
+6 -8
View File
@@ -1,13 +1,11 @@
import zxcvbn from "zxcvbn";
export const E_PASSWORD_STRENGTH = {
EMPTY: "empty",
LENGTH_NOT_VALID: "length_not_valid",
STRENGTH_NOT_VALID: "strength_not_valid",
STRENGTH_VALID: "strength_valid",
} as const;
export type E_PASSWORD_STRENGTH = typeof E_PASSWORD_STRENGTH[keyof typeof E_PASSWORD_STRENGTH];
export enum E_PASSWORD_STRENGTH {
EMPTY = "empty",
LENGTH_NOT_VALID = "length_not_valid",
STRENGTH_NOT_VALID = "strength_not_valid",
STRENGTH_VALID = "strength_valid",
}
const PASSWORD_MIN_LENGTH = 8;
// const PASSWORD_NUMBER_REGEX = /\d/;
+1 -1
View File
@@ -63,6 +63,6 @@
"@types/uuid": "^9.0.1",
"@types/zxcvbn": "^4.4.4",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"typescript": "5.8.3"
"typescript": "5.3.3"
}
}
@@ -2,7 +2,7 @@
import { CommandPalette } from "@/components/command-palette";
import { ContentWrapper } from "@/components/core";
import { SettingsHeader } from "@/components/settings";
import { SettingsContentLayout, SettingsHeader } from "@/components/settings";
import { AuthenticationWrapper } from "@/lib/wrappers";
import { WorkspaceAuthWrapper } from "@/plane-web/layouts/workspace-wrapper";
@@ -15,8 +15,8 @@ export default function SettingsLayout({ children }: { children: React.ReactNode
{/* Header */}
<SettingsHeader />
{/* Content */}
<ContentWrapper className="px-4 md:pl-12 md:flex w-full">
<div className="w-full h-full overflow-hidden">{children}</div>
<ContentWrapper className="px-4 md:pl-12 md:pt-page-y md:flex w-full">
<SettingsContentLayout>{children}</SettingsContentLayout>
</ContentWrapper>
</main>
</WorkspaceAuthWrapper>
@@ -30,7 +30,7 @@ const WorkspaceSettingLayout: FC<IWorkspaceSettingLayout> = observer((props) =>
let isAuthorized: boolean | string = false;
if (pathname && workspaceSlug && userWorkspaceRole) {
isAuthorized = WORKSPACE_SETTINGS_ACCESS[accessKey]?.includes(userWorkspaceRole);
isAuthorized = WORKSPACE_SETTINGS_ACCESS[accessKey]?.includes(userWorkspaceRole as EUserWorkspaceRoles);
}
return (
@@ -39,13 +39,13 @@ const WorkspaceSettingLayout: FC<IWorkspaceSettingLayout> = observer((props) =>
hamburgerContent={WorkspaceSettingsSidebar}
activePath={getWorkspaceActivePath(pathname) || ""}
/>
<div className="inset-y-0 flex flex-row w-full h-full">
<div className="inset-y-0 flex flex-row w-full">
{workspaceUserInfo && !isAuthorized ? (
<NotAuthorizedView section="settings" className="h-auto" />
) : (
<div className="relative flex h-full w-full">
<div className="hidden md:block">{<WorkspaceSettingsSidebar />}</div>
<div className="w-full h-full overflow-y-scroll md:pt-page-y">{children}</div>
{children}
</div>
)}
</div>
@@ -52,7 +52,7 @@ export const WorkspaceSettingsSidebar = (props: TWorkspaceSettingsSidebarProps)
isMobile={isMobile}
categories={WORKSPACE_SETTINGS_CATEGORIES.filter(
(category) =>
isAdmin || !([WORKSPACE_SETTINGS_CATEGORY.FEATURES, WORKSPACE_SETTINGS_CATEGORY.DEVELOPER] as WORKSPACE_SETTINGS_CATEGORY[]).includes(category)
isAdmin || ![WORKSPACE_SETTINGS_CATEGORY.FEATURES, WORKSPACE_SETTINGS_CATEGORY.DEVELOPER].includes(category)
)}
groupedSettings={GROUPED_WORKSPACE_SETTINGS}
workspaceSlug={workspaceSlug.toString()}
@@ -24,9 +24,7 @@ const ProfileSettingsLayout = observer((props: Props) => {
<div className="hidden md:block">
<ProfileSidebar />
</div>
<div className="w-full h-full overflow-y-scroll md:pt-page-y">
<SettingsContentWrapper>{children}</SettingsContentWrapper>
</div>
<SettingsContentWrapper>{children}</SettingsContentWrapper>
</div>
</>
);
@@ -36,7 +36,7 @@ const ProjectSettingsLayout = observer((props: Props) => {
<ProjectAuthWrapper workspaceSlug={workspaceSlug?.toString()} projectId={projectId?.toString()}>
<div className="relative flex h-full w-full">
<div className="hidden md:block">{projectId && <ProjectSettingsSidebar />}</div>
<div className="w-full h-full overflow-y-scroll md:pt-page-y">{children}</div>
{children}
</div>
</ProjectAuthWrapper>
</>
+5 -7
View File
@@ -22,13 +22,11 @@ import { AuthenticationWrapper } from "@/lib/wrappers";
import { WorkspaceService } from "@/plane-web/services";
// services
const EOnboardingSteps = {
PROFILE_SETUP: "PROFILE_SETUP",
WORKSPACE_CREATE_OR_JOIN: "WORKSPACE_CREATE_OR_JOIN",
INVITE_MEMBERS: "INVITE_MEMBERS",
} as const;
type EOnboardingSteps = typeof EOnboardingSteps[keyof typeof EOnboardingSteps];
enum EOnboardingSteps {
PROFILE_SETUP = "PROFILE_SETUP",
WORKSPACE_CREATE_OR_JOIN = "WORKSPACE_CREATE_OR_JOIN",
INVITE_MEMBERS = "INVITE_MEMBERS",
}
const workspaceService = new WorkspaceService();
+2 -4
View File
@@ -47,19 +47,17 @@ const WORKSPACE_ACTION_LINKS = [
},
];
const ProjectActionIcons = ({ type, size, className = "" }: { type: string; size?: number; className?: string }) => {
export const ProjectActionIcons = ({ type, size, className }: { type: string; size?: number; className?: string }) => {
const icons = {
profile: CircleUser,
security: KeyRound,
activity: Activity,
preferences: Settings2,
appearance: Settings2,
notifications: Bell,
"api-tokens": KeyRound,
};
if (type === undefined) return null;
const Icon = icons[type as keyof typeof icons];
if (!Icon) return null;
return <Icon size={size} className={className} />;
};
export const ProfileLayoutSidebar = observer(() => {
-1
View File
@@ -5,7 +5,6 @@ export const ANALYTICS_TABS: {
key: TAnalyticsTabsBase;
i18nKey: string;
content: React.FC;
isExtended?: boolean;
}[] = [
{ key: "overview", i18nKey: "common.overview", content: Overview },
{ key: "work-items", i18nKey: "sidebar.work_items", content: WorkItems },

Some files were not shown because too many files have changed in this diff Show More