Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,6 @@ const IssueRowDetails = observer(function IssueRowDetails(props: IssueRowDetails

const canSelectIssues = !disableUserActions && !selectionHelpers.isSelectionDisabled;

//TODO: add better logic. This is to have a min width for ID/Key based on the length of project identifier
const keyMinWidth = displayProperties?.key
? (getProjectIdentifierById(issueDetail.project_id)?.length ?? 0 + 5) * 7
: 0;

const workItemLink = generateWorkItemLink({
workspaceSlug: workspaceSlug?.toString(),
projectId: issueDetail?.project_id,
Expand All @@ -255,11 +250,12 @@ const IssueRowDetails = observer(function IssueRowDetails(props: IssueRowDetails

return (
<>
{/* Single sticky column containing both identifier and workitem */}
<td
id={`issue-${issueId}`}
ref={cellRef}
tabIndex={0}
className="relative md:sticky left-0 z-10 group/list-block bg-custom-background-100 min-w-60 max-w-[30vw]"
className="relative md:sticky left-0 z-10 group/list-block bg-custom-background-100"
>
<ControlLink
href={workItemLink}
Expand All @@ -278,7 +274,29 @@ const IssueRowDetails = observer(function IssueRowDetails(props: IssueRowDetails
}
)}
>
<div className="flex items-center gap-0.5 min-w-min py-2">
{/* Identifier section - conditionally rendered */}
{displayProperties?.key && (
<div className="flex-shrink-0 flex items-center h-full min-w-24">
<div className="relative flex cursor-pointer items-center text-xs hover:text-custom-text-100">
{issueDetail.project_id && (
<IssueIdentifier
issueId={issueDetail.id}
projectId={issueDetail.project_id}
textContainerClassName="text-sm md:text-xs text-custom-text-300"
displayProperties={displayProperties}
/>
)}
</div>
</div>
)}

{/* Workitem section */}
<div
className={cn("flex items-center gap-0.5 py-2 flex-grow", {
"min-w-[360px]": !displayProperties?.key,
"min-w-60": displayProperties?.key,
})}
>
{/* select checkbox */}
{projectId && canSelectIssues && (
<Tooltip
Expand Down Expand Up @@ -311,21 +329,6 @@ const IssueRowDetails = observer(function IssueRowDetails(props: IssueRowDetails
{/* sub issues indentation */}
{nestingLevel !== 0 && <div style={{ width: subIssueIndentation }} />}

{(displayProperties?.key || displayProperties?.issue_type) && (
<div className="relative flex cursor-pointer items-center text-center text-xs hover:text-custom-text-100">
<p className={`flex font-medium leading-7`} style={{ minWidth: `${keyMinWidth}px` }}>
{issueDetail.project_id && (
<IssueIdentifier
issueId={issueDetail.id}
projectId={issueDetail.project_id}
textContainerClassName="text-sm md:text-xs text-custom-text-300"
displayProperties={displayProperties}
/>
)}
</p>
</div>
)}

{/* sub-issues chevron */}
<div className="grid place-items-center size-4">
{subIssuesCount > 0 && !isEpic && (
Expand All @@ -343,31 +346,31 @@ const IssueRowDetails = observer(function IssueRowDetails(props: IssueRowDetails
</button>
)}
</div>
</div>

<div className="flex items-center gap-2 justify-between h-full w-full truncate my-auto">
<div className="w-full line-clamp-1 text-sm text-custom-text-100">
<div className="w-full overflow-hidden">
<Tooltip tooltipContent={issueDetail.name} isMobile={isMobile}>
<div
className="h-full w-full cursor-pointer truncate pr-4 text-left text-[0.825rem] text-custom-text-100 focus:outline-none"
tabIndex={-1}
>
{issueDetail.name}
</div>
</Tooltip>
<div className="flex items-center gap-2 justify-between h-full w-full truncate my-auto">
<div className="w-full line-clamp-1 text-sm text-custom-text-100">
<div className="w-full overflow-hidden">
<Tooltip tooltipContent={issueDetail.name} isMobile={isMobile}>
<div
className="h-full w-full cursor-pointer truncate pr-4 text-left text-[0.825rem] text-custom-text-100 focus:outline-none"
tabIndex={-1}
>
{issueDetail.name}
</div>
</Tooltip>
</div>
</div>
<div
className={`opacity-0 group-hover:opacity-100 transition-opacity ${isMenuActive ? "!opacity-100" : ""}`}
onClick={(e) => e.stopPropagation()}
>
{quickActions({
issue: issueDetail,
parentRef: cellRef,
customActionButton,
portalElement: portalElement.current,
})}
</div>
</div>
<div
className={`hidden group-hover:block ${isMenuActive ? "!block" : ""}`}
onClick={(e) => e.stopPropagation()}
>
{quickActions({
issue: issueDetail,
parentRef: cellRef,
customActionButton,
portalElement: portalElement.current,
})}
</div>
</div>
</Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { SPREADSHEET_SELECT_GROUP } from "@plane/constants";
// ui
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
// components
import { Row } from "@plane/ui";
import { cn } from "@plane/utils";
import { MultipleSelectGroupAction } from "@/components/core/multiple-select";
// hooks
Expand Down Expand Up @@ -44,27 +43,31 @@ export const SpreadsheetHeader = observer(function SpreadsheetHeader(props: Prop
return (
<thead className="sticky top-0 left-0 z-[12] border-b-[0.5px] border-custom-border-100">
<tr>
{/* Single header column containing both identifier and workitem */}
<th
className="group/list-header sticky min-w-60 left-0 z-[15] h-11 flex items-center gap-1 bg-custom-background-90 text-sm font-medium before:absolute before:h-full before:right-0 before:border-custom-border-100"
className="group/list-header md:sticky min-w-60 left-0 z-[15] h-11 bg-custom-background-90 text-sm font-medium border-r-[0.5px] border-custom-border-100"
tabIndex={-1}
>
<Row>
{canSelectIssues && (
<div className="flex-shrink-0 flex items-center w-3.5 mr-1 absolute left-1 py-[11px]">
<MultipleSelectGroupAction
className={cn(
"size-3.5 opacity-0 pointer-events-none group-hover/list-header:opacity-100 group-hover/list-header:pointer-events-auto !outline-none",
{
"opacity-100 pointer-events-auto": !isGroupSelectionEmpty,
}
)}
groupID={SPREADSHEET_SELECT_GROUP}
selectionHelpers={selectionHelpers}
/>
</div>
)}
<span className="flex h-full w-full flex-grow items-center py-2.5">{`${isEpic ? "Epics" : "Work items"}`}</span>
</Row>
<div className="flex items-center gap-2 h-full w-full px-page-x">
{/* Workitem header section */}
<div className="flex items-center gap-1 flex-grow h-full py-2.5 min-w-80">
{canSelectIssues && (
<div className="flex-shrink-0 flex items-center w-3.5 mr-1">
<MultipleSelectGroupAction
className={cn(
"size-3.5 opacity-0 pointer-events-none group-hover/list-header:opacity-100 group-hover/list-header:pointer-events-auto !outline-none",
{
"opacity-100 pointer-events-auto": !isGroupSelectionEmpty,
}
)}
groupID={SPREADSHEET_SELECT_GROUP}
selectionHelpers={selectionHelpers}
/>
</div>
)}
<span className="text-sm font-medium">{`${isEpic ? "Epics" : "Work items"}`}</span>
</div>
</div>
</th>

{spreadsheetColumnsList.map((property) => (
Expand Down
8 changes: 4 additions & 4 deletions apps/web/core/components/project/create/common-attributes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function ProjectCommonAttributes(props: Props) {
return;
}
if (e.target.value === "") setValue("identifier", "");
else setValue("identifier", projectIdentifierSanitizer(e.target.value).substring(0, 5));
else setValue("identifier", projectIdentifierSanitizer(e.target.value).substring(0, 10));
onChange(e);
handleFormOnChange?.();
};
Expand Down Expand Up @@ -91,11 +91,11 @@ function ProjectCommonAttributes(props: Props) {
/^[ÇŞĞIİÖÜA-Z0-9]+$/.test(value.toUpperCase()) || t("only_alphanumeric_non_latin_characters_allowed"),
minLength: {
value: 1,
message: t("project_id_must_be_at_least_1_character"),
message: t("project_id_min_char"),
},
maxLength: {
value: 5,
message: t("project_id_must_be_at_most_5_characters"),
value: 10,
message: t("project_id_max_char"),
},
}}
render={({ field: { value, onChange } }) => (
Expand Down
6 changes: 3 additions & 3 deletions apps/web/core/components/project/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {

if (project.identifier !== formData.identifier)
await projectService
.checkProjectIdentifierAvailability(workspaceSlug as string, payload.identifier ?? "")
.checkProjectIdentifierAvailability(workspaceSlug, payload.identifier ?? "")
.then(async (res) => {
if (res.exists) setError("identifier", { message: t("common.identifier_already_exists") });
else await handleUpdateChange(payload);
Expand Down Expand Up @@ -338,7 +338,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
message: t("project_id_min_char"),
},
maxLength: {
value: 5,
value: 10,
message: t("project_id_max_char"),
},
}}
Expand All @@ -359,7 +359,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
/>
<Tooltip
isMobile={isMobile}
tooltipContent="Helps you identify work items in the project uniquely. Max 5 characters."
tooltipContent={t("project_id_tooltip_content")}
className="text-sm"
position="right-start"
>
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/cs/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,13 @@ export default {
project_id_must_be_at_least_1_character: "ID projektu musí mít alespoň 1 znak",
project_id_must_be_at_most_5_characters: "ID projektu může mít maximálně 5 znaků",
project_id: "ID projektu",
project_id_tooltip_content: "Pomáhá jednoznačně identifikovat pracovní položky v projektu. Max. 5 znaků.",
project_id_tooltip_content: "Pomáhá jednoznačně identifikovat pracovní položky v projektu. Max. 10 znaků.",
description_placeholder: "Popis",
only_alphanumeric_non_latin_characters_allowed: "Jsou povoleny pouze alfanumerické a nelatinské znaky.",
project_id_is_required: "ID projektu je povinné",
project_id_allowed_char: "Jsou povoleny pouze alfanumerické a nelatinské znaky.",
project_id_min_char: "ID projektu musí mít alespoň 1 znak",
project_id_max_char: "ID projektu může mít maximálně 5 znaků",
project_id_max_char: "ID projektu může mít maximálně 10 znaků",
project_description_placeholder: "Zadejte popis projektu",
select_network: "Vybrat síť",
lead: "Vedoucí",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/de/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,13 @@ export default {
project_id_must_be_at_least_1_character: "Projekt-ID muss mindestens 1 Zeichen lang sein",
project_id_must_be_at_most_5_characters: "Projekt-ID darf maximal 5 Zeichen lang sein",
project_id: "Projekt-ID",
project_id_tooltip_content: "Hilft, Arbeitselemente im Projekt eindeutig zu identifizieren. Max. 5 Zeichen.",
project_id_tooltip_content: "Hilft, Arbeitselemente im Projekt eindeutig zu identifizieren. Max. 10 Zeichen.",
description_placeholder: "Beschreibung",
only_alphanumeric_non_latin_characters_allowed: "Es sind nur alphanumerische und nicht-lateinische Zeichen erlaubt.",
project_id_is_required: "Projekt-ID ist erforderlich",
project_id_allowed_char: "Es sind nur alphanumerische und nicht-lateinische Zeichen erlaubt.",
project_id_min_char: "Projekt-ID muss mindestens 1 Zeichen lang sein",
project_id_max_char: "Projekt-ID darf maximal 5 Zeichen lang sein",
project_id_max_char: "Projekt-ID darf maximal 10 Zeichen lang sein",
project_description_placeholder: "Geben Sie eine Projektbeschreibung ein",
select_network: "Netzwerk auswählen",
lead: "Leitung",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/en/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,13 @@ export default {
project_id_must_be_at_least_1_character: "Project ID must at least be of 1 character",
project_id_must_be_at_most_5_characters: "Project ID must at most be of 5 characters",
project_id: "Project ID",
project_id_tooltip_content: "Helps you identify work items in the project uniquely. Max 5 characters.",
project_id_tooltip_content: "Helps you identify work items in the project uniquely. Max 10 characters.",
description_placeholder: "Description",
only_alphanumeric_non_latin_characters_allowed: "Only Alphanumeric & Non-latin characters are allowed.",
project_id_is_required: "Project ID is required",
project_id_allowed_char: "Only Alphanumeric & Non-latin characters are allowed.",
project_id_min_char: "Project ID must at least be of 1 character",
project_id_max_char: "Project ID must at most be of 5 characters",
project_id_max_char: "Project ID must at most be of 10 characters",
project_description_placeholder: "Enter project description",
select_network: "Select network",
lead: "Lead",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/es/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,13 @@ export default {
project_id_must_be_at_most_5_characters: "El ID del proyecto debe tener como máximo 5 caracteres",
project_id: "ID del proyecto",
project_id_tooltip_content:
"Te ayuda a identificar elementos de trabajo en el proyecto de manera única. Máximo 5 caracteres.",
"Te ayuda a identificar elementos de trabajo en el proyecto de manera única. Máximo 10 caracteres.",
description_placeholder: "Descripción",
only_alphanumeric_non_latin_characters_allowed: "Solo se permiten caracteres alfanuméricos y no latinos.",
project_id_is_required: "El ID del proyecto es requerido",
project_id_allowed_char: "Solo se permiten caracteres alfanuméricos y no latinos.",
project_id_min_char: "El ID del proyecto debe tener al menos 1 carácter",
project_id_max_char: "El ID del proyecto debe tener como máximo 5 caracteres",
project_id_max_char: "El ID del proyecto debe tener como máximo 10 caracteres",
project_description_placeholder: "Ingresa la descripción del proyecto",
select_network: "Seleccionar red",
lead: "Líder",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/fr/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,13 @@ export default {
project_id_must_be_at_most_5_characters: "L’ID du projet doit comporter au plus 5 caractères",
project_id: "ID du projet",
project_id_tooltip_content:
"Vous aide à identifier de manière unique les éléments de travail dans le projet. Maximum 5 caractères.",
"Vous aide à identifier de manière unique les éléments de travail dans le projet. Maximum 10 caractères.",
description_placeholder: "Description",
only_alphanumeric_non_latin_characters_allowed: "Seuls les caractères alphanumériques et non latins sont autorisés.",
project_id_is_required: "L’ID du projet est requis",
project_id_allowed_char: "Seuls les caractères alphanumériques et non latins sont autorisés.",
project_id_min_char: "L’ID du projet doit comporter au moins 1 caractère",
project_id_max_char: "LID du projet doit comporter au plus 5 caractères",
project_id_max_char: "L'ID du projet doit comporter au plus 10 caractères",
project_description_placeholder: "Entrez la description du projet",
select_network: "Sélectionner le réseau",
lead: "Responsable",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/id/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,13 @@ export default {
project_id_must_be_at_most_5_characters: "ID proyek maksimal 5 karakter",
project_id: "ID proyek",
project_id_tooltip_content:
"Membantu Anda mengidentifikasi item kerja dalam proyek secara unik. Maksimal 5 karakter.",
"Membantu Anda mengidentifikasi item kerja dalam proyek secara unik. Maksimal 10 karakter.",
description_placeholder: "Deskripsi",
only_alphanumeric_non_latin_characters_allowed: "Hanya karakter alfanumerik & Non-latin yang diizinkan.",
project_id_is_required: "ID proyek diperlukan",
project_id_allowed_char: "Hanya karakter alfanumerik & Non-latin yang diizinkan.",
project_id_min_char: "ID proyek harus minimal 1 karakter",
project_id_max_char: "ID proyek maksimal 5 karakter",
project_id_max_char: "ID proyek maksimal 10 karakter",
project_description_placeholder: "Masukkan deskripsi proyek",
select_network: "Pilih jaringan",
lead: "Pemimpin",
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/src/locales/it/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,13 @@ export default {
project_id_must_be_at_most_5_characters: "L'ID del progetto deve contenere al massimo 5 caratteri",
project_id: "ID del progetto",
project_id_tooltip_content:
"Ti aiuta a identificare in modo univoco gli elementi di lavoro nel progetto. Massimo 5 caratteri.",
"Ti aiuta a identificare in modo univoco gli elementi di lavoro nel progetto. Massimo 10 caratteri.",
description_placeholder: "Descrizione",
only_alphanumeric_non_latin_characters_allowed: "Sono ammessi solo caratteri alfanumerici e non latini.",
project_id_is_required: "L'ID del progetto è obbligatorio",
project_id_allowed_char: "Sono ammessi solo caratteri alfanumerici e non latini.",
project_id_min_char: "L'ID del progetto deve contenere almeno 1 carattere",
project_id_max_char: "L'ID del progetto deve contenere al massimo 5 caratteri",
project_id_max_char: "L'ID del progetto deve contenere al massimo 10 caratteri",
project_description_placeholder: "Inserisci la descrizione del progetto",
select_network: "Seleziona rete",
lead: "Responsabile",
Expand Down
Loading
Loading