fix: bug fixes (#1000)

* fix: issue sidebar cycle and module dropdown fix

* style: my issue page

* style: date picker theming

* fix: cycle modal

* style: date picker

* fix: info icon fix

* feat: integration banner

* feat: project integration banner

* fix: module card progress bar fix

* style: integration banner

* style: workspace sidebar

* fix: cycle date checker

* fix: calendar page view dropdown
This commit is contained in:
Anmol Singh Bhatia 2023-05-05 15:45:53 +05:30 committed by GitHub
parent 93c105c495
commit 86cb23777e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 332 additions and 187 deletions

View File

@ -134,7 +134,7 @@ export const IssuesFilterView: React.FC = () => {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute right-0 z-20 mt-1 w-screen max-w-xs transform overflow-hidden rounded-lg border border-brand-base bg-brand-surface-1 p-3 shadow-lg">
<Popover.Panel className="absolute right-0 z-20 mt-1 w-screen max-w-xs transform rounded-lg border border-brand-base bg-brand-surface-1 p-3 shadow-lg">
<div className="relative divide-y-2 divide-brand-base">
<div className="space-y-4 pb-3 text-xs">
{issueView !== "calendar" && (

View File

@ -65,7 +65,11 @@ export const CompletedCyclesList: React.FC<CompletedCyclesListProps> = ({
completedCycles.completed_cycles.length > 0 ? (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-2 text-sm text-brand-secondary">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon
height={14}
width={14}
className="fill-current text-brand-secondary"
/>
<span>Completed cycles are not editable.</span>
</div>
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">

View File

@ -1,21 +1,10 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { useEffect } from "react";
// react-hook-form
import { Controller, useForm } from "react-hook-form";
// services
import cyclesService from "services/cycles.service";
// hooks
import useToast from "hooks/use-toast";
// ui
import { DateSelect, Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
// helpers
import {
getDateRangeStatus,
isDateGreaterThanToday,
isDateRangeValid,
} from "helpers/date-time.helper";
// types
import { ICycle } from "types";
@ -34,13 +23,6 @@ const defaultValues: Partial<ICycle> = {
};
export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, status, data }) => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { setToastAlert } = useToast();
const [isDateValid, setIsDateValid] = useState(true);
const {
register,
formState: { errors, isSubmitting },
@ -60,43 +42,6 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
});
};
const cycleStatus =
data?.start_date && data?.end_date ? getDateRangeStatus(data?.start_date, data?.end_date) : "";
const dateChecker = async (payload: any) => {
if (isDateGreaterThanToday(payload.end_date)) {
await cyclesService
.cycleDateCheck(workspaceSlug as string, projectId as string, payload)
.then((res) => {
if (res.status) {
setIsDateValid(true);
} else {
setIsDateValid(false);
setToastAlert({
type: "error",
title: "Error!",
message:
"You have a cycle already on the given dates, if you want to create your draft cycle you can do that by removing dates",
});
}
})
.catch((err) => {
console.log(err);
});
} else {
setIsDateValid(false);
setToastAlert({
type: "error",
title: "Error!",
message: "Unable to create cycle in past date. Please enter a valid date.",
});
}
};
const checkEmptyDate =
(watch("start_date") === "" && watch("end_date") === "") ||
(!watch("start_date") && !watch("end_date"));
useEffect(() => {
reset({
...defaultValues,
@ -147,30 +92,7 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
control={control}
name="start_date"
render={({ field: { value, onChange } }) => (
<DateSelect
label="Start date"
value={value}
onChange={(val) => {
onChange(val);
if (val && watch("end_date")) {
if (isDateRangeValid(val, `${watch("end_date")}`)) {
cycleStatus != "current" &&
dateChecker({
start_date: val,
end_date: watch("end_date"),
});
} else {
setIsDateValid(false);
setToastAlert({
type: "error",
title: "Error!",
message:
"The date you have entered is invalid. Please check and enter a valid date.",
});
}
}
}}
/>
<DateSelect label="Start date" value={value} onChange={(val) => onChange(val)} />
)}
/>
</div>
@ -179,30 +101,7 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
control={control}
name="end_date"
render={({ field: { value, onChange } }) => (
<DateSelect
label="End date"
value={value}
onChange={(val) => {
onChange(val);
if (watch("start_date") && val) {
if (isDateRangeValid(`${watch("start_date")}`, val)) {
cycleStatus != "current" &&
dateChecker({
start_date: watch("start_date"),
end_date: val,
});
} else {
setIsDateValid(false);
setToastAlert({
type: "error",
title: "Error!",
message:
"The date you have entered is invalid. Please check and enter a valid date.",
});
}
}
}}
/>
<DateSelect label="End date" value={value} onChange={(val) => onChange(val)} />
)}
/>
</div>
@ -211,18 +110,7 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
</div>
<div className="-mx-5 mt-5 flex justify-end gap-2 border-t border-brand-base px-5 pt-5">
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
<PrimaryButton
type="submit"
className={
checkEmptyDate
? "cursor-pointer"
: isDateValid
? "cursor-pointer"
: "cursor-not-allowed"
}
disabled={checkEmptyDate ? false : isDateValid ? false : true}
loading={isSubmitting}
>
<PrimaryButton type="submit" loading={isSubmitting}>
{status
? isSubmitting
? "Updating Cycle..."

View File

@ -13,7 +13,7 @@ import useToast from "hooks/use-toast";
// components
import { CycleForm } from "components/cycles";
// helper
import { getDateRangeStatus } from "helpers/date-time.helper";
import { getDateRangeStatus, isDateGreaterThanToday } from "helpers/date-time.helper";
// types
import type { ICycle } from "types";
// fetch keys
@ -128,6 +128,21 @@ export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
});
};
const dateChecker = async (payload: any) => {
try {
const res = await cycleService.cycleDateCheck(
workspaceSlug as string,
projectId as string,
payload
);
console.log(res);
return res.status;
} catch (err) {
console.log(err);
return false;
}
};
const handleFormSubmit = async (formData: Partial<ICycle>) => {
if (!workspaceSlug || !projectId) return;
@ -135,8 +150,63 @@ export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
...formData,
};
if (!data) await createCycle(payload);
else await updateCycle(data.id, payload);
if (payload.start_date && payload.end_date) {
if (!isDateGreaterThanToday(payload.end_date)) {
setToastAlert({
type: "error",
title: "Error!",
message: "Unable to create cycle in past date. Please enter a valid date.",
});
return;
}
const isDateValid = await dateChecker({
start_date: payload.start_date,
end_date: payload.end_date,
});
if (data?.start_date && data?.end_date) {
const isDateValidForExistingCycle = await dateChecker({
start_date: payload.start_date,
end_date: payload.end_date,
cycle_id: data.id,
});
if (isDateValidForExistingCycle) {
await updateCycle(data.id, payload);
return;
} else {
setToastAlert({
type: "error",
title: "Error!",
message:
"You have a cycle already on the given dates, if you want to create your draft cycle you can do that by removing dates",
});
return;
}
}
if (isDateValid) {
if (data) {
await updateCycle(data.id, payload);
} else {
await createCycle(payload);
}
} else {
setToastAlert({
type: "error",
title: "Error!",
message:
"You have a cycle already on the given dates, if you want to create your draft cycle you can do that by removing dates",
});
}
} else {
if (data) {
await updateCycle(data.id, payload);
} else {
await createCycle(payload);
}
}
};
return (

View File

@ -370,7 +370,11 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
</Disclosure.Button>
) : (
<div className="flex items-center gap-1">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon
height={14}
width={14}
className="fill-current text-brand-secondary"
/>
<span className="text-xs italic text-brand-secondary">
{cycleStatus === "upcoming"
? "Cycle is yet to start."
@ -444,7 +448,11 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
</Disclosure.Button>
) : (
<div className="flex items-center gap-1">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon
height={14}
width={14}
className="fill-current text-brand-secondary"
/>
<span className="text-xs italic text-brand-secondary">
No issues found. Please add issue.
</span>

View File

@ -148,7 +148,11 @@ export const TransferIssuesModal: React.FC<Props> = ({ isOpen, handleClose }) =>
))
) : (
<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}
className="fill-current text-brand-secondary"
/>
<span className="text-center text-brand-secondary">
You dont have any current cycle. Please create one to transfer the
issues.

View File

@ -39,7 +39,7 @@ export const TransferIssues: React.FC<Props> = ({ handleClick }) => {
return (
<div className="-mt-2 mb-4 flex items-center justify-between">
<div className="flex items-center gap-2 text-sm text-brand-secondary">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon height={14} width={14} className="fill-current text-brand-secondary" />
<span>Completed cycles are not editable.</span>
</div>

View File

@ -3,14 +3,14 @@ import React from "react";
import type { Props } from "./types";
export const ExclamationIcon: React.FC<Props> = ({ width, height, className }) => (
<svg
width={width}
height={height}
className={className}
viewBox="0 0 14 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7.55321 11.042C7.70668 11.042 7.83359 10.9918 7.93394 10.8915C8.03428 10.7911 8.08446 10.6642 8.08446 10.5107V7.30553C8.08446 7.16387 8.03133 7.04286 7.92508 6.94251C7.81883 6.84217 7.69487 6.79199 7.55321 6.79199C7.39973 6.79199 7.27283 6.84217 7.17248 6.94251C7.07213 7.04286 7.02196 7.16977 7.02196 7.32324V10.5285C7.02196 10.6701 7.07508 10.7911 7.18133 10.8915C7.28758 10.9918 7.41154 11.042 7.55321 11.042ZM7.50008 5.48158C7.66536 5.48158 7.80407 5.42845 7.91623 5.3222C8.02838 5.21595 8.08446 5.08019 8.08446 4.91491C8.08446 4.74963 8.02838 4.60796 7.91623 4.48991C7.80407 4.37185 7.66536 4.31283 7.50008 4.31283C7.3348 4.31283 7.19609 4.37185 7.08394 4.48991C6.97178 4.60796 6.91571 4.74963 6.91571 4.91491C6.91571 5.08019 6.97178 5.21595 7.08394 5.3222C7.19609 5.42845 7.3348 5.48158 7.50008 5.48158ZM7.50008 14.5837C6.49661 14.5837 5.56397 14.4036 4.70217 14.0436C3.84036 13.6835 3.09071 13.1847 2.45321 12.5472C1.81571 11.9097 1.31692 11.16 0.956852 10.2982C0.596783 9.43644 0.416748 8.5038 0.416748 7.50033C0.416748 6.50866 0.596783 5.58192 0.956852 4.72012C1.31692 3.85831 1.81571 3.10866 2.45321 2.47116C3.09071 1.83366 3.84036 1.33192 4.70217 0.965951C5.56397 0.599978 6.49661 0.416992 7.50008 0.416992C8.49175 0.416992 9.41848 0.599978 10.2803 0.965951C11.1421 1.33192 11.8917 1.83366 12.5292 2.47116C13.1667 3.10866 13.6685 3.85831 14.0345 4.72012C14.4004 5.58192 14.5834 6.50866 14.5834 7.50033C14.5834 8.5038 14.4004 9.43644 14.0345 10.2982C13.6685 11.16 13.1667 11.9097 12.5292 12.5472C11.8917 13.1847 11.1421 13.6835 10.2803 14.0436C9.41848 14.4036 8.49175 14.5837 7.50008 14.5837ZM7.50008 13.5212C9.15286 13.5212 10.5695 12.9309 11.7501 11.7503C12.9306 10.5698 13.5209 9.1531 13.5209 7.50033C13.5209 5.84755 12.9306 4.43088 11.7501 3.25033C10.5695 2.06977 9.15286 1.47949 7.50008 1.47949C5.8473 1.47949 4.43064 2.06977 3.25008 3.25033C2.06953 4.43088 1.47925 5.84755 1.47925 7.50033C1.47925 9.1531 2.06953 10.5698 3.25008 11.7503C4.43064 12.9309 5.8473 13.5212 7.50008 13.5212Z" fill="#858E96"/>
</svg>
);
<svg
width={width}
height={height}
className={className}
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7.55321 11.042C7.70668 11.042 7.83359 10.9918 7.93394 10.8915C8.03428 10.7911 8.08446 10.6642 8.08446 10.5107V7.30553C8.08446 7.16387 8.03133 7.04286 7.92508 6.94251C7.81883 6.84217 7.69487 6.79199 7.55321 6.79199C7.39973 6.79199 7.27283 6.84217 7.17248 6.94251C7.07213 7.04286 7.02196 7.16977 7.02196 7.32324V10.5285C7.02196 10.6701 7.07508 10.7911 7.18133 10.8915C7.28758 10.9918 7.41154 11.042 7.55321 11.042ZM7.50008 5.48158C7.66536 5.48158 7.80407 5.42845 7.91623 5.3222C8.02838 5.21595 8.08446 5.08019 8.08446 4.91491C8.08446 4.74963 8.02838 4.60796 7.91623 4.48991C7.80407 4.37185 7.66536 4.31283 7.50008 4.31283C7.3348 4.31283 7.19609 4.37185 7.08394 4.48991C6.97178 4.60796 6.91571 4.74963 6.91571 4.91491C6.91571 5.08019 6.97178 5.21595 7.08394 5.3222C7.19609 5.42845 7.3348 5.48158 7.50008 5.48158ZM7.50008 14.5837C6.49661 14.5837 5.56397 14.4036 4.70217 14.0436C3.84036 13.6835 3.09071 13.1847 2.45321 12.5472C1.81571 11.9097 1.31692 11.16 0.956852 10.2982C0.596783 9.43644 0.416748 8.5038 0.416748 7.50033C0.416748 6.50866 0.596783 5.58192 0.956852 4.72012C1.31692 3.85831 1.81571 3.10866 2.45321 2.47116C3.09071 1.83366 3.84036 1.33192 4.70217 0.965951C5.56397 0.599978 6.49661 0.416992 7.50008 0.416992C8.49175 0.416992 9.41848 0.599978 10.2803 0.965951C11.1421 1.33192 11.8917 1.83366 12.5292 2.47116C13.1667 3.10866 13.6685 3.85831 14.0345 4.72012C14.4004 5.58192 14.5834 6.50866 14.5834 7.50033C14.5834 8.5038 14.4004 9.43644 14.0345 10.2982C13.6685 11.16 13.1667 11.9097 12.5292 12.5472C11.8917 13.1847 11.1421 13.6835 10.2803 14.0436C9.41848 14.4036 8.49175 14.5837 7.50008 14.5837ZM7.50008 13.5212C9.15286 13.5212 10.5695 12.9309 11.7501 11.7503C12.9306 10.5698 13.5209 9.1531 13.5209 7.50033C13.5209 5.84755 12.9306 4.43088 11.7501 3.25033C10.5695 2.06977 9.15286 1.47949 7.50008 1.47949C5.8473 1.47949 4.43064 2.06977 3.25008 3.25033C2.06953 4.43088 1.47925 5.84755 1.47925 7.50033C1.47925 9.1531 2.06953 10.5698 3.25008 11.7503C4.43064 12.9309 5.8473 13.5212 7.50008 13.5212Z" />
</svg>
);

View File

@ -231,6 +231,16 @@ export const IssueActivitySection: React.FC = () => {
action = `${activityItem.verb} the`;
} else if (activityItem.field === "estimate") {
action = "updated the";
} else if (activityItem.field === "cycles") {
action =
activityItem.new_value && activityItem.new_value !== ""
? "set the cycle to"
: "removed the cycle";
} else if (activityItem.field === "modules") {
action =
activityItem.new_value && activityItem.new_value !== ""
? "set the module to"
: "removed the module";
}
// for values that are after the action clause
let value: any = activityItem.new_value ? activityItem.new_value : activityItem.old_value;
@ -282,6 +292,18 @@ export const IssueActivitySection: React.FC = () => {
value = "description";
} else if (activityItem.field === "attachment") {
value = "attachment";
} else if (activityItem.field === "cycles") {
const cycles =
activityItem.new_value && activityItem.new_value !== ""
? activityItem.new_value
: activityItem.old_value;
value = cycles ? addSpaceIfCamelCase(cycles) : "None";
} else if (activityItem.field === "modules") {
const modules =
activityItem.new_value && activityItem.new_value !== ""
? activityItem.new_value
: activityItem.old_value;
value = modules ? addSpaceIfCamelCase(modules) : "None";
} else if (activityItem.field === "link") {
value = "link";
} else if (activityItem.field === "estimate_point") {

View File

@ -82,7 +82,7 @@ export const IssueAttachments = () => {
} uploaded on ${renderLongDateFormat(file.updated_at)}`}
>
<span>
<ExclamationIcon className="h-3 w-3" />
<ExclamationIcon className="h-3 w-3 fill-current text-brand-base" />
</span>
</Tooltip>
</div>

View File

@ -82,7 +82,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
const isNotAllowed = false;
return (
<div className="border-b border-brand-base last:border-b-0 mx-6">
<div className="mx-6 border-b border-brand-base last:border-b-0">
<div key={issue.id} className="flex items-center justify-between gap-2 py-3">
<Link href={`/${workspaceSlug}/projects/${issue?.project_detail?.id}/issues/${issue.id}`}>
<a className="group relative flex items-center gap-2">
@ -91,13 +91,13 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
tooltipHeading="Issue ID"
tooltipContent={`${issue.project_detail?.identifier}-${issue.sequence_id}`}
>
<span className="flex-shrink-0 text-xs text-gray-400">
<span className="flex-shrink-0 text-xs text-brand-secondary">
{issue.project_detail?.identifier}-{issue.sequence_id}
</span>
</Tooltip>
)}
<Tooltip position="top-left" tooltipHeading="Title" tooltipContent={issue.name}>
<span className="break-all text-sm text-brand-base">
<span className="text-[0.825rem] text-brand-base">
{truncateText(issue.name, 50)}
</span>
</Tooltip>
@ -127,7 +127,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
/>
)}
{properties.sub_issue_count && (
<div className="flex items-center gap-1 rounded-md border border-brand-base px-3 py-1.5 text-xs shadow-sm">
<div className="flex items-center gap-1 rounded-md border border-brand-base px-2 py-1 text-xs text-brand-secondary shadow-sm">
{issue?.sub_issues_count} {issue?.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
</div>
)}
@ -136,10 +136,10 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
{issue.label_details.map((label) => (
<span
key={label.id}
className="group flex items-center gap-1 rounded-2xl border border-brand-base px-2 py-0.5 text-xs"
className="group flex items-center gap-1 rounded-2xl border border-brand-base px-2 py-0.5 text-xs text-brand-secondary"
>
<span
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
className="h-1.5 w-1.5 rounded-full"
style={{
backgroundColor: label?.color && label.color !== "" ? label.color : "#000",
}}
@ -171,20 +171,20 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
</Tooltip>
)}
{properties.link && (
<div className="flex items-center rounded-md shadow-sm px-2.5 py-1 cursor-default text-xs border border-gray-200">
<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}`}>
<div className="flex items-center gap-1 text-gray-500">
<LinkIcon className="h-3.5 w-3.5 text-gray-500" />
<div className="flex items-center gap-1 text-brand-secondary">
<LinkIcon className="h-3.5 w-3.5 text-brand-secondary" />
{issue.link_count}
</div>
</Tooltip>
</div>
)}
{properties.attachment_count && (
<div className="flex items-center rounded-md shadow-sm px-2.5 py-1 cursor-default text-xs border border-gray-200">
<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}`}>
<div className="flex items-center gap-1 text-gray-500">
<PaperClipIcon className="h-3.5 w-3.5 text-gray-500 -rotate-45" />
<div className="flex items-center gap-1 text-brand-secondary">
<PaperClipIcon className="h-3.5 w-3.5 -rotate-45 text-brand-secondary" />
{issue.attachment_count}
</div>
</Tooltip>

View File

@ -78,7 +78,7 @@ export const SidebarCycleSelect: React.FC<Props> = ({
</span>
</Tooltip>
}
value={issueCycle?.cycle_detail.id}
value={issueCycle ? issueCycle.cycle_detail.id : null}
onChange={(value: any) => {
!value
? removeIssueFromCycle(issueCycle?.id ?? "", issueCycle?.cycle ?? "")

View File

@ -82,7 +82,7 @@ export const SidebarModuleSelect: React.FC<Props> = ({
</span>
</Tooltip>
}
value={issueModule?.module_detail?.id}
value={issueModule ? issueModule.module_detail?.id : null}
onChange={(value: any) => {
!value
? removeIssueFromModule(issueModule?.id ?? "", issueModule?.module ?? "")

View File

@ -416,7 +416,11 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({ issues, module, isOpen,
</Disclosure.Button>
) : (
<div className="flex items-center gap-1">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon
height={14}
width={14}
className="fill-current text-brand-secondary"
/>
<span className="text-xs italic text-brand-secondary">
Invalid date. Please enter valid date.
</span>
@ -488,7 +492,11 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({ issues, module, isOpen,
</Disclosure.Button>
) : (
<div className="flex items-center gap-1">
<ExclamationIcon height={14} width={14} />
<ExclamationIcon
height={14}
width={14}
className="fill-current text-brand-secondary"
/>
<span className="text-xs italic text-brand-secondary">
No issues found. Please add issue.
</span>

View File

@ -44,7 +44,8 @@ export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule })
const { setToastAlert } = useToast();
const completionPercentage = (module.completed_issues / module.total_issues) * 100;
const completionPercentage =
((module.completed_issues + module.cancelled_issues) / module.total_issues) * 100;
const handleDeleteModule = () => {
if (!module) return;

View File

@ -162,7 +162,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
} on ${renderLongDateFormat(`${page.created_at}`)}`}
>
<span>
<ExclamationIcon className="h-4 w-4 text-gray-400" />
<ExclamationIcon className="h-4 w-4 fill-current text-brand-secondary" />
</span>
</Tooltip>
<CustomMenu verticalEllipsis>

View File

@ -161,7 +161,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
} on ${renderLongDateFormat(`${page.created_at}`)}`}
>
<span>
<ExclamationIcon className="h-4 w-4 text-gray-400" />
<ExclamationIcon className="h-4 w-4 fill-current text-brand-secondary" />
</span>
</Tooltip>

View File

@ -172,8 +172,8 @@ export const SingleSidebarProject: React.FC<Props> = ({
<a
className={`group flex items-center rounded-md p-2 text-xs font-medium outline-none ${
router.asPath.includes(item.href)
? "bg-brand-base text-brand-secondary"
: "text-brand-secondary hover:bg-brand-surface-1 hover:text-brand-secondary focus:bg-brand-base focus:text-brand-secondary"
? "bg-brand-surface-2 text-brand-base"
: "text-brand-secondary hover:bg-brand-surface-2 hover:text-brand-secondary focus:bg-brand-surface-2 focus:text-brand-secondary"
} ${sidebarCollapse ? "justify-center" : ""}`}
>
<div className="grid place-items-center">

View File

@ -47,8 +47,8 @@ export const WorkspaceSidebarMenu: React.FC = () => {
? router.asPath === link.href
: router.asPath.includes(link.href)
)
? "bg-brand-base text-brand-base"
: "text-brand-secondary hover:bg-brand-surface-1 hover:text-brand-secondary focus:bg-brand-base focus:text-brand-secondary"
? "bg-brand-surface-2 text-brand-base"
: "text-brand-secondary hover:bg-brand-surface-2 hover:text-brand-secondary focus:bg-brand-surface-2 focus:text-brand-secondary"
} group flex w-full items-center gap-3 rounded-md p-2 text-sm font-medium outline-none ${
sidebarCollapse ? "justify-center" : ""
}`}

View File

@ -52,7 +52,7 @@ const MyIssuesPage: NextPage = () => {
<>
<Popover.Button
className={`group flex items-center gap-2 rounded-md border border-brand-base bg-transparent px-3 py-1.5 text-xs hover:bg-brand-surface-1 hover:text-brand-base focus:outline-none ${
open ? "bg-brand-surface-1 text-brand-base" : "text-brand-muted-1"
open ? "bg-brand-surface-1 text-brand-base" : "text-brand-secondary"
}`}
>
<span>View</span>
@ -69,29 +69,27 @@ const MyIssuesPage: NextPage = () => {
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute right-1/2 z-10 mr-5 mt-1 w-screen max-w-xs translate-x-1/2 transform overflow-hidden rounded-lg bg-brand-base p-3 shadow-lg">
<div className="relative flex flex-col gap-1 gap-y-4">
<div className="relative flex flex-col gap-1">
<h4 className="text-base text-gray-600">Properties</h4>
<div className="flex flex-wrap items-center gap-2">
{Object.keys(properties).map((key) => {
if (key === "estimate") return null;
<div className="space-y-2 py-3">
<h4 className="text-sm text-brand-secondary">Properties</h4>
<div className="flex flex-wrap items-center gap-2">
{Object.keys(properties).map((key) => {
if (key === "estimate") return null;
return (
<button
key={key}
type="button"
className={`rounded border border-theme px-2 py-1 text-xs capitalize ${
properties[key as keyof Properties]
? "border-theme bg-theme text-white"
: ""
}`}
onClick={() => setProperties(key as keyof Properties)}
>
{key === "key" ? "ID" : replaceUnderscoreIfSnakeCase(key)}
</button>
);
})}
</div>
return (
<button
key={key}
type="button"
className={`rounded border px-2 py-1 text-xs capitalize ${
properties[key as keyof Properties]
? "border-brand-accent bg-brand-accent text-white"
: "border-brand-base"
}`}
onClick={() => setProperties(key as keyof Properties)}
>
{key === "key" ? "ID" : replaceUnderscoreIfSnakeCase(key)}
</button>
);
})}
</div>
</div>
</Popover.Panel>
@ -107,7 +105,7 @@ const MyIssuesPage: NextPage = () => {
document.dispatchEvent(e);
}}
>
<PlusIcon className="w-4 h-4" />
<PlusIcon className="h-4 w-4" />
Add Issue
</PrimaryButton>
</div>

View File

@ -16,6 +16,7 @@ import { EmptySpace, EmptySpaceItem, Loader } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// icons
import { PlusIcon, PuzzlePieceIcon } from "@heroicons/react/24/outline";
import { ExclamationIcon } from "components/icons";
// types
import { IProject } from "types";
import type { NextPage } from "next";
@ -56,7 +57,17 @@ const ProjectIntegrations: NextPage = () => {
{workspaceIntegrations ? (
workspaceIntegrations.length > 0 ? (
<section className="space-y-8">
<h3 className="text-2xl font-semibold">Integrations</h3>
<div className="flex flex-col items-start gap-3">
<h3 className="text-2xl font-semibold">Integrations</h3>
<div className="flex items-center gap-3 rounded-[10px] border border-brand-accent/75 bg-brand-accent/5 p-4 text-sm text-brand-base">
<ExclamationIcon height={24} width={24} className="fill-current text-brand-base" />
<p className="leading-5">
Integrations and importers are only available on the cloud version. We plan to
open-source our SDKs in the near future so that the community can request or
contribute integrations as needed.
</p>
</div>
</div>
<div className="space-y-5">
{workspaceIntegrations.map((integration) => (
<SingleIntegration

View File

@ -14,6 +14,8 @@ import { SingleIntegrationCard } from "components/integration";
// ui
import { Loader } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// icons
import { ExclamationIcon } from "components/icons";
// types
import type { NextPage } from "next";
// fetch-keys
@ -45,7 +47,17 @@ const WorkspaceIntegrations: NextPage = () => {
}
>
<section className="space-y-8">
<h3 className="text-2xl font-semibold">Integrations</h3>
<div className="flex flex-col items-start gap-3">
<h3 className="text-2xl font-semibold">Integrations</h3>
<div className="flex items-center gap-3 rounded-[10px] border border-brand-accent/75 bg-brand-accent/5 p-4 text-sm text-brand-base">
<ExclamationIcon height={24} width={24} className="fill-current text-brand-base" />
<p className="leading-5">
Integrations and importers are only available on the cloud version. We plan to
open-source our SDKs in the near future so that the community can request or
contribute integrations as needed.
</p>
</div>
</div>
<div className="space-y-5">
{appIntegrations ? (
appIntegrations.map((integration) => (

View File

@ -8,6 +8,7 @@ import "styles/globals.css";
import "styles/editor.css";
import "styles/command-pallette.css";
import "styles/nprogress.css";
import "styles/react-datepicker.css";
// router
import Router from "next/router";

View File

@ -0,0 +1,118 @@
.react-datepicker-wrapper input::placeholder {
color: rgba(var(--color-text-secondary));
opacity: 1;
}
.react-datepicker-wrapper input:-ms-input-placeholder {
color: rgba(var(--color-text-secondary));
}
.react-datepicker-wrapper .react-datepicker__close-icon::after {
background: transparent;
color: rgba(var(--color-text-secondary));
}
.react-datepicker-popper {
z-index: 30 !important;
}
.react-datepicker-wrapper {
position: relative;
background-color: rgba(var(--color-bg-base)) !important;
}
.react-datepicker {
font-family: "Inter" !important;
border: none !important;
background-color: rgba(var(--color-bg-base)) !important;
}
.react-datepicker__month-container {
width: 300px;
background-color: rgba(var(--color-bg-base)) !important;
color: rgba(var(--color-text-base)) !important;
border-radius: 10px !important;
/* border: 1px solid rgba(var(--color-border)) !important; */
}
.react-datepicker__header {
border-radius: 10px !important;
background-color: rgba(var(--color-bg-base)) !important;
border: none !important;
}
.react-datepicker__navigation {
line-height: 0.78;
}
.react-datepicker__triangle {
border-color: rgba(var(--color-bg-base)) transparent transparent transparent !important;
}
.react-datepicker__triangle:before {
border-bottom-color: rgba(var(--color-border)) !important;
}
.react-datepicker__triangle:after {
border-bottom-color: rgba(var(--color-bg-base)) !important;
}
.react-datepicker__current-month {
font-weight: 500 !important;
color: rgba(var(--color-text-base)) !important;
}
.react-datepicker__month {
border-collapse: collapse;
color: rgba(var(--color-text-base)) !important;
}
.react-datepicker__day-names {
margin-top: 10px;
margin-left: 14px;
width: 280px;
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0;
}
.react-datepicker__day-name {
color: rgba(var(--color-text-base)) !important;
}
.react-datepicker__week {
display: grid;
grid-template-columns: repeat(7, 1fr);
margin-left: 8px;
}
.react-datepicker__day {
color: rgba(var(--color-text-base)) !important;
}
.react-datepicker__day {
border-radius: 50% !important;
transition: all 0.15s ease-in-out;
}
.react-datepicker__day:hover {
background-color: rgba(var(--color-bg-surface-2)) !important;
color: rgba(var(--color-text-base)) !important;
}
.react-datepicker__day--selected {
background-color: #216ba5 !important;
color: white !important;
}
.react-datepicker__day--today {
font-weight: 800;
}
.react-datepicker__day--highlighted {
background-color: rgba(var(--color-bg-surface-2)) !important;
}
.react-datepicker__day--keyboard-selected {
background-color: #216ba5 !important;
color: white !important;
}