mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: remove unnecessary types
This commit is contained in:
parent
2921f230bf
commit
0aa02a603d
@ -1,59 +1,32 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { CalendarCheck2 } from "lucide-react";
|
||||||
|
// types
|
||||||
|
import { TStateGroups } from "@plane/types";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderFullDate } from "@/helpers/date-time.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
|
import { renderFormattedDate } from "@/helpers/date-time.helper";
|
||||||
|
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
|
||||||
|
|
||||||
export const dueDateIconDetails = (
|
type Props = {
|
||||||
date: string,
|
due_date: string;
|
||||||
stateGroup: string
|
group: TStateGroups;
|
||||||
): {
|
|
||||||
iconName: string;
|
|
||||||
className: string;
|
|
||||||
} => {
|
|
||||||
let iconName = "calendar_today";
|
|
||||||
let className = "";
|
|
||||||
|
|
||||||
if (!date || ["completed", "cancelled"].includes(stateGroup)) {
|
|
||||||
iconName = "calendar_today";
|
|
||||||
className = "";
|
|
||||||
} else {
|
|
||||||
const today = new Date();
|
|
||||||
today.setHours(0, 0, 0, 0);
|
|
||||||
const targetDate = new Date(date);
|
|
||||||
targetDate.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const timeDifference = targetDate.getTime() - today.getTime();
|
|
||||||
|
|
||||||
if (timeDifference < 0) {
|
|
||||||
iconName = "event_busy";
|
|
||||||
className = "text-red-500";
|
|
||||||
} else if (timeDifference === 0) {
|
|
||||||
iconName = "today";
|
|
||||||
className = "text-red-500";
|
|
||||||
} else if (timeDifference === 24 * 60 * 60 * 1000) {
|
|
||||||
iconName = "event";
|
|
||||||
className = "text-yellow-500";
|
|
||||||
} else {
|
|
||||||
iconName = "calendar_today";
|
|
||||||
className = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
iconName,
|
|
||||||
className,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IssueBlockDueDate = ({ due_date, group }: { due_date: string; group: string }) => {
|
export const IssueBlockDueDate = (props: Props) => {
|
||||||
const iconDetails = dueDateIconDetails(due_date, group);
|
const { due_date, group } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs text-custom-text-100">
|
<div
|
||||||
<span className={`material-symbols-rounded -my-0.5 text-sm ${iconDetails.className}`}>
|
className={cn(
|
||||||
{iconDetails.iconName}
|
"flex items-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs text-custom-text-100",
|
||||||
</span>
|
{
|
||||||
{renderFullDate(due_date)}
|
"text-red-500": shouldHighlightIssueDueDate(due_date, group),
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<CalendarCheck2 className="size-3 flex-shrink-0" />
|
||||||
|
{renderFormattedDate(due_date)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
// types
|
// types
|
||||||
import { issuePriorityFilter } from "@/constants/issue";
|
import { TIssuePriorities } from "@plane/types";
|
||||||
import { TIssueFilterPriority } from "@/types/issue";
|
|
||||||
// constants
|
// constants
|
||||||
|
import { issuePriorityFilter } from "@/constants/issue";
|
||||||
|
|
||||||
export const IssueBlockPriority = ({ priority }: { priority: TIssueFilterPriority | null }) => {
|
export const IssueBlockPriority = ({ priority }: { priority: TIssuePriorities | null }) => {
|
||||||
const priority_detail = priority != null ? issuePriorityFilter(priority) : null;
|
const priority_detail = priority != null ? issuePriorityFilter(priority) : null;
|
||||||
|
|
||||||
if (priority_detail === null) return <></>;
|
if (priority_detail === null) return <></>;
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
// mobx react lite
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
// types
|
||||||
|
import { IStateLite } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { StateGroupIcon } from "@plane/ui";
|
import { StateGroupIcon } from "@plane/ui";
|
||||||
// constants
|
// constants
|
||||||
import { issueGroupFilter } from "@/constants/issue";
|
import { issueGroupFilter } from "@/constants/issue";
|
||||||
// mobx hook
|
|
||||||
// import { useIssue } from "@/hooks/store";
|
|
||||||
// interfaces
|
|
||||||
import { IIssueState } from "@/types/issue";
|
|
||||||
|
|
||||||
export const IssueKanBanHeader = observer(({ state }: { state: IIssueState }) => {
|
export const IssueKanBanHeader = observer(({ state }: { state: IStateLite }) => {
|
||||||
// const { getCountOfIssuesByState } = useIssue();
|
// const { getCountOfIssuesByState } = useIssue();
|
||||||
const stateGroup = issueGroupFilter(state.group);
|
const stateGroup = issueGroupFilter(state.group);
|
||||||
|
|
||||||
@ -21,7 +19,7 @@ export const IssueKanBanHeader = observer(({ state }: { state: IIssueState }) =>
|
|||||||
<div className="flex h-3.5 w-3.5 flex-shrink-0 items-center justify-center">
|
<div className="flex h-3.5 w-3.5 flex-shrink-0 items-center justify-center">
|
||||||
<StateGroupIcon stateGroup={state.group} color={state.color} height="14" width="14" />
|
<StateGroupIcon stateGroup={state.group} color={state.color} height="14" width="14" />
|
||||||
</div>
|
</div>
|
||||||
<div className="mr-1 truncate font-semibold capitalize text-custom-text-200">{state?.name}</div>
|
<div className="mr-1 truncate font-medium capitalize text-custom-text-200">{state?.name}</div>
|
||||||
{/* <span className="flex-shrink-0 rounded-full text-custom-text-300">{getCountOfIssuesByState(state.id)}</span> */}
|
{/* <span className="flex-shrink-0 rounded-full text-custom-text-300">{getCountOfIssuesByState(state.id)}</span> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
// types
|
||||||
|
import { IStateLite } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { StateGroupIcon } from "@plane/ui";
|
import { StateGroupIcon } from "@plane/ui";
|
||||||
// constants
|
// constants
|
||||||
import { issueGroupFilter } from "@/constants/issue";
|
import { issueGroupFilter } from "@/constants/issue";
|
||||||
// mobx hook
|
|
||||||
// import { useIssue } from "@/hooks/store";
|
|
||||||
// types
|
|
||||||
import { IIssueState } from "@/types/issue";
|
|
||||||
|
|
||||||
export const IssueListHeader = observer(({ state }: { state: IIssueState }) => {
|
export const IssueListHeader = observer(({ state }: { state: IStateLite }) => {
|
||||||
// const { getCountOfIssuesByState } = useIssue();
|
// const { getCountOfIssuesByState } = useIssue();
|
||||||
const stateGroup = issueGroupFilter(state.group);
|
const stateGroup = issueGroupFilter(state.group);
|
||||||
// const count = getCountOfIssuesByState(state.id);
|
// const count = getCountOfIssuesByState(state.id);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
// icons
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
// types
|
// types
|
||||||
import { IIssueLabel, IIssueState, TFilters } from "@/types/issue";
|
import { IStateLite } from "@plane/types";
|
||||||
|
import { IIssueLabel, TFilters } from "@/types/issue";
|
||||||
// components
|
// components
|
||||||
import { AppliedPriorityFilters } from "./priority";
|
import { AppliedPriorityFilters } from "./priority";
|
||||||
import { AppliedStateFilters } from "./state";
|
import { AppliedStateFilters } from "./state";
|
||||||
@ -14,7 +14,7 @@ type Props = {
|
|||||||
handleRemoveAllFilters: () => void;
|
handleRemoveAllFilters: () => void;
|
||||||
handleRemoveFilter: (key: keyof TFilters, value: string | null) => void;
|
handleRemoveFilter: (key: keyof TFilters, value: string | null) => void;
|
||||||
labels?: IIssueLabel[] | undefined;
|
labels?: IIssueLabel[] | undefined;
|
||||||
states?: IIssueState[] | undefined;
|
states?: IStateLite[] | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const replaceUnderscoreIfSnakeCase = (str: string) => str.replace(/_/g, " ");
|
export const replaceUnderscoreIfSnakeCase = (str: string) => str.replace(/_/g, " ");
|
||||||
|
@ -80,7 +80,7 @@ export const IssueAppliedFilters: FC<TIssueAppliedFilters> = observer((props) =>
|
|||||||
if (Object.keys(appliedFilters).length === 0) return null;
|
if (Object.keys(appliedFilters).length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border-b border-custom-border-200 p-5 py-3">
|
<div className="border-b border-custom-border-200 bg-custom-background-100 p-4">
|
||||||
<AppliedFiltersList
|
<AppliedFiltersList
|
||||||
appliedFilters={appliedFilters || {}}
|
appliedFilters={appliedFilters || {}}
|
||||||
handleRemoveFilter={handleFilters as any}
|
handleRemoveFilter={handleFilters as any}
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
import { StateGroupIcon } from "@plane/ui";
|
|
||||||
// types
|
// types
|
||||||
import { IIssueState } from "@/types/issue";
|
import { IStateLite } from "@plane/types";
|
||||||
|
// ui
|
||||||
|
import { StateGroupIcon } from "@plane/ui";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleRemove: (val: string) => void;
|
handleRemove: (val: string) => void;
|
||||||
states: IIssueState[];
|
states: IStateLite[];
|
||||||
values: string[];
|
values: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,8 @@ import React, { useState } from "react";
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Search, X } from "lucide-react";
|
import { Search, X } from "lucide-react";
|
||||||
// types
|
// types
|
||||||
import { IIssueState, IIssueLabel, IIssueFilterOptions, TIssueFilterKeys } from "@/types/issue";
|
import { IStateLite } from "@plane/types";
|
||||||
|
import { IIssueLabel, IIssueFilterOptions, TIssueFilterKeys } from "@/types/issue";
|
||||||
// components
|
// components
|
||||||
import { FilterPriority, FilterState } from "./";
|
import { FilterPriority, FilterState } from "./";
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ type Props = {
|
|||||||
handleFilters: (key: keyof IIssueFilterOptions, value: string | string[]) => void;
|
handleFilters: (key: keyof IIssueFilterOptions, value: string | string[]) => void;
|
||||||
layoutDisplayFiltersOptions: TIssueFilterKeys[];
|
layoutDisplayFiltersOptions: TIssueFilterKeys[];
|
||||||
labels?: IIssueLabel[] | undefined;
|
labels?: IIssueLabel[] | undefined;
|
||||||
states?: IIssueState[] | undefined;
|
states?: IStateLite[] | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FilterSelection: React.FC<Props> = observer((props) => {
|
export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
// types
|
||||||
|
import { IStateLite } from "@plane/types";
|
||||||
|
// ui
|
||||||
import { Loader, StateGroupIcon } from "@plane/ui";
|
import { Loader, StateGroupIcon } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { FilterHeader, FilterOption } from "@/components/issues/filters/helpers";
|
import { FilterHeader, FilterOption } from "@/components/issues/filters/helpers";
|
||||||
// types
|
|
||||||
import { IIssueState } from "@/types/issue";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
appliedFilters: string[] | null;
|
appliedFilters: string[] | null;
|
||||||
handleUpdate: (val: string) => void;
|
handleUpdate: (val: string) => void;
|
||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
states: IIssueState[] | undefined;
|
states: IStateLite[] | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FilterState: React.FC<Props> = (props) => {
|
export const FilterState: React.FC<Props> = (props) => {
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
|
import { CalendarCheck2 } from "lucide-react";
|
||||||
// ui
|
// ui
|
||||||
import { StateGroupIcon, TOAST_TYPE, setToast } from "@plane/ui";
|
import { StateGroupIcon, TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
// icons
|
// components
|
||||||
import { Icon } from "@/components/ui";
|
import { Icon } from "@/components/ui";
|
||||||
// constants
|
// constants
|
||||||
import { issueGroupFilter, issuePriorityFilter } from "@/constants/issue";
|
import { issueGroupFilter, issuePriorityFilter } from "@/constants/issue";
|
||||||
// helpers
|
// helpers
|
||||||
import { renderFullDate } from "@/helpers/date-time.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
|
import { renderFormattedDate } from "@/helpers/date-time.helper";
|
||||||
|
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
|
||||||
import { copyTextToClipboard, addSpaceIfCamelCase } from "@/helpers/string.helper";
|
import { copyTextToClipboard, addSpaceIfCamelCase } from "@/helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IPeekMode } from "@/types/issue";
|
import { IIssue, IPeekMode } from "@/types/issue";
|
||||||
// components
|
|
||||||
import { dueDateIconDetails } from "../board-views/block-due-date";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
issueDetails: IIssue;
|
issueDetails: IIssue;
|
||||||
@ -23,8 +24,6 @@ export const PeekOverviewIssueProperties: React.FC<Props> = ({ issueDetails, mod
|
|||||||
|
|
||||||
const priority = issueDetails.priority ? issuePriorityFilter(issueDetails.priority) : null;
|
const priority = issueDetails.priority ? issuePriorityFilter(issueDetails.priority) : null;
|
||||||
|
|
||||||
const dueDateIcon = dueDateIconDetails(issueDetails.target_date, state.group);
|
|
||||||
|
|
||||||
const handleCopyLink = () => {
|
const handleCopyLink = () => {
|
||||||
const urlToCopy = window.location.href;
|
const urlToCopy = window.location.href;
|
||||||
|
|
||||||
@ -104,11 +103,19 @@ export const PeekOverviewIssueProperties: React.FC<Props> = ({ issueDetails, mod
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{issueDetails.target_date ? (
|
{issueDetails.target_date ? (
|
||||||
<div className="flex h-6 items-center gap-1 rounded border border-custom-border-100 bg-custom-background-80 px-2.5 py-1 text-xs text-custom-text-100">
|
<div
|
||||||
<span className={`material-symbols-rounded -my-0.5 text-sm ${dueDateIcon.className}`}>
|
className={cn(
|
||||||
{dueDateIcon.iconName}
|
"flex h-6 items-center gap-1 rounded border border-custom-border-100 bg-custom-background-80 px-2.5 py-1 text-xs text-custom-text-100",
|
||||||
</span>
|
{
|
||||||
{renderFullDate(issueDetails.target_date)}
|
"text-red-500": shouldHighlightIssueDueDate(
|
||||||
|
issueDetails.target_date,
|
||||||
|
issueDetails.state_detail.group
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<CalendarCheck2 className="size-3" />
|
||||||
|
{renderFormattedDate(issueDetails.target_date)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-custom-text-200">Empty</span>
|
<span className="text-custom-text-200">Empty</span>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// interfaces
|
// types
|
||||||
|
import { TIssuePriorities } from "@plane/types";
|
||||||
import {
|
import {
|
||||||
TIssueLayout,
|
TIssueLayout,
|
||||||
TIssueLayoutViews,
|
TIssueLayoutViews,
|
||||||
TIssueFilterKeys,
|
TIssueFilterKeys,
|
||||||
TIssueFilterPriority,
|
|
||||||
TIssueFilterPriorityObject,
|
TIssueFilterPriorityObject,
|
||||||
TIssueFilterState,
|
TIssueFilterState,
|
||||||
TIssueFilterStateObject,
|
TIssueFilterStateObject,
|
||||||
} from "types/issue";
|
} from "@/types/issue";
|
||||||
|
|
||||||
// issue filters
|
// issue filters
|
||||||
export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: { [key in TIssueLayout]: Record<"filters", TIssueFilterKeys[]> } = {
|
export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: { [key in TIssueLayout]: Record<"filters", TIssueFilterKeys[]> } = {
|
||||||
@ -75,7 +75,7 @@ export const issuePriorityFilters: TIssueFilterPriorityObject[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const issuePriorityFilter = (priorityKey: TIssueFilterPriority): TIssueFilterPriorityObject | undefined => {
|
export const issuePriorityFilter = (priorityKey: TIssuePriorities): TIssueFilterPriorityObject | undefined => {
|
||||||
const currentIssuePriority: TIssueFilterPriorityObject | undefined =
|
const currentIssuePriority: TIssueFilterPriorityObject | undefined =
|
||||||
issuePriorityFilters && issuePriorityFilters.length > 0
|
issuePriorityFilters && issuePriorityFilters.length > 0
|
||||||
? issuePriorityFilters.find((_priority) => _priority.key === priorityKey)
|
? issuePriorityFilters.find((_priority) => _priority.key === priorityKey)
|
||||||
|
37
space/constants/state.ts
Normal file
37
space/constants/state.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { TStateGroups } from "@plane/types";
|
||||||
|
|
||||||
|
export const STATE_GROUPS: {
|
||||||
|
[key in TStateGroups]: {
|
||||||
|
key: TStateGroups;
|
||||||
|
label: string;
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
} = {
|
||||||
|
backlog: {
|
||||||
|
key: "backlog",
|
||||||
|
label: "Backlog",
|
||||||
|
color: "#d9d9d9",
|
||||||
|
},
|
||||||
|
unstarted: {
|
||||||
|
key: "unstarted",
|
||||||
|
label: "Unstarted",
|
||||||
|
color: "#3f76ff",
|
||||||
|
},
|
||||||
|
started: {
|
||||||
|
key: "started",
|
||||||
|
label: "Started",
|
||||||
|
color: "#f59e0b",
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
key: "completed",
|
||||||
|
label: "Completed",
|
||||||
|
color: "#16a34a",
|
||||||
|
},
|
||||||
|
cancelled: {
|
||||||
|
key: "cancelled",
|
||||||
|
label: "Canceled",
|
||||||
|
color: "#dc2626",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ARCHIVABLE_STATE_GROUPS = [STATE_GROUPS.completed.key, STATE_GROUPS.cancelled.key];
|
@ -1,3 +1,6 @@
|
|||||||
|
import { format, isValid } from "date-fns";
|
||||||
|
import isNumber from "lodash/isNumber";
|
||||||
|
|
||||||
export const timeAgo = (time: any) => {
|
export const timeAgo = (time: any) => {
|
||||||
switch (typeof time) {
|
switch (typeof time) {
|
||||||
case "number":
|
case "number":
|
||||||
@ -14,24 +17,43 @@ export const timeAgo = (time: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Returns date and month, if date is of the current year
|
* This method returns a date from string of type yyyy-mm-dd
|
||||||
* @description Returns date, month adn year, if date is of a different year than current
|
* This method is recommended to use instead of new Date() as this does not introduce any timezone offsets
|
||||||
* @param {string} date
|
* @param date
|
||||||
* @example renderFullDate("2023-01-01") // 1 Jan
|
* @returns date or undefined
|
||||||
* @example renderFullDate("2021-01-01") // 1 Jan, 2021
|
|
||||||
*/
|
*/
|
||||||
|
export const getDate = (date: string | Date | undefined | null): Date | undefined => {
|
||||||
|
try {
|
||||||
|
if (!date || date === "") return;
|
||||||
|
|
||||||
export const renderFullDate = (date: string): string => {
|
if (typeof date !== "string" && !(date instanceof String)) return date;
|
||||||
if (!date) return "";
|
|
||||||
|
|
||||||
const months: string[] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
const [yearString, monthString, dayString] = date.substring(0, 10).split("-");
|
||||||
|
const year = parseInt(yearString);
|
||||||
|
const month = parseInt(monthString);
|
||||||
|
const day = parseInt(dayString);
|
||||||
|
if (!isNumber(year) || !isNumber(month) || !isNumber(day)) return;
|
||||||
|
|
||||||
const currentDate: Date = new Date();
|
return new Date(year, month - 1, day);
|
||||||
const [year, month, day]: number[] = date.split("-").map(Number);
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
const formattedMonth: string = months[month - 1];
|
}
|
||||||
const formattedDay: string = day < 10 ? `0${day}` : day.toString();
|
};
|
||||||
|
|
||||||
if (currentDate.getFullYear() === year) return `${formattedDay} ${formattedMonth}`;
|
/**
|
||||||
else return `${formattedDay} ${formattedMonth}, ${year}`;
|
* @returns {string | null} formatted date in the format of MMM dd, yyyy
|
||||||
|
* @description Returns date in the formatted format
|
||||||
|
* @param {Date | string} date
|
||||||
|
* @example renderFormattedDate("2024-01-01") // Jan 01, 2024
|
||||||
|
*/
|
||||||
|
export const renderFormattedDate = (date: string | Date | undefined | null): string | null => {
|
||||||
|
// Parse the date to check if it is valid
|
||||||
|
const parsedDate = getDate(date);
|
||||||
|
// return if undefined
|
||||||
|
if (!parsedDate) return null;
|
||||||
|
// Check if the parsed date is valid before formatting
|
||||||
|
if (!isValid(parsedDate)) return null; // Return null for invalid dates
|
||||||
|
// Format the date in format (MMM dd, yyyy)
|
||||||
|
const formattedDate = format(parsedDate, "MMM dd, yyyy");
|
||||||
|
return formattedDate;
|
||||||
};
|
};
|
||||||
|
30
space/helpers/issue.helper.ts
Normal file
30
space/helpers/issue.helper.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { differenceInCalendarDays } from "date-fns";
|
||||||
|
// types
|
||||||
|
import { TStateGroups } from "@plane/types";
|
||||||
|
// constants
|
||||||
|
import { STATE_GROUPS } from "@/constants/state";
|
||||||
|
// helpers
|
||||||
|
import { getDate } from "@/helpers/date-time.helper";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description check if the issue due date should be highlighted
|
||||||
|
* @param date
|
||||||
|
* @param stateGroup
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
|
export const shouldHighlightIssueDueDate = (
|
||||||
|
date: string | Date | null,
|
||||||
|
stateGroup: TStateGroups | undefined
|
||||||
|
): boolean => {
|
||||||
|
if (!date || !stateGroup) return false;
|
||||||
|
// if the issue is completed or cancelled, don't highlight the due date
|
||||||
|
if ([STATE_GROUPS.completed.key, STATE_GROUPS.cancelled.key].includes(stateGroup)) return false;
|
||||||
|
|
||||||
|
const parsedDate = getDate(date);
|
||||||
|
if (!parsedDate) return false;
|
||||||
|
|
||||||
|
const targetDateDistance = differenceInCalendarDays(parsedDate, new Date());
|
||||||
|
|
||||||
|
// if the issue is overdue, highlight the due date
|
||||||
|
return targetDateDistance <= 0;
|
||||||
|
};
|
@ -26,6 +26,7 @@
|
|||||||
"@sentry/nextjs": "^8",
|
"@sentry/nextjs": "^8",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
|
"date-fns": "^3.6.0",
|
||||||
"dompurify": "^3.0.11",
|
"dompurify": "^3.0.11",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||||
import { computedFn } from "mobx-utils";
|
import { computedFn } from "mobx-utils";
|
||||||
|
// types
|
||||||
|
import { IStateLite } from "@plane/types";
|
||||||
// services
|
// services
|
||||||
import IssueService from "@/services/issue.service";
|
import IssueService from "@/services/issue.service";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IIssueState, IIssueLabel } from "@/types/issue";
|
import { IIssue, IIssueLabel } from "@/types/issue";
|
||||||
// store
|
// store
|
||||||
import { RootStore } from "./root.store";
|
import { RootStore } from "./root.store";
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ export interface IIssueStore {
|
|||||||
error: any;
|
error: any;
|
||||||
// observables
|
// observables
|
||||||
issues: IIssue[];
|
issues: IIssue[];
|
||||||
states: IIssueState[];
|
states: IStateLite[];
|
||||||
labels: IIssueLabel[];
|
labels: IIssueLabel[];
|
||||||
// filter observables
|
// filter observables
|
||||||
filteredStates: string[];
|
filteredStates: string[];
|
||||||
@ -29,7 +31,7 @@ export class IssueStore implements IIssueStore {
|
|||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
// observables
|
// observables
|
||||||
states: IIssueState[] = [];
|
states: IStateLite[] = [];
|
||||||
labels: IIssueLabel[] = [];
|
labels: IIssueLabel[] = [];
|
||||||
issues: IIssue[] = [];
|
issues: IIssue[] = [];
|
||||||
// filter observables
|
// filter observables
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { observable, makeObservable, computed } from "mobx";
|
import { observable, makeObservable, computed } from "mobx";
|
||||||
|
// types
|
||||||
|
import { IWorkspaceLite } from "@plane/types";
|
||||||
// store types
|
// store types
|
||||||
import { RootStore } from "@/store/root.store";
|
import { RootStore } from "@/store/root.store";
|
||||||
// types
|
// types
|
||||||
import { TProjectDetails, TViewDetails, TWorkspaceDetails } from "@/types/project";
|
import { TProjectDetails, TViewDetails } from "@/types/project";
|
||||||
import { TPublishEntityType, TPublishSettings } from "@/types/publish";
|
import { TPublishEntityType, TPublishSettings } from "@/types/publish";
|
||||||
|
|
||||||
export interface IPublishStore extends TPublishSettings {
|
export interface IPublishStore extends TPublishSettings {
|
||||||
@ -31,7 +33,7 @@ export class PublishStore implements IPublishStore {
|
|||||||
view_props: TViewDetails | undefined;
|
view_props: TViewDetails | undefined;
|
||||||
votes: boolean;
|
votes: boolean;
|
||||||
workspace: string | undefined;
|
workspace: string | undefined;
|
||||||
workspace_detail: TWorkspaceDetails | undefined;
|
workspace_detail: IWorkspaceLite | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private store: RootStore,
|
private store: RootStore,
|
||||||
|
68
space/types/issue.d.ts
vendored
68
space/types/issue.d.ts
vendored
@ -1,14 +1,19 @@
|
|||||||
|
import { IStateLite, IWorkspaceLite, TIssuePriorities } from "@plane/types";
|
||||||
|
|
||||||
export type TIssueLayout = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt";
|
export type TIssueLayout = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt";
|
||||||
export type TIssueLayoutOptions = {
|
export type TIssueLayoutOptions = {
|
||||||
[key in TIssueLayout]: boolean;
|
[key in TIssueLayout]: boolean;
|
||||||
};
|
};
|
||||||
export type TIssueLayoutViews = {
|
export type TIssueLayoutViews = {
|
||||||
[key in TIssueLayout]: { title: string; icon: string; className: string };
|
[key in TIssueLayout]: {
|
||||||
|
title: string;
|
||||||
|
icon: string;
|
||||||
|
className: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TIssueFilterPriority = "urgent" | "high" | "medium" | "low" | "none";
|
|
||||||
export type TIssueFilterPriorityObject = {
|
export type TIssueFilterPriorityObject = {
|
||||||
key: TIssueFilterPriority;
|
key: TIssuePriorities;
|
||||||
title: string;
|
title: string;
|
||||||
className: string;
|
className: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
@ -30,7 +35,7 @@ export type TDisplayFilters = {
|
|||||||
|
|
||||||
export type TFilters = {
|
export type TFilters = {
|
||||||
state: TIssueFilterState[];
|
state: TIssueFilterState[];
|
||||||
priority: TIssueFilterPriority[];
|
priority: TIssuePriorities[];
|
||||||
labels: string[];
|
labels: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,7 +49,7 @@ export type TIssueQueryFilters = Partial<TFilters>;
|
|||||||
export type TIssueQueryFiltersParams = Partial<Record<keyof TFilters, string>>;
|
export type TIssueQueryFiltersParams = Partial<Record<keyof TFilters, string>>;
|
||||||
|
|
||||||
export type TIssuesResponse = {
|
export type TIssuesResponse = {
|
||||||
states: IIssueState[];
|
states: IStateLite[];
|
||||||
labels: IIssueLabel[];
|
labels: IIssueLabel[];
|
||||||
issues: IIssue[];
|
issues: IIssue[];
|
||||||
};
|
};
|
||||||
@ -74,13 +79,6 @@ export interface IIssue {
|
|||||||
|
|
||||||
export type IPeekMode = "side" | "modal" | "full";
|
export type IPeekMode = "side" | "modal" | "full";
|
||||||
|
|
||||||
export interface IIssueState {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
group: TIssueGroupKey;
|
|
||||||
color: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IIssueLabel {
|
export interface IIssueLabel {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -121,7 +119,7 @@ export interface Comment {
|
|||||||
updated_at: Date;
|
updated_at: Date;
|
||||||
updated_by: string;
|
updated_by: string;
|
||||||
workspace: string;
|
workspace: string;
|
||||||
workspace_detail: WorkspaceDetail;
|
workspace_detail: IWorkspaceLite;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IIssueReaction {
|
export interface IIssueReaction {
|
||||||
@ -182,52 +180,8 @@ export interface ProjectDetail {
|
|||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceDetail {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IssueDetailType {
|
|
||||||
[issueId: string]: {
|
|
||||||
issue: IIssue;
|
|
||||||
comments: Comment[];
|
|
||||||
reactions: any[];
|
|
||||||
votes: any[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TIssueGroupByOptions = "state" | "priority" | "labels" | null;
|
|
||||||
|
|
||||||
export type TIssueParams = "priority" | "state" | "labels";
|
|
||||||
|
|
||||||
export interface IIssueFilterOptions {
|
export interface IIssueFilterOptions {
|
||||||
state?: string[] | null;
|
state?: string[] | null;
|
||||||
labels?: string[] | null;
|
labels?: string[] | null;
|
||||||
priority?: string[] | null;
|
priority?: string[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// issues
|
|
||||||
export interface IGroupedIssues {
|
|
||||||
[group_id: string]: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISubGroupedIssues {
|
|
||||||
[sub_grouped_id: string]: {
|
|
||||||
[group_id: string]: string[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TUnGroupedIssues = string[];
|
|
||||||
|
|
||||||
export interface IIssueResponse {
|
|
||||||
[issue_id: string]: IIssue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TLoader = "init-loader" | "mutation" | undefined;
|
|
||||||
|
|
||||||
export interface ViewFlags {
|
|
||||||
enableQuickAdd: boolean;
|
|
||||||
enableIssueCreation: boolean;
|
|
||||||
enableInlineEditing: boolean;
|
|
||||||
}
|
|
||||||
|
6
space/types/project.d.ts
vendored
6
space/types/project.d.ts
vendored
@ -1,11 +1,5 @@
|
|||||||
import { TLogoProps } from "@plane/types";
|
import { TLogoProps } from "@plane/types";
|
||||||
|
|
||||||
export type TWorkspaceDetails = {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TViewDetails = {
|
export type TViewDetails = {
|
||||||
list: boolean;
|
list: boolean;
|
||||||
gantt: boolean;
|
gantt: boolean;
|
||||||
|
5
space/types/publish.d.ts
vendored
5
space/types/publish.d.ts
vendored
@ -1,4 +1,5 @@
|
|||||||
import { TProjectDetails, TViewDetails, TWorkspaceDetails } from "./project";
|
import { IWorkspaceLite } from "@plane/types";
|
||||||
|
import { TProjectDetails, TViewDetails } from "./project";
|
||||||
|
|
||||||
export type TPublishEntityType = "project";
|
export type TPublishEntityType = "project";
|
||||||
|
|
||||||
@ -19,5 +20,5 @@ export type TPublishSettings = {
|
|||||||
view_props: TViewDetails | undefined;
|
view_props: TViewDetails | undefined;
|
||||||
votes: boolean;
|
votes: boolean;
|
||||||
workspace: string | undefined;
|
workspace: string | undefined;
|
||||||
workspace_detail: TWorkspaceDetails | undefined;
|
workspace_detail: IWorkspaceLite | undefined;
|
||||||
};
|
};
|
||||||
|
43
yarn.lock
43
yarn.lock
@ -6281,6 +6281,11 @@ date-fns@^2.30.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.21.0"
|
"@babel/runtime" "^7.21.0"
|
||||||
|
|
||||||
|
date-fns@^3.6.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf"
|
||||||
|
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==
|
||||||
|
|
||||||
debug@2.6.9:
|
debug@2.6.9:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
@ -10681,7 +10686,7 @@ prelude-ls@^1.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||||
|
|
||||||
"prettier-fallback@npm:prettier@^3":
|
"prettier-fallback@npm:prettier@^3", prettier@^3.1.1, prettier@^3.2.5, prettier@latest:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.0.tgz#d173ea0524a691d4c0b1181752f2b46724328cdf"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.0.tgz#d173ea0524a691d4c0b1181752f2b46724328cdf"
|
||||||
integrity sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==
|
integrity sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==
|
||||||
@ -10708,11 +10713,6 @@ prettier@^2.8.8:
|
|||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
|
||||||
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
|
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
|
||||||
|
|
||||||
prettier@^3.1.1, prettier@^3.2.5, prettier@latest:
|
|
||||||
version "3.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.0.tgz#d173ea0524a691d4c0b1181752f2b46724328cdf"
|
|
||||||
integrity sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==
|
|
||||||
|
|
||||||
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||||
@ -12112,16 +12112,7 @@ string-argv@~0.3.2:
|
|||||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
|
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
|
||||||
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
|
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0":
|
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
|
||||||
dependencies:
|
|
||||||
emoji-regex "^8.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
strip-ansi "^6.0.1"
|
|
||||||
|
|
||||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
@ -12217,14 +12208,7 @@ stringify-object@^3.3.0:
|
|||||||
is-obj "^1.0.1"
|
is-obj "^1.0.1"
|
||||||
is-regexp "^1.0.0"
|
is-regexp "^1.0.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
|
||||||
dependencies:
|
|
||||||
ansi-regex "^5.0.1"
|
|
||||||
|
|
||||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
@ -13648,16 +13632,7 @@ workbox-window@6.6.1, workbox-window@^6.5.4:
|
|||||||
"@types/trusted-types" "^2.0.2"
|
"@types/trusted-types" "^2.0.2"
|
||||||
workbox-core "6.6.1"
|
workbox-core "6.6.1"
|
||||||
|
|
||||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
string-width "^4.1.0"
|
|
||||||
strip-ansi "^6.0.0"
|
|
||||||
|
|
||||||
wrap-ansi@^7.0.0:
|
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
Loading…
Reference in New Issue
Block a user