forked from github/plane
Merge pull request #990 from makeplane/develop
promote: develop to stage-release
This commit is contained in:
commit
e5703dbe70
@ -59,7 +59,9 @@ def service_importer(service, importer_id):
|
|||||||
|
|
||||||
[
|
[
|
||||||
send_welcome_email.delay(
|
send_welcome_email.delay(
|
||||||
user, True, f"{user.email} was imported to Plane from {service}"
|
str(user.id),
|
||||||
|
True,
|
||||||
|
f"{user.email} was imported to Plane from {service}",
|
||||||
)
|
)
|
||||||
for user in new_users
|
for user in new_users
|
||||||
]
|
]
|
||||||
|
@ -10,9 +10,15 @@ from sentry_sdk import capture_exception
|
|||||||
from slack_sdk import WebClient
|
from slack_sdk import WebClient
|
||||||
from slack_sdk.errors import SlackApiError
|
from slack_sdk.errors import SlackApiError
|
||||||
|
|
||||||
|
# Module imports
|
||||||
|
from plane.db.models import User
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_welcome_email(instance, created, message):
|
def send_welcome_email(user_id, created, message):
|
||||||
try:
|
try:
|
||||||
|
instance = User.objects.get(pk=user_id)
|
||||||
|
|
||||||
if created and not instance.is_bot:
|
if created and not instance.is_bot:
|
||||||
first_name = instance.first_name.capitalize()
|
first_name = instance.first_name.capitalize()
|
||||||
to_email = instance.email
|
to_email = instance.email
|
||||||
|
@ -4,7 +4,7 @@ import { Dialog, Transition } from "@headlessui/react";
|
|||||||
// icons
|
// icons
|
||||||
import { XMarkIcon } from "@heroicons/react/20/solid";
|
import { XMarkIcon } from "@heroicons/react/20/solid";
|
||||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||||
import { MacCommandIcon } from "components/icons";
|
import { CommandIcon } from "components/icons";
|
||||||
// ui
|
// ui
|
||||||
import { Input } from "components/ui";
|
import { Input } from "components/ui";
|
||||||
|
|
||||||
@ -123,17 +123,23 @@ export const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
|
|||||||
<div key={shortcut.keys} className="flex w-full flex-col">
|
<div key={shortcut.keys} className="flex w-full flex-col">
|
||||||
<div className="flex flex-col gap-y-3">
|
<div className="flex flex-col gap-y-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="text-sm text-brand-secondary">{shortcut.description}</p>
|
<p className="text-sm text-brand-secondary">
|
||||||
|
{shortcut.description}
|
||||||
|
</p>
|
||||||
<div className="flex items-center gap-x-2.5">
|
<div className="flex items-center gap-x-2.5">
|
||||||
{shortcut.keys.split(",").map((key, index) => (
|
{shortcut.keys.split(",").map((key, index) => (
|
||||||
<span key={index} className="flex items-center gap-1">
|
<span key={index} className="flex items-center gap-1">
|
||||||
{key === "Ctrl" ? (
|
{key === "Ctrl" ? (
|
||||||
<span className="flex h-full items-center rounded-sm border border-brand-base bg-brand-surface-1 p-2">
|
<span className="flex h-full items-center rounded-sm border border-brand-base bg-brand-surface-1 p-1.5">
|
||||||
<MacCommandIcon />
|
<CommandIcon className="h-4 w-4 fill-current text-brand-secondary" />
|
||||||
</span>
|
</span>
|
||||||
|
) : key === "Ctrl" ? (
|
||||||
|
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 p-1.5 text-sm font-medium text-brand-secondary">
|
||||||
|
<CommandIcon className="h-4 w-4 fill-current text-brand-secondary" />
|
||||||
|
</kbd>
|
||||||
) : (
|
) : (
|
||||||
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 px-2 py-1 text-sm font-medium text-gray-800">
|
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 px-2 py-1 text-sm font-medium text-brand-secondary">
|
||||||
{key === "Ctrl" ? <MacCommandIcon /> : key}
|
{key}
|
||||||
</kbd>
|
</kbd>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@ -167,12 +173,16 @@ export const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
|
|||||||
{keys.split(",").map((key, index) => (
|
{keys.split(",").map((key, index) => (
|
||||||
<span key={index} className="flex items-center gap-1">
|
<span key={index} className="flex items-center gap-1">
|
||||||
{key === "Ctrl" ? (
|
{key === "Ctrl" ? (
|
||||||
<span className="flex h-full items-center rounded-sm border border-brand-base text-brand-secondary bg-brand-surface-1 p-2">
|
<span className="flex h-full items-center rounded-sm border border-brand-base bg-brand-surface-1 p-1.5 text-brand-secondary">
|
||||||
<MacCommandIcon />
|
<CommandIcon className="h-4 w-4 fill-current text-brand-secondary" />
|
||||||
</span>
|
</span>
|
||||||
|
) : key === "Ctrl" ? (
|
||||||
|
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 p-1.5 text-sm font-medium text-brand-secondary">
|
||||||
|
<CommandIcon className="h-4 w-4 fill-current text-brand-secondary" />
|
||||||
|
</kbd>
|
||||||
) : (
|
) : (
|
||||||
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 px-2 py-1 text-sm font-medium text-brand-secondary">
|
<kbd className="rounded-sm border border-brand-base bg-brand-surface-1 px-2 py-1 text-sm font-medium text-brand-secondary">
|
||||||
{key === "Ctrl" ? <MacCommandIcon /> : key}
|
{key}
|
||||||
</kbd>
|
</kbd>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -391,8 +391,8 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
{properties.link && (
|
{properties.link && (
|
||||||
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
||||||
<Tooltip tooltipHeading="Link" tooltipContent={`${issue.link_count}`}>
|
<Tooltip tooltipHeading="Link" tooltipContent={`${issue.link_count}`}>
|
||||||
<div className="flex items-center gap-1 text-gray-500">
|
<div className="flex items-center gap-1 text-brand-secondary">
|
||||||
<LinkIcon className="h-3.5 w-3.5 text-gray-500" />
|
<LinkIcon className="h-3.5 w-3.5 text-brand-secondary" />
|
||||||
{issue.link_count}
|
{issue.link_count}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -401,8 +401,8 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
{properties.attachment_count && (
|
{properties.attachment_count && (
|
||||||
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
||||||
<Tooltip tooltipHeading="Attachment" tooltipContent={`${issue.attachment_count}`}>
|
<Tooltip tooltipHeading="Attachment" tooltipContent={`${issue.attachment_count}`}>
|
||||||
<div className="flex items-center gap-1 text-gray-500">
|
<div className="flex items-center gap-1 text-brand-secondary">
|
||||||
<PaperClipIcon className="h-3.5 w-3.5 -rotate-45 text-gray-500" />
|
<PaperClipIcon className="h-3.5 w-3.5 -rotate-45 text-brand-secondary" />
|
||||||
{issue.attachment_count}
|
{issue.attachment_count}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -160,7 +160,7 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
Select issues to add
|
Select issues to add
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
<ul className="text-sm text-gray-700">
|
<ul className="text-sm text-brand-base">
|
||||||
{filteredIssues.map((issue) => (
|
{filteredIssues.map((issue) => (
|
||||||
<Combobox.Option
|
<Combobox.Option
|
||||||
key={issue.id}
|
key={issue.id}
|
||||||
|
@ -246,7 +246,7 @@ export const IssuesFilterView: React.FC = () => {
|
|||||||
type="button"
|
type="button"
|
||||||
className={`rounded border px-2 py-1 text-xs capitalize ${
|
className={`rounded border px-2 py-1 text-xs capitalize ${
|
||||||
properties[key as keyof Properties]
|
properties[key as keyof Properties]
|
||||||
? "border-brand-accent bg-brand-accent text-brand-base"
|
? "border-brand-accent bg-brand-accent text-white"
|
||||||
: "border-brand-base"
|
: "border-brand-base"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setProperties(key as keyof Properties)}
|
onClick={() => setProperties(key as keyof Properties)}
|
||||||
|
@ -313,8 +313,8 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
{properties.link && (
|
{properties.link && (
|
||||||
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
||||||
<Tooltip tooltipHeading="Links" tooltipContent={`${issue.link_count}`}>
|
<Tooltip tooltipHeading="Links" tooltipContent={`${issue.link_count}`}>
|
||||||
<div className="flex items-center gap-1 text-gray-500">
|
<div className="flex items-center gap-1 text-brand-secondary">
|
||||||
<LinkIcon className="h-3.5 w-3.5 text-gray-500" />
|
<LinkIcon className="h-3.5 w-3.5 text-brand-secondary" />
|
||||||
{issue.link_count}
|
{issue.link_count}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -323,8 +323,8 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
{properties.attachment_count && (
|
{properties.attachment_count && (
|
||||||
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
<div className="flex cursor-default items-center rounded-md border border-brand-base px-2.5 py-1 text-xs shadow-sm">
|
||||||
<Tooltip tooltipHeading="Attachments" tooltipContent={`${issue.attachment_count}`}>
|
<Tooltip tooltipHeading="Attachments" tooltipContent={`${issue.attachment_count}`}>
|
||||||
<div className="flex items-center gap-1 text-gray-500">
|
<div className="flex items-center gap-1 text-brand-secondary">
|
||||||
<PaperClipIcon className="h-3.5 w-3.5 -rotate-45 text-gray-500" />
|
<PaperClipIcon className="h-3.5 w-3.5 -rotate-45 text-brand-secondary" />
|
||||||
{issue.attachment_count}
|
{issue.attachment_count}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -106,30 +106,30 @@ export const TransferIssuesModal: React.FC<Props> = ({ isOpen, handleClose }) =>
|
|||||||
<Dialog.Panel className="relative transform rounded-lg bg-brand-surface-1 py-5 text-left shadow-xl transition-all sm:w-full sm:max-w-2xl">
|
<Dialog.Panel className="relative transform rounded-lg bg-brand-surface-1 py-5 text-left shadow-xl transition-all sm:w-full sm:max-w-2xl">
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex items-center justify-between px-5">
|
<div className="flex items-center justify-between px-5">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-3">
|
||||||
<TransferIcon className="h-4 w-5" color="#495057" />
|
<TransferIcon className="h-4 w-5" color="#495057" />
|
||||||
<h4 className="text-gray-700 font-medium text-[1.50rem]">Transfer Issues</h4>
|
<h4 className="text-xl font-medium text-brand-base">Transfer Issues</h4>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={handleClose}>
|
<button onClick={handleClose}>
|
||||||
<XMarkIcon className="h-4 w-4" />
|
<XMarkIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 pb-3 px-5 border-b border-brand-base">
|
<div className="flex items-center gap-2 border-b border-brand-base px-5 pb-3">
|
||||||
<MagnifyingGlassIcon className="h-4 w-4 text-brand-secondary" />
|
<MagnifyingGlassIcon className="h-4 w-4 text-brand-secondary" />
|
||||||
<input
|
<input
|
||||||
className="outline-none"
|
className="bg-brand-surface-1 outline-none"
|
||||||
placeholder="Search for a cycle..."
|
placeholder="Search for a cycle..."
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
value={query}
|
value={query}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-start w-full gap-2 px-5">
|
<div className="flex w-full flex-col items-start gap-2 px-5">
|
||||||
{filteredOptions ? (
|
{filteredOptions ? (
|
||||||
filteredOptions.length > 0 ? (
|
filteredOptions.length > 0 ? (
|
||||||
filteredOptions.map((option: ICycle) => (
|
filteredOptions.map((option: ICycle) => (
|
||||||
<button
|
<button
|
||||||
key={option.id}
|
key={option.id}
|
||||||
className="flex items-center gap-4 px-4 py-3 text-gray-600 text-sm rounded w-full hover:bg-brand-surface-1"
|
className="flex w-full items-center gap-4 rounded px-4 py-3 text-sm text-brand-secondary hover:bg-brand-surface-1"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
transferIssue({
|
transferIssue({
|
||||||
new_cycle_id: option?.id,
|
new_cycle_id: option?.id,
|
||||||
@ -138,16 +138,16 @@ export const TransferIssuesModal: React.FC<Props> = ({ isOpen, handleClose }) =>
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ContrastIcon className="h-5 w-5" />
|
<ContrastIcon className="h-5 w-5" />
|
||||||
<div className="flex justify-between w-full">
|
<div className="flex w-full justify-between">
|
||||||
<span>{option?.name}</span>
|
<span>{option?.name}</span>
|
||||||
<span className=" flex bg-gray-200 capitalize px-2 rounded-full items-center">
|
<span className=" flex items-center rounded-full bg-brand-surface-2 px-2 capitalize">
|
||||||
{getDateRangeStatus(option?.start_date, option?.end_date)}
|
{getDateRangeStatus(option?.start_date, option?.end_date)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-center gap-4 p-5 text-sm w-full">
|
<div className="flex w-full items-center justify-center gap-4 p-5 text-sm">
|
||||||
<ExclamationIcon height={14} width={14} />
|
<ExclamationIcon height={14} width={14} />
|
||||||
<span className="text-center text-brand-secondary">
|
<span className="text-center text-brand-secondary">
|
||||||
You don’t have any current cycle. Please create one to transfer the
|
You don’t have any current cycle. Please create one to transfer the
|
||||||
|
@ -37,7 +37,7 @@ export const TransferIssues: React.FC<Props> = ({ handleClick }) => {
|
|||||||
? cycleDetails.backlog_issues + cycleDetails.unstarted_issues + cycleDetails.started_issues
|
? cycleDetails.backlog_issues + cycleDetails.unstarted_issues + cycleDetails.started_issues
|
||||||
: 0;
|
: 0;
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between -mt-4 mb-4">
|
<div className="-mt-2 mb-4 flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2 text-sm text-brand-secondary">
|
<div className="flex items-center gap-2 text-sm text-brand-secondary">
|
||||||
<ExclamationIcon height={14} width={14} />
|
<ExclamationIcon height={14} width={14} />
|
||||||
<span>Completed cycles are not editable.</span>
|
<span>Completed cycles are not editable.</span>
|
||||||
@ -46,7 +46,7 @@ export const TransferIssues: React.FC<Props> = ({ handleClick }) => {
|
|||||||
{transferableIssuesCount > 0 && (
|
{transferableIssuesCount > 0 && (
|
||||||
<div>
|
<div>
|
||||||
<PrimaryButton onClick={handleClick} className="flex items-center gap-3 rounded-lg">
|
<PrimaryButton onClick={handleClick} className="flex items-center gap-3 rounded-lg">
|
||||||
<TransferIcon className="h-4 w-4" color="white"/>
|
<TransferIcon className="h-4 w-4" color="white" />
|
||||||
<span className="text-white">Transfer Issues</span>
|
<span className="text-white">Transfer Issues</span>
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,7 +46,7 @@ export const DeleteEstimateModal: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-50 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||||
@ -60,10 +60,10 @@ export const DeleteEstimateModal: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
<Dialog.Panel className="relative transform overflow-hidden rounded-lg border border-brand-base bg-brand-base text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
||||||
<div className="flex flex-col gap-6 p-6">
|
<div className="flex flex-col gap-6 p-6">
|
||||||
<div className="flex w-full items-center justify-start gap-6">
|
<div className="flex w-full items-center justify-start gap-6">
|
||||||
<span className="place-items-center rounded-full bg-red-100 p-4">
|
<span className="place-items-center rounded-full bg-red-500/20 p-4">
|
||||||
<ExclamationTriangleIcon
|
<ExclamationTriangleIcon
|
||||||
className="h-6 w-6 text-red-600"
|
className="h-6 w-6 text-red-600"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -74,9 +74,9 @@ export const DeleteEstimateModal: React.FC<Props> = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<p className="break-all text-sm leading-7 text-gray-500">
|
<p className="break-all text-sm leading-7 text-brand-secondary">
|
||||||
Are you sure you want to delete estimate-{" "}
|
Are you sure you want to delete estimate-{" "}
|
||||||
<span className="break-all font-semibold">{data.name}</span>
|
<span className="break-all font-medium text-brand-base">{data.name}</span>
|
||||||
{""}? All of the data related to the estiamte will be permanently removed.
|
{""}? All of the data related to the estiamte will be permanently removed.
|
||||||
This action cannot be undone.
|
This action cannot be undone.
|
||||||
</p>
|
</p>
|
||||||
|
21
apps/app/components/icons/command-icon.tsx
Normal file
21
apps/app/components/icons/command-icon.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import type { Props } from "./types";
|
||||||
|
|
||||||
|
export const CommandIcon: React.FC<Props> = ({
|
||||||
|
width = "81",
|
||||||
|
height = "80",
|
||||||
|
color = "#858E96",
|
||||||
|
className,
|
||||||
|
}) => (
|
||||||
|
<svg
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
className={className}
|
||||||
|
viewBox="0 0 81 80"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="M21.4577 69.8924C18.4684 69.8924 15.922 68.8406 13.8184 66.737C11.7149 64.6335 10.6631 62.087 10.6631 59.0978C10.6631 56.1085 11.7149 53.562 13.8184 51.4585C15.922 49.3549 18.4684 48.3031 21.4577 48.3031H27.2702V31.696H21.4577C18.4684 31.696 15.922 30.6442 13.8184 28.5406C11.7149 26.437 10.6631 23.8906 10.6631 20.9013C10.6631 17.912 11.7149 15.3656 13.8184 13.262C15.922 11.1585 18.4684 10.1067 21.4577 10.1067C24.447 10.1067 26.9934 11.1585 29.097 13.262C31.2006 15.3656 32.2524 17.912 32.2524 20.9013V26.7138H48.8595V20.9013C48.8595 17.912 49.9113 15.3656 52.0149 13.262C54.1184 11.1585 56.6649 10.1067 59.6542 10.1067C62.6434 10.1067 65.1899 11.1585 67.2934 13.262C69.397 15.3656 70.4488 17.912 70.4488 20.9013C70.4488 23.8906 69.397 26.437 67.2934 28.5406C65.1899 30.6442 62.6434 31.696 59.6542 31.696H53.8417V48.3031H59.6542C62.6434 48.3031 65.1899 49.3549 67.2934 51.4585C69.397 53.562 70.4488 56.1085 70.4488 59.0978C70.4488 62.087 69.397 64.6335 67.2934 66.737C65.1899 68.8406 62.6434 69.8924 59.6542 69.8924C56.6649 69.8924 54.1184 68.8406 52.0149 66.737C49.9113 64.6335 48.8595 62.087 48.8595 59.0978V53.2853H32.2524V59.0978C32.2524 62.087 31.2006 64.6335 29.097 66.737C26.9934 68.8406 24.447 69.8924 21.4577 69.8924ZM21.4577 64.9103C23.0631 64.9103 24.4332 64.3428 25.568 63.208C26.7028 62.0732 27.2702 60.7031 27.2702 59.0978V53.2853H21.4577C19.8524 53.2853 18.4823 53.8527 17.3475 54.9875C16.2126 56.1223 15.6452 57.4924 15.6452 59.0978C15.6452 60.7031 16.2126 62.0732 17.3475 63.208C18.4823 64.3428 19.8524 64.9103 21.4577 64.9103ZM59.6542 64.9103C61.2595 64.9103 62.6296 64.3428 63.7644 63.208C64.8992 62.0732 65.4667 60.7031 65.4667 59.0978C65.4667 57.4924 64.8992 56.1223 63.7644 54.9875C62.6296 53.8527 61.2595 53.2853 59.6542 53.2853H53.8417V59.0978C53.8417 60.7031 54.4091 62.0732 55.5439 63.208C56.6787 64.3428 58.0488 64.9103 59.6542 64.9103ZM32.2524 48.3031H48.8595V31.696H32.2524V48.3031ZM21.4577 26.7138H27.2702V20.9013C27.2702 19.296 26.7028 17.9259 25.568 16.7911C24.4332 15.6562 23.0631 15.0888 21.4577 15.0888C19.8524 15.0888 18.4823 15.6562 17.3475 16.7911C16.2126 17.9259 15.6452 19.296 15.6452 20.9013C15.6452 22.5067 16.2126 23.8768 17.3475 25.0116C18.4823 26.1464 19.8524 26.7138 21.4577 26.7138ZM53.8417 26.7138H59.6542C61.2595 26.7138 62.6296 26.1464 63.7644 25.0116C64.8992 23.8768 65.4667 22.5067 65.4667 20.9013C65.4667 19.296 64.8992 17.9259 63.7644 16.7911C62.6296 15.6562 61.2595 15.0888 59.6542 15.0888C58.0488 15.0888 56.6787 15.6562 55.5439 16.7911C54.4091 17.9259 53.8417 19.296 53.8417 20.9013V26.7138Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
@ -43,7 +43,7 @@ export * from "./user-icon";
|
|||||||
export * from "./grid-view-icons";
|
export * from "./grid-view-icons";
|
||||||
export * from "./assignment-clipboard-icon";
|
export * from "./assignment-clipboard-icon";
|
||||||
export * from "./tick-mark-icon";
|
export * from "./tick-mark-icon";
|
||||||
export * from "./target-icon"
|
export * from "./target-icon";
|
||||||
export * from "./contrast-icon";
|
export * from "./contrast-icon";
|
||||||
export * from "./people-group-icon";
|
export * from "./people-group-icon";
|
||||||
export * from "./cmd-icon";
|
export * from "./cmd-icon";
|
||||||
@ -72,4 +72,5 @@ export * from "./svg-file-icon";
|
|||||||
export * from "./txt-file-icon";
|
export * from "./txt-file-icon";
|
||||||
export * from "./default-file-icon";
|
export * from "./default-file-icon";
|
||||||
export * from "./video-file-icon";
|
export * from "./video-file-icon";
|
||||||
export * from "./audio-file-icon";
|
export * from "./audio-file-icon";
|
||||||
|
export * from "./command-icon";
|
||||||
|
@ -11,7 +11,7 @@ import { CustomSearchSelect } from "components/ui";
|
|||||||
// helpers
|
// helpers
|
||||||
import { truncateText } from "helpers/string.helper";
|
import { truncateText } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IWorkspaceIntegration } from "types";
|
import { IWorkspaceIntegration, IGithubRepository } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
integration: IWorkspaceIntegration;
|
integration: IWorkspaceIntegration;
|
||||||
@ -54,7 +54,9 @@ export const SelectRepository: React.FC<Props> = ({
|
|||||||
isValidating,
|
isValidating,
|
||||||
} = useSWRInfinite(getKey, fetchGithubRepos);
|
} = useSWRInfinite(getKey, fetchGithubRepos);
|
||||||
|
|
||||||
const userRepositories = (paginatedData ?? []).map((data) => data.repositories).flat();
|
let userRepositories = (paginatedData ?? []).map((data) => data.repositories).flat();
|
||||||
|
userRepositories = userRepositories.filter((data) => data?.id);
|
||||||
|
|
||||||
const totalCount = paginatedData && paginatedData.length > 0 ? paginatedData[0].total_count : 0;
|
const totalCount = paginatedData && paginatedData.length > 0 ? paginatedData[0].total_count : 0;
|
||||||
|
|
||||||
const options =
|
const options =
|
||||||
|
@ -34,7 +34,7 @@ export const IssueAttachments = () => {
|
|||||||
workspaceSlug && projectId && issueId ? ISSUE_ATTACHMENTS(issueId as string) : null,
|
workspaceSlug && projectId && issueId ? ISSUE_ATTACHMENTS(issueId as string) : null,
|
||||||
workspaceSlug && projectId && issueId
|
workspaceSlug && projectId && issueId
|
||||||
? () =>
|
? () =>
|
||||||
issuesService.getIssueAttachment(
|
issuesService.getIssueAttachment(
|
||||||
workspaceSlug as string,
|
workspaceSlug as string,
|
||||||
projectId as string,
|
projectId as string,
|
||||||
issueId as string
|
issueId as string
|
||||||
@ -61,7 +61,7 @@ export const IssueAttachments = () => {
|
|||||||
attachments.map((file) => (
|
attachments.map((file) => (
|
||||||
<div
|
<div
|
||||||
key={file.id}
|
key={file.id}
|
||||||
className="flex items-center justify-between h-[60px] gap-1 px-4 py-2 text-sm border border-gray-200 bg-white rounded-md"
|
className="flex h-[60px] items-center justify-between gap-1 rounded-md border-[2px] border-brand-surface-2 bg-brand-base px-4 py-2 text-sm"
|
||||||
>
|
>
|
||||||
<Link href={file.asset}>
|
<Link href={file.asset}>
|
||||||
<a target="_blank">
|
<a target="_blank">
|
||||||
@ -87,7 +87,7 @@ export const IssueAttachments = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-3 text-gray-500 text-xs">
|
<div className="flex items-center gap-3 text-xs text-gray-500">
|
||||||
<span>{getFileExtension(file.asset).toUpperCase()}</span>
|
<span>{getFileExtension(file.asset).toUpperCase()}</span>
|
||||||
<span>{convertBytesToSize(file.attributes.size)}</span>
|
<span>{convertBytesToSize(file.attributes.size)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,7 +75,7 @@ export const DeleteAttachmentModal: React.FC<Props> = ({ isOpen, setIsOpen, data
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-75 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||||
@ -89,8 +89,8 @@ export const DeleteAttachmentModal: React.FC<Props> = ({ isOpen, setIsOpen, data
|
|||||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-[40rem]">
|
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-brand-surface-2 text-left shadow-xl transition-all sm:my-8 sm:w-[40rem]">
|
||||||
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
<div className="bg-brand-surface-2 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||||
<div className="sm:flex sm:items-start">
|
<div className="sm:flex sm:items-start">
|
||||||
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||||
<ExclamationTriangleIcon
|
<ExclamationTriangleIcon
|
||||||
@ -101,12 +101,12 @@ export const DeleteAttachmentModal: React.FC<Props> = ({ isOpen, setIsOpen, data
|
|||||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||||
<Dialog.Title
|
<Dialog.Title
|
||||||
as="h3"
|
as="h3"
|
||||||
className="text-lg font-medium leading-6 text-gray-900"
|
className="text-lg font-medium leading-6 text-brand-base"
|
||||||
>
|
>
|
||||||
Delete Attachment
|
Delete Attachment
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-brand-secondary">
|
||||||
Are you sure you want to delete attachment-{" "}
|
Are you sure you want to delete attachment-{" "}
|
||||||
<span className="font-bold">{getFileName(data.attributes.name)}</span>?
|
<span className="font-bold">{getFileName(data.attributes.name)}</span>?
|
||||||
This attachment will be permanently removed. This action cannot be
|
This attachment will be permanently removed. This action cannot be
|
||||||
@ -116,7 +116,7 @@ export const DeleteAttachmentModal: React.FC<Props> = ({ isOpen, setIsOpen, data
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
<div className="flex justify-end gap-2 bg-brand-surface-1 p-4 sm:px-6">
|
||||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||||
<DangerButton
|
<DangerButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -163,7 +163,7 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-25 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-50 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||||
@ -176,7 +176,7 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100 scale-100"
|
leaveFrom="opacity-100 scale-100"
|
||||||
leaveTo="opacity-0 scale-95"
|
leaveTo="opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-10 rounded-xl bg-brand-surface-2 bg-opacity-80 shadow-2xl ring-1 ring-black ring-opacity-5 backdrop-blur backdrop-filter transition-all">
|
<Dialog.Panel className="relative mx-auto max-w-2xl transform rounded-xl border border-brand-base bg-brand-base shadow-2xl transition-all">
|
||||||
<form>
|
<form>
|
||||||
<Combobox
|
<Combobox
|
||||||
onChange={(val: string) => {
|
onChange={(val: string) => {
|
||||||
@ -204,7 +204,7 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
|
|
||||||
<Combobox.Options
|
<Combobox.Options
|
||||||
static
|
static
|
||||||
className="max-h-80 scroll-py-2 divide-y divide-gray-500 divide-opacity-10 overflow-y-auto"
|
className="max-h-80 scroll-py-2 divide-y divide-brand-base overflow-y-auto"
|
||||||
>
|
>
|
||||||
{filteredIssues.length > 0 ? (
|
{filteredIssues.length > 0 ? (
|
||||||
<li className="p-2">
|
<li className="p-2">
|
||||||
@ -213,7 +213,7 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
Select blocked issues
|
Select blocked issues
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
<ul className="text-sm text-gray-700">
|
<ul className="text-sm text-brand-base">
|
||||||
{filteredIssues.map((issue) => {
|
{filteredIssues.map((issue) => {
|
||||||
if (
|
if (
|
||||||
!watch("blocked_list").includes(issue.id) &&
|
!watch("blocked_list").includes(issue.id) &&
|
||||||
@ -225,8 +225,8 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
as="div"
|
as="div"
|
||||||
value={issue.id}
|
value={issue.id}
|
||||||
className={({ active }) =>
|
className={({ active }) =>
|
||||||
`flex cursor-pointer select-none items-center justify-between rounded-md px-3 py-2 ${
|
`flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 text-brand-secondary ${
|
||||||
active ? "bg-gray-900 bg-opacity-5 text-brand-base" : ""
|
active ? "bg-brand-surface-2 text-brand-base" : ""
|
||||||
}`
|
}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -262,7 +262,7 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center gap-4 px-3 py-8 text-center">
|
<div className="flex flex-col items-center justify-center gap-4 px-3 py-8 text-center">
|
||||||
<LayerDiagonalIcon height="56" width="56" />
|
<LayerDiagonalIcon height="56" width="56" />
|
||||||
<h3 className="text-brand-secondary">
|
<h3 className="text-sm text-brand-secondary">
|
||||||
No issues found. Create a new issue with{" "}
|
No issues found. Create a new issue with{" "}
|
||||||
<pre className="inline rounded bg-brand-surface-2 px-2 py-1">C</pre>.
|
<pre className="inline rounded bg-brand-surface-2 px-2 py-1">C</pre>.
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -163,7 +163,7 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-25 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-50 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||||
@ -176,7 +176,7 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
leaveFrom="opacity-100 scale-100"
|
leaveFrom="opacity-100 scale-100"
|
||||||
leaveTo="opacity-0 scale-95"
|
leaveTo="opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-10 rounded-xl bg-brand-surface-2 bg-opacity-80 shadow-2xl ring-1 ring-black ring-opacity-5 backdrop-blur backdrop-filter transition-all">
|
<Dialog.Panel className="relative mx-auto max-w-2xl transform rounded-xl border border-brand-base bg-brand-base shadow-2xl transition-all">
|
||||||
<Combobox
|
<Combobox
|
||||||
onChange={(val: string) => {
|
onChange={(val: string) => {
|
||||||
const selectedIssues = watchBlocker("blocker_issue_ids");
|
const selectedIssues = watchBlocker("blocker_issue_ids");
|
||||||
@ -203,7 +203,7 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
|
|
||||||
<Combobox.Options
|
<Combobox.Options
|
||||||
static
|
static
|
||||||
className="max-h-80 scroll-py-2 divide-y divide-gray-500 divide-opacity-10 overflow-y-auto"
|
className="max-h-80 scroll-py-2 divide-y divide-brand-base overflow-y-auto"
|
||||||
>
|
>
|
||||||
{filteredIssues.length > 0 ? (
|
{filteredIssues.length > 0 ? (
|
||||||
<li className="p-2">
|
<li className="p-2">
|
||||||
@ -212,7 +212,7 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
Select blocker issues
|
Select blocker issues
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
<ul className="text-sm text-gray-700">
|
<ul className="text-sm text-brand-base">
|
||||||
{filteredIssues.map((issue) => {
|
{filteredIssues.map((issue) => {
|
||||||
if (
|
if (
|
||||||
!watch("blockers_list").includes(issue.id) &&
|
!watch("blockers_list").includes(issue.id) &&
|
||||||
@ -224,9 +224,9 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
as="div"
|
as="div"
|
||||||
value={issue.id}
|
value={issue.id}
|
||||||
className={({ active }) =>
|
className={({ active }) =>
|
||||||
`flex cursor-pointer select-none items-center justify-between rounded-md px-3 py-2 ${
|
`flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 text-brand-secondary ${
|
||||||
active ? "bg-gray-900 bg-opacity-5 text-brand-base" : ""
|
active ? "bg-brand-surface-2 text-brand-base" : ""
|
||||||
}`
|
} `
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@ -260,7 +260,7 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center gap-4 px-3 py-8 text-center">
|
<div className="flex flex-col items-center justify-center gap-4 px-3 py-8 text-center">
|
||||||
<LayerDiagonalIcon height="56" width="56" />
|
<LayerDiagonalIcon height="56" width="56" />
|
||||||
<h3 className="text-brand-secondary">
|
<h3 className="text-sm text-brand-secondary">
|
||||||
No issues found. Create a new issue with{" "}
|
No issues found. Create a new issue with{" "}
|
||||||
<pre className="inline rounded bg-brand-surface-2 px-2 py-1">C</pre>.
|
<pre className="inline rounded bg-brand-surface-2 px-2 py-1">C</pre>.
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -213,13 +213,13 @@ export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
|
|||||||
<Disclosure.Button className="flex items-center gap-1 rounded px-2 py-1 text-xs font-medium hover:bg-brand-surface-1">
|
<Disclosure.Button className="flex items-center gap-1 rounded px-2 py-1 text-xs font-medium hover:bg-brand-surface-1">
|
||||||
<ChevronRightIcon className={`h-3 w-3 ${open ? "rotate-90" : ""}`} />
|
<ChevronRightIcon className={`h-3 w-3 ${open ? "rotate-90" : ""}`} />
|
||||||
Sub-issues{" "}
|
Sub-issues{" "}
|
||||||
<span className="ml-1 text-gray-600">
|
<span className="ml-1 text-brand-secondary">
|
||||||
{subIssuesResponse.sub_issues.length}
|
{subIssuesResponse.sub_issues.length}
|
||||||
</span>
|
</span>
|
||||||
</Disclosure.Button>
|
</Disclosure.Button>
|
||||||
{subIssuesResponse.state_distribution && (
|
{subIssuesResponse.state_distribution && (
|
||||||
<div className="flex w-60 items-center gap-2 text-gray-800">
|
<div className="flex w-60 items-center gap-2 text-brand-base">
|
||||||
<div className="bar relative h-1.5 w-full rounded bg-gray-300">
|
<div className="bar relative h-1.5 w-full rounded bg-brand-surface-2">
|
||||||
<div
|
<div
|
||||||
className="absolute top-0 left-0 h-1.5 rounded bg-green-500 duration-300"
|
className="absolute top-0 left-0 h-1.5 rounded bg-green-500 duration-300"
|
||||||
style={{
|
style={{
|
||||||
@ -286,7 +286,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
|
|||||||
backgroundColor: issue.state_detail.color,
|
backgroundColor: issue.state_detail.color,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span className="flex-shrink-0 text-gray-600">
|
<span className="flex-shrink-0 text-brand-secondary">
|
||||||
{issue.project_detail.identifier}-{issue.sequence_id}
|
{issue.project_detail.identifier}-{issue.sequence_id}
|
||||||
</span>
|
</span>
|
||||||
<span className="max-w-sm break-all font-medium">{issue.name}</span>
|
<span className="max-w-sm break-all font-medium">{issue.name}</span>
|
||||||
|
@ -76,7 +76,7 @@ export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent }
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-25 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-50 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
<div className="fixed inset-0 z-20 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||||
@ -89,7 +89,7 @@ export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent }
|
|||||||
leaveFrom="opacity-100 scale-100"
|
leaveFrom="opacity-100 scale-100"
|
||||||
leaveTo="opacity-0 scale-95"
|
leaveTo="opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-10 rounded-xl bg-brand-surface-2 shadow-2xl ring-1 ring-black ring-opacity-5 transition-all">
|
<Dialog.Panel className="relative mx-auto max-w-2xl transform rounded-xl border border-brand-base bg-brand-base shadow-2xl transition-all">
|
||||||
<Combobox>
|
<Combobox>
|
||||||
<div className="relative m-1">
|
<div className="relative m-1">
|
||||||
<MagnifyingGlassIcon
|
<MagnifyingGlassIcon
|
||||||
@ -131,8 +131,8 @@ export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent }
|
|||||||
name: label.name,
|
name: label.name,
|
||||||
}}
|
}}
|
||||||
className={({ active }) =>
|
className={({ active }) =>
|
||||||
`flex cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 ${
|
`flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 text-brand-secondary ${
|
||||||
active ? "bg-gray-900 bg-opacity-5 text-brand-base" : ""
|
active ? "bg-brand-surface-2 text-brand-base" : ""
|
||||||
}`
|
}`
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -10,7 +10,7 @@ import projectServices from "services/project.service";
|
|||||||
// ui
|
// ui
|
||||||
import { Avatar, CustomSearchSelect } from "components/ui";
|
import { Avatar, CustomSearchSelect } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
import User from "public/user.png";
|
import { UserCircleIcon } from "@heroicons/react/24/outline";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_MEMBERS } from "constants/fetch-keys";
|
import { PROJECT_MEMBERS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -60,9 +60,7 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
|
|||||||
{selectedOption ? (
|
{selectedOption ? (
|
||||||
<Avatar user={selectedOption} />
|
<Avatar user={selectedOption} />
|
||||||
) : (
|
) : (
|
||||||
<div className="h-4 w-4 rounded-full bg-brand-surface-2">
|
<UserCircleIcon className="h-4 w-4 text-brand-secondary" />
|
||||||
<Image src={User} height="100%" width="100%" className="rounded-full" alt="No user" />
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
{selectedOption ? (
|
{selectedOption ? (
|
||||||
selectedOption?.first_name && selectedOption.first_name !== "" ? (
|
selectedOption?.first_name && selectedOption.first_name !== "" ? (
|
||||||
|
@ -43,7 +43,7 @@ export const ModuleStatusSelect: React.FC<Props> = ({ control, error }) => (
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{MODULE_STATUS.find((s) => s.value === value)?.label ?? (
|
{MODULE_STATUS.find((s) => s.value === value)?.label ?? (
|
||||||
<span className="text-brand-secondary">Status</span>
|
<span className={`${error ? "text-red-500" : "text-brand-secondary"}`}>Status</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export * from "./invite-members";
|
export * from "./invite-members";
|
||||||
export * from "./onboarding-card";
|
export * from "./onboarding-card";
|
||||||
export * from "./user-details";
|
export * from "./user-details";
|
||||||
export * from "./workspace";
|
export * from "./workspace";
|
||||||
|
export * from "./onboarding-logo";
|
||||||
|
29
apps/app/components/onboarding/onboarding-logo.tsx
Normal file
29
apps/app/components/onboarding/onboarding-logo.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
className?: string;
|
||||||
|
width?: string | number;
|
||||||
|
height?: string | number;
|
||||||
|
color?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OnboardingLogo: React.FC<Props> = ({
|
||||||
|
width = "378",
|
||||||
|
height = "117",
|
||||||
|
color = "#858E96",
|
||||||
|
className,
|
||||||
|
}) => (
|
||||||
|
<svg
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
className={className}
|
||||||
|
viewBox="0 0 378 117"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="M101.928 74V15.0505H128.464C134.757 15.0505 139.714 16.7721 143.335 20.2152C146.956 23.599 148.767 28.1998 148.767 34.0176C148.767 39.8354 146.956 44.4659 143.335 47.909C139.714 51.2929 134.757 52.9848 128.464 52.9848H108.606V74H101.928ZM108.606 46.7514H128.019C132.649 46.7514 136.152 45.6235 138.526 43.3676C140.901 41.1117 142.088 37.9951 142.088 34.0176C142.088 30.0995 140.901 27.0125 138.526 24.7567C136.152 22.5008 132.649 21.3729 128.019 21.3729H108.606V46.7514ZM152.411 74V11.6667H159.09V74H152.411ZM185.455 74.7124C181.121 74.7124 177.322 73.7032 174.057 71.6848C170.851 69.607 168.358 66.8168 166.577 63.3143C164.796 59.8117 163.906 55.953 163.906 51.7381C163.906 47.4638 164.796 43.6051 166.577 40.1619C168.358 36.6594 170.851 33.8989 174.057 31.8805C177.322 29.8027 181.121 28.7638 185.455 28.7638C189.136 28.7638 192.282 29.4762 194.894 30.9009C197.566 32.3257 199.732 34.2551 201.395 36.689V29.4762H208.073V74H201.395V66.8762C199.732 69.2508 197.566 71.1505 194.894 72.5752C192.282 74 189.136 74.7124 185.455 74.7124ZM186.346 68.6571C189.67 68.6571 192.46 67.8854 194.716 66.3419C197.031 64.7984 198.783 62.7503 199.97 60.1976C201.157 57.5856 201.751 54.7657 201.751 51.7381C201.751 48.6511 201.157 45.8313 199.97 43.2786C198.783 40.7259 197.031 38.6778 194.716 37.1343C192.46 35.5908 189.67 34.819 186.346 34.819C183.08 34.819 180.261 35.5908 177.886 37.1343C175.511 38.6778 173.701 40.7259 172.454 43.2786C171.207 45.8313 170.584 48.6511 170.584 51.7381C170.584 54.7657 171.207 57.5856 172.454 60.1976C173.701 62.7503 175.511 64.7984 177.886 66.3419C180.261 67.8854 183.08 68.6571 186.346 68.6571ZM215.618 74V29.4762H222.296V36.4219C223.899 34.2848 225.858 32.4741 228.174 30.99C230.489 29.5059 233.457 28.7638 237.078 28.7638C240.165 28.7638 243.045 29.5059 245.716 30.99C248.447 32.4148 250.643 34.5816 252.305 37.4905C254.027 40.34 254.888 43.8722 254.888 48.0871V74H248.209V48.2652C248.209 44.2284 247.052 40.993 244.736 38.559C242.421 36.0657 239.423 34.819 235.743 34.819C233.249 34.819 230.993 35.383 228.975 36.5109C226.957 37.6389 225.324 39.2417 224.077 41.3195C222.89 43.3379 222.296 45.6829 222.296 48.3543V74H215.618ZM281.816 74.7124C277.305 74.7124 273.357 73.7032 269.973 71.6848C266.589 69.607 263.948 66.8168 262.048 63.3143C260.208 59.8117 259.287 55.953 259.287 51.7381C259.287 47.4638 260.178 43.6051 261.959 40.1619C263.74 36.6594 266.292 33.8989 269.617 31.8805C272.941 29.8027 276.859 28.7638 281.371 28.7638C285.942 28.7638 289.86 29.8027 293.125 31.8805C296.45 33.8989 299.003 36.6594 300.784 40.1619C302.565 43.6051 303.455 47.4638 303.455 51.7381V54.4095H266.144C266.5 57.0216 267.331 59.4259 268.637 61.6224C270.003 63.7595 271.813 65.4811 274.069 66.7871C276.325 68.0338 278.937 68.6571 281.905 68.6571C285.052 68.6571 287.694 67.9744 289.831 66.609C291.968 65.1843 293.63 63.3736 294.817 61.1771H302.119C300.576 65.1546 298.112 68.4197 294.728 70.9724C291.404 73.4657 287.1 74.7124 281.816 74.7124ZM266.233 48.1762H296.509C295.916 44.3768 294.313 41.2008 291.701 38.6481C289.089 36.0954 285.645 34.819 281.371 34.819C277.097 34.819 273.654 36.0954 271.042 38.6481C268.489 41.2008 266.886 44.3768 266.233 48.1762Z" />
|
||||||
|
<path d="M81 8H27V36H54V63H81V8Z" fill="#3F76FF" />
|
||||||
|
<rect y="36" width="27" height="27" fill="#3F76FF" />
|
||||||
|
<rect x="27" y="63" width="27" height="27" fill="#3F76FF" />
|
||||||
|
</svg>
|
||||||
|
);
|
@ -163,7 +163,7 @@ export const Workspace: React.FC<Props> = ({ setStep, setWorkspace }) => {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h3 className="text-brand-secondary">You have no invitations</h3>
|
<h3 className="text-brand-secondary">{`You don't have any invitations yet.`}</h3>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,21 +63,23 @@ const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, ha
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||||
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-brand-base">
|
<Dialog.Title
|
||||||
|
as="h3"
|
||||||
|
className="text-lg font-medium leading-6 text-brand-base"
|
||||||
|
>
|
||||||
Remove {data?.email}?
|
Remove {data?.email}?
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Are you sure you want to remove member- {" "}
|
Are you sure you want to remove member-{" "}
|
||||||
<span className="font-bold">{data?.email}</span>
|
<span className="font-bold">{data?.email}</span>? They will no longer have
|
||||||
? They will no longer have access to this project. This action
|
access to this project. This action cannot be undone.
|
||||||
cannot be undone.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
<div className="flex justify-end gap-2 bg-brand-surface-1 p-4 sm:px-6">
|
||||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||||
{isDeleteLoading ? "Removing..." : "Remove"}
|
{isDeleteLoading ? "Removing..." : "Remove"}
|
||||||
|
@ -180,7 +180,9 @@ export const ProjectSidebarList: FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div className="space-y-3 text-center">
|
<div className="space-y-3 text-center">
|
||||||
{!sidebarCollapse && (
|
{!sidebarCollapse && (
|
||||||
<h4 className="text-sm text-gray-700">You don{"'"}t have any project yet</h4>
|
<h4 className="text-sm text-brand-secondary">
|
||||||
|
You don{"'"}t have any project yet
|
||||||
|
</h4>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -126,8 +126,9 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
|||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Are you sure you want to delete state-{" "}
|
Are you sure you want to delete state-{" "}
|
||||||
<span className="italic">{data?.name}</span>? All of the data related to
|
<span className="font-medium text-brand-base">{data?.name}</span>? All of
|
||||||
the state will be permanently removed. This action cannot be undone.
|
the data related to the state will be permanently removed. This action
|
||||||
|
cannot be undone.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,7 +56,11 @@ export const MultiInput = ({ label, name, placeholder, setValue, watch }: any) =
|
|||||||
{label && <label className="mb-2 text-brand-secondary">{label}</label>}
|
{label && <label className="mb-2 text-brand-secondary">{label}</label>}
|
||||||
<div className="rounded-md border border-brand-base p-2">
|
<div className="rounded-md border border-brand-base p-2">
|
||||||
{watch(name)?.map((tag: any, index: number) => (
|
{watch(name)?.map((tag: any, index: number) => (
|
||||||
<button type="button" className="m-1.5 rounded-full bg-slate-300 p-1.5" key={index}>
|
<button
|
||||||
|
type="button"
|
||||||
|
className="m-1.5 rounded-full bg-brand-surface-2 px-3 py-2 "
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
{tag.email} <span onClick={() => removeTag(index)}>×</span>
|
{tag.email} <span onClick={() => removeTag(index)}>×</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
@ -101,7 +101,7 @@ export const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
|
|||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
{option.children && option.id === openChildFor && (
|
{option.children && option.id === openChildFor && (
|
||||||
<div
|
<div
|
||||||
className={`absolute top-0 w-36 origin-top-right select-none overflow-y-scroll rounded-md bg-brand-surface-1 shadow-lg focus:outline-none ${
|
className={`absolute top-0 w-auto min-w-[144px] max-w-[192px] origin-top-right select-none overflow-y-scroll rounded-md bg-brand-surface-1 shadow-lg focus:outline-none ${
|
||||||
direction === "left"
|
direction === "left"
|
||||||
? "right-full -translate-x-1"
|
? "right-full -translate-x-1"
|
||||||
: "left-full translate-x-1"
|
: "left-full translate-x-1"
|
||||||
@ -127,7 +127,7 @@ export const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
|
|||||||
}}
|
}}
|
||||||
className={`${
|
className={`${
|
||||||
child.selected ? "bg-brand-surface-2" : ""
|
child.selected ? "bg-brand-surface-2" : ""
|
||||||
} flex w-full items-center break-all rounded px-1 py-1.5 text-left capitalize text-brand-secondary hover:bg-brand-surface-2`}
|
} flex w-full items-center whitespace-nowrap break-all rounded px-1 py-1.5 text-left capitalize text-brand-secondary hover:bg-brand-surface-2`}
|
||||||
>
|
>
|
||||||
{child.label}
|
{child.label}
|
||||||
</button>
|
</button>
|
||||||
|
@ -39,7 +39,7 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-[#131313] bg-opacity-50 transition-opacity" />
|
<div className="fixed inset-0 bg-brand-backdrop bg-opacity-50 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||||
@ -63,21 +63,23 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||||
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-brand-base">
|
<Dialog.Title
|
||||||
|
as="h3"
|
||||||
|
className="text-lg font-medium leading-6 text-brand-base"
|
||||||
|
>
|
||||||
Remove {data?.email}?
|
Remove {data?.email}?
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Are you sure you want to remove member- {" "}
|
Are you sure you want to remove member-{" "}
|
||||||
<span className="font-bold">{data?.email}</span>
|
<span className="font-bold">{data?.email}</span>? They will no longer have
|
||||||
? They will no longer have access to this workspace. This action
|
access to this workspace. This action cannot be undone.
|
||||||
cannot be undone.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
<div className="flex justify-end gap-2 bg-brand-surface-1 p-4 sm:px-6">
|
||||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||||
{isDeleteLoading ? "Removing..." : "Remove"}
|
{isDeleteLoading ? "Removing..." : "Remove"}
|
||||||
|
@ -122,6 +122,7 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
|
|||||||
`Name can only contain (" "), ( - ), ( _ ) & Alphanumeric characters.`,
|
`Name can only contain (" "), ( - ), ( _ ) & Alphanumeric characters.`,
|
||||||
}}
|
}}
|
||||||
placeholder="e.g. My Workspace"
|
placeholder="e.g. My Workspace"
|
||||||
|
className="placeholder:text-brand-secondary"
|
||||||
error={errors.name}
|
error={errors.name}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,13 +13,17 @@ import useUser from "hooks/use-user";
|
|||||||
import DefaultLayout from "layouts/default-layout";
|
import DefaultLayout from "layouts/default-layout";
|
||||||
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
|
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
|
||||||
// components
|
// components
|
||||||
import { InviteMembers, OnboardingCard, UserDetails, Workspace } from "components/onboarding";
|
import {
|
||||||
|
InviteMembers,
|
||||||
|
OnboardingCard,
|
||||||
|
OnboardingLogo,
|
||||||
|
UserDetails,
|
||||||
|
Workspace,
|
||||||
|
} from "components/onboarding";
|
||||||
// ui
|
// ui
|
||||||
import { PrimaryButton } from "components/ui";
|
import { PrimaryButton } from "components/ui";
|
||||||
// constant
|
// constant
|
||||||
import { ONBOARDING_CARDS } from "constants/workspace";
|
import { ONBOARDING_CARDS } from "constants/workspace";
|
||||||
// images
|
|
||||||
import Logo from "public/onboarding/logo.svg";
|
|
||||||
// types
|
// types
|
||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
import { ICurrentUserResponse } from "types";
|
import { ICurrentUserResponse } from "types";
|
||||||
@ -42,8 +46,8 @@ const Onboarding: NextPage = () => {
|
|||||||
<div className="grid h-full place-items-center p-5">
|
<div className="grid h-full place-items-center p-5">
|
||||||
{step <= 3 ? (
|
{step <= 3 ? (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="mb-8 text-center">
|
<div className="mb-8 flex items-center justify-center text-center">
|
||||||
<Image src={Logo} height="50" alt="Plane Logo" />
|
<OnboardingLogo className="h-12 w-48 fill-current text-brand-base" />
|
||||||
</div>
|
</div>
|
||||||
{step === 1 ? (
|
{step === 1 ? (
|
||||||
<UserDetails user={user} setStep={setStep} setUserRole={setUserRole} />
|
<UserDetails user={user} setStep={setStep} setUserRole={setUserRole} />
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Loading…
Reference in New Issue
Block a user