@critical-path/svelte 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -171
- package/dist/workload-state.svelte.d.ts +26 -0
- package/dist/workload-state.svelte.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/index.test.ts +85 -2
- package/src/index.ts +1 -0
- package/src/workload-state.svelte.ts +83 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CriticalPathClient } from '@critical-path/client';
|
|
2
|
+
import type { WorkloadDistribution, WorkloadDistributionOptions, WorkloadInterval, WorkloadGroupBy, WorkloadMetric, WorkloadBucket } from '@critical-path/core';
|
|
3
|
+
export declare class WorkloadState {
|
|
4
|
+
private client;
|
|
5
|
+
projectId?: string | undefined;
|
|
6
|
+
initialOptions?: WorkloadDistributionOptions | undefined;
|
|
7
|
+
data: WorkloadDistribution | null;
|
|
8
|
+
interval: WorkloadInterval;
|
|
9
|
+
groupBy: WorkloadGroupBy;
|
|
10
|
+
metric: WorkloadMetric;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
error: Error | null;
|
|
13
|
+
buckets: WorkloadBucket[];
|
|
14
|
+
seriesKeys: string[];
|
|
15
|
+
seriesLabels: Record<string, string>;
|
|
16
|
+
totalHours: number;
|
|
17
|
+
totalCapacity: number;
|
|
18
|
+
averageUtilization: number | undefined;
|
|
19
|
+
constructor(client: CriticalPathClient, projectId?: string | undefined, initialOptions?: WorkloadDistributionOptions | undefined);
|
|
20
|
+
setInterval(newInterval: WorkloadInterval): Promise<void>;
|
|
21
|
+
setGroupBy(newGroupBy: WorkloadGroupBy): Promise<void>;
|
|
22
|
+
setMetric(newMetric: WorkloadMetric): Promise<void>;
|
|
23
|
+
fetch(options?: WorkloadDistributionOptions): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createWorkloadState(client: CriticalPathClient, projectId?: string, initialOptions?: WorkloadDistributionOptions): WorkloadState;
|
|
26
|
+
//# sourceMappingURL=workload-state.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-state.svelte.d.ts","sourceRoot":"","sources":["../src/workload-state.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,cAAc,EACf,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,aAAa;IAgBtB,OAAO,CAAC,MAAM;IACP,SAAS,CAAC,EAAE,MAAM;IAClB,cAAc,CAAC,EAAE,2BAA2B;IAjBrD,IAAI,8BAA6C;IACjD,QAAQ,mBAAoC;IAC5C,OAAO,kBAAuC;IAC9C,MAAM,iBAAqC;IAC3C,OAAO,UAA0B;IACjC,KAAK,eAA8B;IAEnC,OAAO,mBAAwD;IAC/D,UAAU,WAAmD;IAC7D,YAAY,yBAAmE;IAC/E,UAAU,SAAgD;IAC1D,aAAa,SAAmD;IAChE,kBAAkB,qBAA+D;gBAGvE,MAAM,EAAE,kBAAkB,EAC3B,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,cAAc,CAAC,EAAE,2BAA2B,YAAA;IAa/C,WAAW,CAAC,WAAW,EAAE,gBAAgB;IAKzC,UAAU,CAAC,UAAU,EAAE,eAAe;IAKtC,SAAS,CAAC,SAAS,EAAE,cAAc;IAKnC,KAAK,CAAC,OAAO,CAAC,EAAE,2BAA2B;CAiBlD;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,EAC1B,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,2BAA2B,GAC3C,aAAa,CAEf"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@critical-path/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Svelte 5 Runes state and reactive integrations for Critical Path headless project management framework",
|
|
5
5
|
"author": "Jack James",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@critical-path/client": "0.
|
|
22
|
-
"@critical-path/
|
|
23
|
-
"@critical-path/
|
|
21
|
+
"@critical-path/client": "0.12.0",
|
|
22
|
+
"@critical-path/core": "0.18.0",
|
|
23
|
+
"@critical-path/mcp": "0.5.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"svelte": "^5.0.0"
|
package/src/index.test.ts
CHANGED
|
@@ -28,7 +28,9 @@ import {
|
|
|
28
28
|
TimelineLadderState,
|
|
29
29
|
createTimelineLadderState,
|
|
30
30
|
TaskMetricsState,
|
|
31
|
-
createTaskMetricsState
|
|
31
|
+
createTaskMetricsState,
|
|
32
|
+
WorkloadState,
|
|
33
|
+
createWorkloadState
|
|
32
34
|
} from './index.js';
|
|
33
35
|
import type { CriticalPathClient } from '@critical-path/client';
|
|
34
36
|
import type {
|
|
@@ -40,7 +42,8 @@ import type {
|
|
|
40
42
|
Deliverable,
|
|
41
43
|
DeliverableSummary,
|
|
42
44
|
CriticalPathAnalysis,
|
|
43
|
-
TimelineLadder
|
|
45
|
+
TimelineLadder,
|
|
46
|
+
WorkloadDistribution
|
|
44
47
|
} from '@critical-path/core';
|
|
45
48
|
|
|
46
49
|
describe('@critical-path/svelte Svelte 5 Runes Test Suite', () => {
|
|
@@ -735,6 +738,86 @@ describe('@critical-path/svelte Svelte 5 Runes Test Suite', () => {
|
|
|
735
738
|
expect(state.curveProfile).toBe('linear');
|
|
736
739
|
});
|
|
737
740
|
});
|
|
741
|
+
|
|
742
|
+
describe('WorkloadState & createWorkloadState', () => {
|
|
743
|
+
it('initializes with default options and fetches workload distribution', async () => {
|
|
744
|
+
const mockDistribution: WorkloadDistribution = {
|
|
745
|
+
projectId: 'proj_wl',
|
|
746
|
+
startDate: '2026-09-01',
|
|
747
|
+
endDate: '2026-09-14',
|
|
748
|
+
interval: 'week',
|
|
749
|
+
groupBy: 'assignee',
|
|
750
|
+
metric: 'blended',
|
|
751
|
+
seriesKeys: ['u1', 'u2'],
|
|
752
|
+
seriesLabels: { u1: 'Alice', u2: 'Bob' },
|
|
753
|
+
buckets: [
|
|
754
|
+
{
|
|
755
|
+
date: '2026-09-01',
|
|
756
|
+
timestamp: 1788220800000,
|
|
757
|
+
totalHours: 40,
|
|
758
|
+
values: { u1: 25, u2: 15 },
|
|
759
|
+
capacity: { u1: 35, u2: 40 },
|
|
760
|
+
totalCapacity: 75,
|
|
761
|
+
utilizationRatio: 0.533
|
|
762
|
+
}
|
|
763
|
+
],
|
|
764
|
+
totalHours: 40,
|
|
765
|
+
totalCapacity: 75,
|
|
766
|
+
averageUtilization: 0.533
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
const mockClient = {
|
|
770
|
+
getWorkloadDistribution: vi.fn().mockResolvedValue(mockDistribution)
|
|
771
|
+
} as unknown as CriticalPathClient;
|
|
772
|
+
|
|
773
|
+
const state = createWorkloadState(mockClient, 'proj_wl', {
|
|
774
|
+
interval: 'week',
|
|
775
|
+
groupBy: 'assignee',
|
|
776
|
+
metric: 'blended'
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
expect(state.data).toBeNull();
|
|
780
|
+
expect(state.buckets).toEqual([]);
|
|
781
|
+
expect(state.seriesKeys).toEqual([]);
|
|
782
|
+
expect(state.totalHours).toBe(0);
|
|
783
|
+
|
|
784
|
+
await state.fetch();
|
|
785
|
+
|
|
786
|
+
expect(mockClient.getWorkloadDistribution).toHaveBeenCalledWith('proj_wl', {
|
|
787
|
+
interval: 'week',
|
|
788
|
+
groupBy: 'assignee',
|
|
789
|
+
metric: 'blended'
|
|
790
|
+
});
|
|
791
|
+
expect(state.data).toEqual(mockDistribution);
|
|
792
|
+
expect(state.buckets).toHaveLength(1);
|
|
793
|
+
expect(state.seriesKeys).toEqual(['u1', 'u2']);
|
|
794
|
+
expect(state.totalHours).toBe(40);
|
|
795
|
+
expect(state.totalCapacity).toBe(75);
|
|
796
|
+
expect(state.averageUtilization).toBe(0.533);
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
it('updates interval and re-fetches', async () => {
|
|
800
|
+
const mockClient = {
|
|
801
|
+
getWorkloadDistribution: vi.fn().mockResolvedValue({
|
|
802
|
+
buckets: [],
|
|
803
|
+
seriesKeys: [],
|
|
804
|
+
seriesLabels: {},
|
|
805
|
+
totalHours: 0,
|
|
806
|
+
totalCapacity: 0
|
|
807
|
+
})
|
|
808
|
+
} as unknown as CriticalPathClient;
|
|
809
|
+
|
|
810
|
+
const state = new WorkloadState(mockClient, 'proj_wl');
|
|
811
|
+
expect(state.interval).toBe('week');
|
|
812
|
+
|
|
813
|
+
await state.setInterval('day');
|
|
814
|
+
expect(state.interval).toBe('day');
|
|
815
|
+
expect(mockClient.getWorkloadDistribution).toHaveBeenCalledWith(
|
|
816
|
+
'proj_wl',
|
|
817
|
+
expect.objectContaining({ interval: 'day' })
|
|
818
|
+
);
|
|
819
|
+
});
|
|
820
|
+
});
|
|
738
821
|
});
|
|
739
822
|
|
|
740
823
|
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/// <reference types="svelte" />
|
|
2
|
+
import type { CriticalPathClient } from '@critical-path/client';
|
|
3
|
+
import type {
|
|
4
|
+
WorkloadDistribution,
|
|
5
|
+
WorkloadDistributionOptions,
|
|
6
|
+
WorkloadInterval,
|
|
7
|
+
WorkloadGroupBy,
|
|
8
|
+
WorkloadMetric,
|
|
9
|
+
WorkloadBucket
|
|
10
|
+
} from '@critical-path/core';
|
|
11
|
+
|
|
12
|
+
export class WorkloadState {
|
|
13
|
+
data = $state<WorkloadDistribution | null>(null);
|
|
14
|
+
interval = $state<WorkloadInterval>('week');
|
|
15
|
+
groupBy = $state<WorkloadGroupBy>('assignee');
|
|
16
|
+
metric = $state<WorkloadMetric>('blended');
|
|
17
|
+
loading = $state<boolean>(false);
|
|
18
|
+
error = $state<Error | null>(null);
|
|
19
|
+
|
|
20
|
+
buckets = $derived<WorkloadBucket[]>(this.data?.buckets ?? []);
|
|
21
|
+
seriesKeys = $derived<string[]>(this.data?.seriesKeys ?? []);
|
|
22
|
+
seriesLabels = $derived<Record<string, string>>(this.data?.seriesLabels ?? {});
|
|
23
|
+
totalHours = $derived<number>(this.data?.totalHours ?? 0);
|
|
24
|
+
totalCapacity = $derived<number>(this.data?.totalCapacity ?? 0);
|
|
25
|
+
averageUtilization = $derived<number | undefined>(this.data?.averageUtilization);
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
private client: CriticalPathClient,
|
|
29
|
+
public projectId?: string,
|
|
30
|
+
public initialOptions?: WorkloadDistributionOptions
|
|
31
|
+
) {
|
|
32
|
+
if (initialOptions?.interval) {
|
|
33
|
+
this.interval = initialOptions.interval;
|
|
34
|
+
}
|
|
35
|
+
if (initialOptions?.groupBy) {
|
|
36
|
+
this.groupBy = initialOptions.groupBy;
|
|
37
|
+
}
|
|
38
|
+
if (initialOptions?.metric) {
|
|
39
|
+
this.metric = initialOptions.metric;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async setInterval(newInterval: WorkloadInterval) {
|
|
44
|
+
this.interval = newInterval;
|
|
45
|
+
await this.fetch();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async setGroupBy(newGroupBy: WorkloadGroupBy) {
|
|
49
|
+
this.groupBy = newGroupBy;
|
|
50
|
+
await this.fetch();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async setMetric(newMetric: WorkloadMetric) {
|
|
54
|
+
this.metric = newMetric;
|
|
55
|
+
await this.fetch();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async fetch(options?: WorkloadDistributionOptions) {
|
|
59
|
+
this.loading = true;
|
|
60
|
+
this.error = null;
|
|
61
|
+
try {
|
|
62
|
+
this.data = await this.client.getWorkloadDistribution(this.projectId, {
|
|
63
|
+
...this.initialOptions,
|
|
64
|
+
interval: this.interval,
|
|
65
|
+
groupBy: this.groupBy,
|
|
66
|
+
metric: this.metric,
|
|
67
|
+
...options
|
|
68
|
+
});
|
|
69
|
+
} catch (err) {
|
|
70
|
+
this.error = err instanceof Error ? err : new Error(String(err));
|
|
71
|
+
} finally {
|
|
72
|
+
this.loading = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function createWorkloadState(
|
|
78
|
+
client: CriticalPathClient,
|
|
79
|
+
projectId?: string,
|
|
80
|
+
initialOptions?: WorkloadDistributionOptions
|
|
81
|
+
): WorkloadState {
|
|
82
|
+
return new WorkloadState(client, projectId, initialOptions);
|
|
83
|
+
}
|