import { ReactElement } from "react";
import { ProjectCardLabel, ProjectCardPerson, TaskCardLabel } from "../stackedCard/content";
/**
 * The board's third "draw a box, then say what goes in it" element, after the
 * link and the file card. The gesture ladder is deliberately the same one those
 * two already established, because it is the only one the dock teaches:
 *
 *   armed      the Project Elements dock button opens a submenu (Project /
 *              Task); picking one arms the tool and puts the canvas in
 *              crosshair mode.
 *   drawn      mouse down → drag → up leaves a dashed PLACEHOLDER at the drawn
 *              box (clamped to a card-sized minimum), exactly where the real
 *              card will sit.
 *   picking    the release opens the picker — a centred popover replicating the
 *              app's `MenuSelector/ProjectList` (and, for tasks, the two-step
 *              `ProjectTaskMenuSelector`: projects, then that project's tasks).
 *   resolving  a short skeleton flash in the placeholder's own box, standing in
 *              for "the board is fetching this record's details".
 *   resolved   the placeholder becomes the real card, anchored at the
 *              placeholder's top-left and grown to the card's natural size.
 *
 * Escape or a click on the overlay cancels: the picker closes and the
 * placeholder is thrown away, so a cancelled gesture leaves no debris.
 */
export declare const PLACEHOLDER_MIN_WIDTH = 260;
export declare const PLACEHOLDER_MIN_HEIGHT = 120;
export declare const PROJECT_CARD_WIDTH = 300;
export declare const TASK_CARD_WIDTH = 260;
export declare const RESOLVE_MS = 480;
export type ProjectElementKind = "project" | "task";
export type ProjectElementStatus = "placeholder" | "resolving" | "resolved";
/** True for the two board tools this module owns. */
export declare const isProjectTool: (tool: string) => tool is ProjectElementKind;
/**
 * The people and labels the board carries are exactly what the shared content
 * cards read, so the picker's types ARE the cards' types — one shape, so a card
 * cannot be fed something it does not understand.
 */
export type PickerPerson = ProjectCardPerson;
export type PickerTaskLabel = TaskCardLabel;
export interface PickerTask {
    id: string;
    /** The task number the app prefixes the name with (`#123: …`). */
    number: number;
    name: string;
    /** The task list the task belongs to — the picker's group header. */
    taskList: string;
    label?: PickerTaskLabel;
    subtasks?: number;
    comments?: number;
    date?: string;
    assignees: PickerPerson[];
}
/**
 * A project label. The app renders it as a FILLED pill whose background is the
 * label's own colour and whose text is a darker shade of it
 * (`ProjectLabel.jsx`: `EntityLabel` with `backgroundColor: label.color` and
 * `color: label.darker_text_color`), which is the design system's `Chip` — not
 * the colour-text `Tag` the column cards use. Both colours are data. The shape
 * is the shared `ProjectCard`'s own.
 */
export type PickerProjectLabel = ProjectCardLabel;
export interface PickerProject {
    id: string;
    name: string;
    /**
     * The client company, and the picker's group header. NULL for an internal
     * project: the card then reads "Internal" rather than repeating the owner
     * company's own name back at the reader, which says nothing.
     */
    client: string | null;
    /** The description excerpt, when the project has one. */
    description?: string;
    /** A project need not have a leader. */
    lead?: PickerPerson;
    /** A project need not have a label. */
    label?: PickerProjectLabel;
    tasks: PickerTask[];
}
/**
 * What an internal project's client line says. The word belongs to the card (it
 * is the card that has to decide what to print for a project with no client), so
 * the board re-exports the card's own constant rather than keeping a second copy
 * that could drift.
 */
export declare const INTERNAL_CLIENT_LABEL = "Internal";
export declare const projectClientLabel: (project: PickerProject) => string;
export interface PickerProjectGroup {
    client: string;
    projects: PickerProject[];
}
export interface PickerTaskGroup {
    taskList: string;
    tasks: PickerTask[];
}
export declare const PICKER_PEOPLE: Record<string, PickerPerson>;
export declare const PICKER_LABELS: Record<string, PickerTaskLabel>;
export declare const PICKER_PROJECT_LABELS: Record<string, PickerProjectLabel>;
export declare const PICKER_PROJECTS: PickerProject[];
export declare const groupProjects: (projects: PickerProject[]) => PickerProjectGroup[];
export declare const groupTasks: (tasks: PickerTask[]) => PickerTaskGroup[];
/** `#123: Name` — `utils/taskDisplayName`, the app's own task display name. */
export declare const taskDisplayName: (task: PickerTask) => string;
/**
 * A board is shared with people who do not all see the same projects. When a
 * card points at a task or project the current viewer cannot open, the board
 * cannot just drop it: the element is part of everyone else's layout, and a
 * hole would be a worse lie than a blank. So the card stays and says exactly
 * one thing — something is here, and it is not yours to see.
 *
 * This follows the app's existing limited-access language (Workload):
 *   - the wording is "Limited Access", the phrase `EntityPlaceholder`,
 *     `WorkloadCalendarEvent`, Expenses and Timelist all already use;
 *   - nothing else is rendered. Workload's own limited cell
 *     (`.workload_null_project_cell`) shows an aggregate and no name, and the
 *     shape it is fed is literally `{ hoursOccupied, leftOffset }` — a quantity
 *     and a position, never an identity;
 *   - the surface is muted and hatched, the treatment the app reserves for
 *     "this area is not live" (weekend / day-off cells, `--muted-surface`);
 *   - no affordance suggests opening: Workload points the link at "#", disables
 *     the name tooltip so the title cannot leak, and marks blocked interactions
 *     `cursor: not-allowed`.
 */
export declare const LIMITED_ACCESS_LABEL = "Limited Access";
export declare const LIMITED_ACCESS_MESSAGE = "You don't have access to this item.";
/** A project / task element on the board. Position lives in `positions`. */
export interface ProjectElementDef {
    id: string;
    kind: ProjectElementKind;
    /**
     * The element's width — the drawn placeholder box first, then the card's
     * natural width, written once when the card resolves.
     *
     * It is one field and not two (a placeholder box plus a derived card width)
     * because the Inspector edits this: a derived width would be read-only by
     * construction, and a second stored width would be a copy that can disagree.
     */
    width: number;
    /** The placeholder box height. A resolved card is auto-height. */
    height: number;
    status: ProjectElementStatus;
    /**
     * The viewer cannot access what this card points at, so there is nothing to
     * fill `project` / `task` with and never will be — the details are withheld
     * by the server, not merely unfetched. Everything the card can do is
     * withheld with them: it does not move, resize or open.
     */
    limited?: boolean;
    /** Filled once the picker returns; for a task this is its project. */
    project: PickerProject | null;
    task: PickerTask | null;
}
/** The natural width a resolved card of this kind grows to. */
export declare const projectCardWidth: (kind: ProjectElementKind) => number;
/**
 * What the card is OF — the task's or the project's own name.
 *
 * These cards are a view of a record that lives in the project, so the board
 * does not get to name them: the title is the entity's, and it is read-only
 * wherever it appears. A placeholder has no entity yet, so it says what it is
 * still waiting for.
 */
export declare const projectElementTitle: (element: ProjectElementDef) => string;
export declare const SEEDED_PROJECT_ELEMENTS: ProjectElementDef[];
export declare const SEEDED_PROJECT_ELEMENT_POSITIONS: Record<string, {
    x: number;
    y: number;
}>;
export declare const StyledProjectElementBox: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const StyledProjectDraft: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const StyledPlaceholder: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const StyledResolving: import("styled-components").StyledComponent<"div", any, {}, never>;
/**
 * The limited-access face — the card-shaped translation of Workload's black
 * `.workload_null_project_cell`.
 *
 * The app hardcodes that cell `#000000` on `#ffffff` text, which works there
 * because it always sits on light paper. A canvas is not always light: on the
 * dark board a black slab would sink into the background instead of reading as
 * something withheld. So the same idea is expressed with the design system's
 * own "not live" tokens — `--muted-surface` / `--muted-surface-text` are the
 * pair the app itself substitutes for muted surfaces in dark themes, and they
 * are a legible, deliberately flat combination in every theme.
 *
 * The -45° hatch is copied stroke for stroke from the app's unavailable
 * surfaces (weekend and day-off cells): `transparent 5px, <line> 5px, <line>
 * 5.7px`, with `--stripe-pattern` as the line — the token workload.less uses
 * for exactly this in dark themes.
 */
export declare const StyledLimitedCard: import("styled-components").StyledComponent<"div", any, {}, never>;
export interface TaskFaceProps {
    project: PickerProject;
    task: PickerTask;
    selected?: boolean;
}
/**
 * The task face — the shared `TaskCard`, with the project line switched on.
 *
 * The board writes no anatomy of its own: the title clamp, the info line (labels
 * as colour text, the counter signifiers and their 2px dot separators) and the
 * date / assignees row all live in the content card, where the column-view
 * baseline they preserve is documented. The one thing the board asks for is the
 * project line above the title: on a canvas a task card has lost the column that
 * used to say which project it came from.
 *
 * The title is the app's own display name (`#123: Name`, `taskDisplayName`), so
 * the card's separate task-number prefix stays off.
 */
export declare const TaskElementCard: ({ project, task, selected, }: TaskFaceProps) => ReactElement;
/**
 * The project face — the shared `ProjectCard`.
 *
 * The whiteboard's face spec and the content type's are the SAME spec, so it is
 * implemented once, in the card: name and client, an optional description
 * excerpt, and one row carrying the leader on the left and the label on the
 * right. No progress indicator, and no row at all when the project has neither a
 * leader nor a label.
 */
export declare const ProjectElementCard: ({ project, selected, }: {
    project: PickerProject;
    selected?: boolean;
}) => ReactElement;
/**
 * The limited-access card. Deliberately the shortest component in this file:
 * one phrase, no icon, no entity data of any kind.
 *
 * No icon because the app uses none — Expenses and Timelist both render the
 * bare `Caption1 weight="bold"` "Limited Access", and an icon here would be a
 * second signal competing with the hatch. Even the KIND (task vs project) is
 * withheld: the viewer is told that a card exists, not what sort of thing it
 * points at.
 *
 * The tooltip is allowed to exist because it carries the viewer's situation,
 * not the entity's identity — the opposite of the tooltip Workload disables on
 * a limited event, which would have leaked the name.
 */
export declare const LimitedElementCard: () => ReactElement;
/** One board element, in whichever of its three states it currently is. */
export declare const ProjectElementNode: ({ element, selected, }: {
    element: ProjectElementDef;
    /**
     * Host-owned selection. A resolved card is a `StackedCard`, and the shell draws
     * its own ring from `--sc-selection-ring` (the board sets it to the selection
     * blue) — the same arrangement the link and file cards already use, which is
     * why their wrapper carries `is-card` to suppress the box's second ring.
     */
    selected?: boolean;
}) => ReactElement;
export interface PickerRowProps {
    id: string;
    name: string;
    onSelect: () => void;
}
export interface ProjectElementPickerProps {
    kind: ProjectElementKind;
    onSelectProject: (project: PickerProject) => void;
    onSelectTask: (project: PickerProject, task: PickerTask) => void;
    onCancel: () => void;
}
/**
 * One picker, two flows — the same split the app makes between
 * `MenuSelector/ProjectList` (one step) and `ProjectTaskMenuSelector` (project,
 * then task). The task flow deliberately drops the app's "Directly on project"
 * default option: a task card has to be a task.
 */
export declare const ProjectElementPicker: ({ kind, onSelectProject, onSelectTask, onCancel, }: ProjectElementPickerProps) => ReactElement;
//# sourceMappingURL=projectElements.d.ts.map