feat: project cover art with AI generation, branding rename, RBAC fix, computation graph
- Add DALL-E cover art generation for projects (Azure OpenAI + standard OpenAI)
- CoverArtSection component with generate/upload/remove/focus-point controls
- Client-side image compression (10MB input → WebP/JPEG, max 1920px)
- DALL-E settings in admin panel (deployment, endpoint, API key)
- MCP assistant tools for cover art (generate_project_cover, remove_project_cover)
- Rename "Planarchy" → "plANARCHY" across all UI-facing text (13 files)
- Fix hardcoded canEdit={true} on project detail page — now checks user role
- Computation graph visualization (2D/3D) for calculation rules
- OG image and OpenGraph metadata
Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -6,6 +6,7 @@ import { OrderType, AllocationType, ProjectStatus } from "@planarchy/shared";
|
||||
import type { Project } from "@planarchy/shared";
|
||||
import { trpc } from "~/lib/trpc/client.js";
|
||||
import { DateInput } from "~/components/ui/DateInput.js";
|
||||
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
|
||||
|
||||
const ORDER_TYPE_OPTIONS = [
|
||||
{ value: "BD", label: "BD" },
|
||||
@@ -283,6 +284,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="shortCode">
|
||||
Chargecode <span className="text-red-500">*</span>
|
||||
<InfoTooltip content="Unique project identifier for time tracking and cost attribution. Cannot be changed after creation." />
|
||||
</label>
|
||||
<input
|
||||
id="shortCode"
|
||||
@@ -306,6 +308,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="name">
|
||||
Name <span className="text-red-500">*</span>
|
||||
<InfoTooltip content="Display name shown on the timeline and in reports." />
|
||||
</label>
|
||||
<input
|
||||
id="name"
|
||||
@@ -331,6 +334,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="orderType">
|
||||
Order Type
|
||||
<InfoTooltip content="BD = Business Development (pre-sales), CHARGEABLE = billable client work, INTERNAL = internal project, OVERHEAD = non-project overhead." />
|
||||
</label>
|
||||
<select
|
||||
id="orderType"
|
||||
@@ -348,6 +352,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="allocationType">
|
||||
Allocation
|
||||
<InfoTooltip content="INT = staffed with internal resources, EXT = staffed with external contractors or freelancers." />
|
||||
</label>
|
||||
<select
|
||||
id="allocationType"
|
||||
@@ -365,6 +370,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="winProbability">
|
||||
Win Probability %
|
||||
<InfoTooltip content="Likelihood of winning this project (0-100%). Affects the weighted pipeline value: budget x probability." />
|
||||
</label>
|
||||
<input
|
||||
id="winProbability"
|
||||
@@ -391,6 +397,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="utilizationCategoryId">
|
||||
Utilization Category
|
||||
<InfoTooltip content="Groups projects for chargeability and utilization reporting. Determines how hours count toward resource utilization." />
|
||||
</label>
|
||||
<select
|
||||
id="utilizationCategoryId"
|
||||
@@ -409,6 +416,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="clientId">
|
||||
Client
|
||||
<InfoTooltip content="The client or customer this project is for. Used for filtering and reporting." />
|
||||
</label>
|
||||
<select
|
||||
id="clientId"
|
||||
@@ -437,6 +445,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="startDate">
|
||||
Start Date
|
||||
<InfoTooltip content="First day of the project period. Assignments begin from this date." />
|
||||
</label>
|
||||
<DateInput
|
||||
id="startDate"
|
||||
@@ -451,6 +460,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="endDate">
|
||||
End Date
|
||||
<InfoTooltip content="Last day of the project period. Must be on or after the start date." />
|
||||
</label>
|
||||
<DateInput
|
||||
id="endDate"
|
||||
@@ -466,6 +476,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="budgetEur">
|
||||
Budget (€)
|
||||
<InfoTooltip content="Total project budget in EUR. Tracked against the sum of assignment costs (hours x daily rate)." />
|
||||
</label>
|
||||
<input
|
||||
id="budgetEur"
|
||||
@@ -493,6 +504,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="status">
|
||||
Status
|
||||
<InfoTooltip content="DRAFT = not visible on timeline, ACTIVE = in progress, ON_HOLD = paused, COMPLETED = finished, CANCELLED = abandoned." />
|
||||
</label>
|
||||
<select
|
||||
id="status"
|
||||
@@ -510,6 +522,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="responsiblePerson">
|
||||
Responsible Person
|
||||
<InfoTooltip content="Project lead or account manager responsible for this project." />
|
||||
</label>
|
||||
<input
|
||||
id="responsiblePerson"
|
||||
@@ -523,6 +536,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
||||
<div>
|
||||
<label className={labelClass} htmlFor="projectColor">
|
||||
Timeline Color
|
||||
<InfoTooltip content="Custom color for this project's bars on the timeline view. Leave empty for the default color." />
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user