npm package: @svar-ui/lib-mspx
Description: Convert between Microsoft Project XML and SVAR Gantt format
Latest version: 0.2.0

# mspx

A JavaScript library for converting between Microsoft Project XML format and SVAR Gantt JSON format.

## Installation

```bash
npm install mspx
```

## Usage

### Converting MS Project XML to Gantt format

```javascript
import { mspx2gantt } from "mspx";

const xml = `<?xml version="1.0" encoding="UTF-8"?>
<Project xmlns="http://schemas.microsoft.com/project/2003">
  <Tasks>
    <Task>
      <UID>1</UID>
      <Name>Design Phase</Name>
      <Start>2024-02-01T08:00:00</Start>
      <Finish>2024-02-15T17:00:00</Finish>
      <Duration>PT336H0M0S</Duration>
      <PercentComplete>50</PercentComplete>
    </Task>
  </Tasks>
</Project>`;

const ganttData = mspx2gantt(xml);
// Result:
// {
//   tasks: [
//     {
//       id: 1,
//       text: "Design Phase",
//       start: Date,
//       end: Date,
//       duration: 14,
//       progress: 50,
//       type: "task"
//     }
//   ],
//   links: []
// }
```

### Converting Gantt format to MS Project XML

```javascript
import { gantt2mspx } from "mspx";

const ganttData = {
  tasks: [
    {
      id: 1,
      text: "Design Phase",
      start: new Date("2024-02-01T08:00:00Z"),
      end: new Date("2024-02-15T17:00:00Z"),
      duration: 14,
      progress: 50,
    },
    {
      id: 2,
      text: "Development",
      start: new Date("2024-02-16T08:00:00Z"),
      end: new Date("2024-03-15T17:00:00Z"),
      duration: 28,
    },
  ],
  links: [
    { source: 1, target: 2, type: "e2s" }
  ],
};

const xml = gantt2mspx(ganttData);
```

### Downloading as file (browser)

```javascript
import { gantt2mspx, downloadAs } from "mspx";

const xml = gantt2mspx(ganttData);
downloadAs(xml, "project.xml");
```

## Data Format

### Tasks

```typescript
interface GanttTask {
  id?: string | number;
  text?: string;              // Task name
  start?: Date;               // Start date
  end?: Date;                 // End date
  duration?: number;          // Duration in days (24-hour days)
  progress?: number;          // Percent complete (0-100)
  type?: "task" | "summary" | "milestone";
  parent?: string | number;   // Parent task ID
  $level?: number;            // Hierarchy level (1 = top level)
  details?: string;           // Notes/description

  // Baseline values
  base_start?: Date;
  base_end?: Date;
  base_duration?: number;
}
```

**Note:** Tasks should be ordered hierarchically (parent → children → grandchildren → next parent). The `$level` property indicates the nesting depth (1 = top level, 2 = child, etc.). When exporting with `gantt2mspx`, summary tasks are auto-detected if the next task has a higher `$level`.

### Links

```typescript
interface GanttLink {
  id?: string | number;
  source: string | number;    // Source task ID
  target: string | number;    // Target task ID
  type: "s2s" | "s2e" | "e2s" | "e2e";
}
```

### Link Types

| Gantt | MS Project | Description |
|-------|------------|-------------|
| `e2s` | FS | Finish-to-Start (default) |
| `s2s` | SS | Start-to-Start |
| `e2e` | FF | Finish-to-Finish |
| `s2e` | SF | Start-to-Finish |

## Features

- Converts tasks with hierarchy (parent-child relationships)
- Supports all dependency link types
- Handles milestones and summary tasks
- Preserves baseline data (base_start, base_end, base_duration)
- Duration in 24-hour days
- Progress/percent complete
- Task notes/details

## Examples

### Working with hierarchical tasks

```javascript
// Tasks must be ordered: parent → children → next parent
// $level indicates depth (1 = top level)
const ganttData = {
  tasks: [
    { id: 1, text: "Project Planning", $level: 1 },  // Auto-detected as summary
    { id: 2, text: "Requirements", $level: 2 },
    { id: 3, text: "Design", $level: 2 },
    { id: 4, text: "Development", $level: 1 },
  ],
  links: [
    { source: 2, target: 3, type: "e2s" },
    { source: 1, target: 4, type: "e2s" },
  ],
};

const xml = gantt2mspx(ganttData);
// Task 1 will have Summary=1 because task 2 has higher $level
```

### Working with baselines

```javascript
const ganttData = {
  tasks: [
    {
      id: 1,
      text: "Task with slippage",
      $level: 1,
      // Actual dates (delayed)
      start: new Date("2024-02-10"),
      end: new Date("2024-02-25"),
      duration: 15,
      // Original baseline dates
      base_start: new Date("2024-02-01"),
      base_end: new Date("2024-02-15"),
      base_duration: 14,
    },
  ],
  links: [],
};
```

### Milestones

```javascript
const ganttData = {
  tasks: [
    {
      id: 1,
      text: "Project Kickoff",
      $level: 1,
      type: "milestone",
      start: new Date("2024-02-01"),
      end: new Date("2024-02-01"),
      duration: 0,
    },
  ],
  links: [],
};
```

### Complete workflow

```javascript
import { mspx2gantt, gantt2mspx, downloadAs } from "mspx";

// 1. Load MS Project XML file
const response = await fetch("project.xml");
const xml = await response.text();

// 2. Convert to Gantt format for editing
const ganttData = mspx2gantt(xml);

// 3. Modify tasks
ganttData.tasks[0].progress = 75;
ganttData.tasks.push({
  id: 100,
  text: "New Task",
  start: new Date(),
  duration: 5,
});

// 4. Convert back to XML
const updatedXml = gantt2mspx(ganttData);

// 5. Download the file
downloadAs(updatedXml, "updated-project.xml");
```

## API Reference

### mspx2gantt(xmlString: string, options?: Mspx2GanttOptions): GanttData

Converts MS Project XML string to Gantt data format.

**Parameters:**
- `xmlString` - MS Project XML content as string
- `options` - Optional configuration object:
  - `openSummary` - If `true` (default), summary tasks will have `open: true` for expanded tree view. Set to `false` to disable.

**Returns:**
- `GanttData` object with `tasks` and `links` arrays

**Example:**
```javascript
// Default: summary tasks are open
const data = mspx2gantt(xml);

// Disable auto-open for summary tasks
const data = mspx2gantt(xml, { openSummary: false });
```

### gantt2mspx(data: GanttData): string

Converts Gantt data to MS Project XML string.

**Parameters:**
- `data` - Object with `tasks` and `links` arrays

**Returns:**
- MS Project XML as string

### downloadAs(content: string | Blob, filename: string, contentType?: string): void

Downloads content as a file in the browser.

**Parameters:**
- `content` - Text content or Blob to download
- `filename` - Name for the downloaded file
- `contentType` - Optional MIME type (default: `"text/xml;charset=utf-8"` for strings, Blob's original type for Blobs)

## License

MIT