@26lights/orcha 0.42.186 → 0.42.188

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.
@@ -6,6 +6,10 @@ interface CreateSprintPayload {
6
6
  endDate: string;
7
7
  }
8
8
  declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
9
+ milestoneId: {
10
+ type: import("vue").PropType<string>;
11
+ default: undefined;
12
+ };
9
13
  isEditable: {
10
14
  type: import("vue").PropType<boolean | "only-own">;
11
15
  required: true;
@@ -34,10 +38,6 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
34
38
  type: import("vue").PropType<ActivityType[]>;
35
39
  default: () => never[];
36
40
  };
37
- milestoneId: {
38
- type: import("vue").PropType<string>;
39
- default: undefined;
40
- };
41
41
  templateActivities: {
42
42
  type: import("vue").PropType<(Activity | ActivityFeed<import('../types/index').ActivityFeedStatus>)[]>;
43
43
  required: true;
@@ -94,6 +94,10 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
94
94
  toast: (messageKey: string, type: "error" | "success") => void;
95
95
  createSprint: (payload: CreateSprintPayload) => void;
96
96
  }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
97
+ milestoneId: {
98
+ type: import("vue").PropType<string>;
99
+ default: undefined;
100
+ };
97
101
  isEditable: {
98
102
  type: import("vue").PropType<boolean | "only-own">;
99
103
  required: true;
@@ -122,10 +126,6 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
122
126
  type: import("vue").PropType<ActivityType[]>;
123
127
  default: () => never[];
124
128
  };
125
- milestoneId: {
126
- type: import("vue").PropType<string>;
127
- default: undefined;
128
- };
129
129
  templateActivities: {
130
130
  type: import("vue").PropType<(Activity | ActivityFeed<import('../types/index').ActivityFeedStatus>)[]>;
131
131
  required: true;
@@ -182,11 +182,11 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
182
182
  onToast?: ((messageKey: string, type: "error" | "success") => any) | undefined;
183
183
  onCreateSprint?: ((payload: CreateSprintPayload) => any) | undefined;
184
184
  }>, {
185
+ milestoneId: string;
185
186
  breadcrumbs: string;
186
187
  userId: string;
187
188
  isTemplate: boolean;
188
189
  activityTypes: ActivityType[];
189
- milestoneId: string;
190
190
  templateMilestones: Milestone[];
191
191
  isTaskCheckable: (task: Subtask) => boolean;
192
192
  statuses: ActivityStatus[];
@@ -1,11 +1,142 @@
1
1
  import type { BulkStructureConvention, BulkStructureEntityType, BulkStructureRoot } from '../types/bulkStructure';
2
+ /**
3
+ * Canonical hierarchy used by the bulk insert feature.
4
+ *
5
+ * The order defines the allowed nesting:
6
+ *
7
+ * phase
8
+ * milestone
9
+ * activity
10
+ * task
11
+ *
12
+ * Depending on where bulk insert is opened, the hierarchy starts
13
+ * at a different level.
14
+ *
15
+ * Examples:
16
+ *
17
+ * getLevelsForRoot('phase')
18
+ * -> ['phase', 'milestone', 'activity', 'task']
19
+ *
20
+ * getLevelsForRoot('milestone')
21
+ * -> ['milestone', 'activity', 'task']
22
+ *
23
+ * getLevelsForRoot('activity')
24
+ * -> ['activity', 'task']
25
+ */
2
26
  export declare const HIERARCHY: readonly BulkStructureEntityType[];
27
+ /**
28
+ * Canonical indentation convention.
29
+ *
30
+ * One hierarchy level currently equals one space.
31
+ *
32
+ * Example:
33
+ *
34
+ * Phase 1
35
+ * Milestone 1
36
+ * Activity 1
37
+ * Task 1
38
+ *
39
+ * The parser and the UI example generator both rely on this
40
+ * configuration so they always use the same indentation rules.
41
+ */
3
42
  export declare const INDENT_CONFIG: {
4
43
  readonly indentSize: 1;
5
44
  readonly indentCharacter: " ";
6
45
  };
46
+ /**
47
+ * Returns the hierarchy levels available from a given root type.
48
+ *
49
+ * Example:
50
+ *
51
+ * getLevelsForRoot('milestone')
52
+ *
53
+ * returns:
54
+ *
55
+ * ['milestone', 'activity', 'task']
56
+ *
57
+ * This is what allows the same parser to work when bulk insert is
58
+ * opened from a phase, milestone or activity.
59
+ */
7
60
  export declare function getLevelsForRoot(rootType: BulkStructureRoot): BulkStructureEntityType[];
61
+ /**
62
+ * Returns the complete convention used by the parser for a root type.
63
+ *
64
+ * Example:
65
+ *
66
+ * getBulkStructureConvention('milestone')
67
+ *
68
+ * returns:
69
+ *
70
+ * {
71
+ * rootType: 'milestone',
72
+ * levels: ['milestone', 'activity', 'task'],
73
+ * indentSize: 1,
74
+ * indentCharacter: ' '
75
+ * }
76
+ *
77
+ * The parser can then map indentation level to entity type:
78
+ *
79
+ * Milestone 1 -> level 0 -> milestone
80
+ * Activity 1 -> level 1 -> activity
81
+ * Task 1 -> level 2 -> task
82
+ */
8
83
  export declare function getBulkStructureConvention(rootType: BulkStructureRoot): BulkStructureConvention;
84
+ /**
85
+ * Returns the string representing exactly one indentation level.
86
+ *
87
+ * With the current configuration:
88
+ *
89
+ * getIndentUnit()
90
+ * -> ' '
91
+ *
92
+ * If indentSize became 2:
93
+ *
94
+ * getIndentUnit()
95
+ * -> ' '
96
+ */
9
97
  export declare function getIndentUnit(convention?: Pick<BulkStructureConvention, 'indentCharacter' | 'indentSize'>): string;
98
+ /**
99
+ * Returns the indentation prefix for a specific hierarchy level.
100
+ *
101
+ * With the current one-space convention:
102
+ *
103
+ * getIndentPrefix(0) -> ''
104
+ * getIndentPrefix(1) -> ' '
105
+ * getIndentPrefix(2) -> ' '
106
+ * getIndentPrefix(3) -> ' '
107
+ *
108
+ * This is mainly used to generate examples that follow exactly
109
+ * the same convention as the parser.
110
+ */
10
111
  export declare function getIndentPrefix(level: number, convention?: Pick<BulkStructureConvention, 'indentCharacter' | 'indentSize'>): string;
112
+ /**
113
+ * Generates a textual example of the hierarchy for a given root type.
114
+ *
115
+ * This helper is responsible for hierarchy and indentation only.
116
+ * It does not contain user-facing labels or translations.
117
+ *
118
+ * Labels are provided by the caller through getLabel().
119
+ *
120
+ * Example:
121
+ *
122
+ * getBulkStructureExample(
123
+ * 'phase',
124
+ * getLabel,
125
+ * )
126
+ *
127
+ * can output:
128
+ *
129
+ * Phase
130
+ * Milestone
131
+ * Activity
132
+ * Task
133
+ *
134
+ * The modal can then transform that into:
135
+ *
136
+ * Phase 1
137
+ * Milestone 1
138
+ * Activity 1
139
+ * Task 1
140
+ * ...
141
+ */
11
142
  export declare function getBulkStructureExample(rootType: BulkStructureRoot, getLabel: (type: BulkStructureEntityType) => string): string;
@@ -1,4 +1,156 @@
1
1
  import type { BulkStructureEntityType, BulkStructureNode, BulkStructureParseResult, BulkStructureRoot } from '../types/bulkStructure';
2
+ /**
3
+ * Parses bulk text into a generic hierarchical structure.
4
+ *
5
+ * The parser is responsible for:
6
+ *
7
+ * - reading indentation
8
+ * - determining the entity type from the indentation level
9
+ * - validating hierarchy
10
+ * - building parent/child relationships
11
+ *
12
+ * It does not generate ranks, IDs or GraphQL payloads and does not
13
+ * persist anything. Those responsibilities belong to later layers.
14
+ *
15
+ * Example with rootType = 'phase':
16
+ *
17
+ * Input:
18
+ *
19
+ * Phase 1
20
+ * Milestone 1
21
+ * Activity 1
22
+ * Task 1
23
+ * Activity 2
24
+ * Phase 2
25
+ *
26
+ * Output:
27
+ *
28
+ * {
29
+ * valid: true,
30
+ * errors: [],
31
+ * data: [
32
+ * {
33
+ * type: 'phase',
34
+ * name: 'Phase 1',
35
+ * children: [
36
+ * {
37
+ * type: 'milestone',
38
+ * name: 'Milestone 1',
39
+ * children: [
40
+ * {
41
+ * type: 'activity',
42
+ * name: 'Activity 1',
43
+ * children: [
44
+ * {
45
+ * type: 'task',
46
+ * name: 'Task 1',
47
+ * children: []
48
+ * }
49
+ * ]
50
+ * },
51
+ * {
52
+ * type: 'activity',
53
+ * name: 'Activity 2',
54
+ * children: []
55
+ * }
56
+ * ]
57
+ * }
58
+ * ]
59
+ * },
60
+ * {
61
+ * type: 'phase',
62
+ * name: 'Phase 2',
63
+ * children: []
64
+ * }
65
+ * ]
66
+ * }
67
+ *
68
+ * nodesAtLevel keeps track of the latest valid node at every depth.
69
+ *
70
+ * After:
71
+ *
72
+ * Phase 1
73
+ * Milestone 1
74
+ * Activity 1
75
+ *
76
+ * it contains:
77
+ *
78
+ * nodesAtLevel[0] = Phase 1
79
+ * nodesAtLevel[1] = Milestone 1
80
+ * nodesAtLevel[2] = Activity 1
81
+ *
82
+ * If another activity is encountered at level 2, its parent is simply
83
+ * nodesAtLevel[1], which is the current milestone.
84
+ *
85
+ * nodesAtLevel.length = level + 1 removes stale deeper nodes whenever
86
+ * the parser moves back up the hierarchy.
87
+ *
88
+ * It also allows skipped hierarchy to be detected.
89
+ *
90
+ * Example:
91
+ *
92
+ * Phase 1
93
+ * Activity 1
94
+ *
95
+ * Activity 1 is level 2 but nodesAtLevel[1] does not exist, so the
96
+ * parser returns EXPECTED_PARENT_BEFORE for the missing milestone.
97
+ */
2
98
  export declare function parseBulkStructure(text: string, rootType: BulkStructureRoot): BulkStructureParseResult;
99
+ /**
100
+ * Flattens the parsed hierarchy into a depth-first list.
101
+ *
102
+ * Example:
103
+ *
104
+ * Input:
105
+ *
106
+ * [
107
+ * {
108
+ * type: 'phase',
109
+ * name: 'Phase 1',
110
+ * children: [
111
+ * {
112
+ * type: 'milestone',
113
+ * name: 'Milestone 1',
114
+ * children: []
115
+ * }
116
+ * ]
117
+ * }
118
+ * ]
119
+ *
120
+ * Output:
121
+ *
122
+ * [
123
+ * Phase 1,
124
+ * Milestone 1
125
+ * ]
126
+ *
127
+ * The original nodes are returned; they are not cloned.
128
+ *
129
+ * This is useful when an operation needs to inspect all nodes but does
130
+ * not care about the parent/child hierarchy.
131
+ */
3
132
  export declare function flattenBulkStructure(nodes: BulkStructureNode[]): BulkStructureNode[];
133
+ /**
134
+ * Counts every entity type contained in the parsed hierarchy.
135
+ *
136
+ * Example input:
137
+ *
138
+ * Phase 1
139
+ * Milestone 1
140
+ * Activity 1
141
+ * Task 1
142
+ * Activity 2
143
+ *
144
+ * Output:
145
+ *
146
+ * {
147
+ * phase: 1,
148
+ * milestone: 1,
149
+ * activity: 2,
150
+ * task: 1
151
+ * }
152
+ *
153
+ * flattenBulkStructure() is used first so the counting logic does not
154
+ * need to know anything about hierarchy or parent/child relationships.
155
+ */
4
156
  export declare function countByType(nodes: BulkStructureNode[]): Record<BulkStructureEntityType, number>;
@@ -1,9 +1,177 @@
1
1
  import type { BulkActivityHierarchyPayload, BulkMilestoneHierarchyPayload, BulkPhaseHierarchyPayload, BulkStructureNode } from '../types/bulkStructure';
2
+ /**
3
+ * Minimal shape required from existing ordered entities.
4
+ *
5
+ * Existing phases, milestones or activities are only used here
6
+ * to determine where new items should be appended.
7
+ *
8
+ * generateRanksAtEnd() currently expects an Ordered-compatible
9
+ * object, which contains both id and rank.
10
+ */
2
11
  interface RankedItem {
3
12
  id: string;
4
13
  rank: string;
5
14
  }
15
+ /**
16
+ * Public builder used when bulk inserting activities directly
17
+ * into an existing milestone.
18
+ *
19
+ * Flow:
20
+ *
21
+ * parsed BulkStructureNode[]
22
+ * -> assign ranks after existing activities
23
+ * -> convert nested tasks
24
+ * -> BulkActivityHierarchyPayload[]
25
+ *
26
+ * Example:
27
+ *
28
+ * Parsed:
29
+ *
30
+ * Activity 1
31
+ * Task 1
32
+ * Activity 2
33
+ *
34
+ * Existing activities:
35
+ *
36
+ * [
37
+ * { id: 'existing-1', rank: '...' }
38
+ * ]
39
+ *
40
+ * Output:
41
+ *
42
+ * [
43
+ * {
44
+ * name: 'Activity 1',
45
+ * rank: '<rank after existing-1>',
46
+ * tasks: [
47
+ * { name: 'Task 1' }
48
+ * ]
49
+ * },
50
+ * {
51
+ * name: 'Activity 2',
52
+ * rank: '<next rank>'
53
+ * }
54
+ * ]
55
+ */
6
56
  export declare function buildActivityHierarchy(nodes: BulkStructureNode[], existingActivities: RankedItem[]): BulkActivityHierarchyPayload[];
57
+ /**
58
+ * Converts parsed milestone nodes into ranked milestone payloads.
59
+ *
60
+ * Root milestones are ranked after the milestones already present
61
+ * in the existing phase.
62
+ *
63
+ * Activities nested inside a newly-created milestone start with an
64
+ * empty existing activity list because that milestone does not yet
65
+ * contain any activities.
66
+ *
67
+ * Example parsed input:
68
+ *
69
+ * Milestone 1
70
+ * Activity 1
71
+ * Task 1
72
+ * Activity 2
73
+ * Milestone 2
74
+ *
75
+ * Output:
76
+ *
77
+ * [
78
+ * {
79
+ * name: 'Milestone 1',
80
+ * rank: '<next milestone rank>',
81
+ * activities: [
82
+ * {
83
+ * name: 'Activity 1',
84
+ * rank: '<first activity rank>',
85
+ * tasks: [
86
+ * { name: 'Task 1' }
87
+ * ]
88
+ * },
89
+ * {
90
+ * name: 'Activity 2',
91
+ * rank: '<next activity rank>'
92
+ * }
93
+ * ]
94
+ * },
95
+ * {
96
+ * name: 'Milestone 2',
97
+ * rank: '<next milestone rank>'
98
+ * }
99
+ * ]
100
+ */
7
101
  export declare function buildMilestoneHierarchy(nodes: BulkStructureNode[], existingMilestones: RankedItem[]): BulkMilestoneHierarchyPayload[];
102
+ /**
103
+ * Converts parsed phase nodes into the final ranked phase hierarchy payload.
104
+ *
105
+ * Root phases are ranked after the phases already present in the project.
106
+ *
107
+ * Milestones inside a newly-created phase start with an empty existing
108
+ * milestone list because the new phase has no existing milestones yet.
109
+ *
110
+ * The same rule continues recursively:
111
+ *
112
+ * new phase
113
+ * -> new milestones
114
+ * -> new activities
115
+ * -> new tasks
116
+ *
117
+ * Only phase, milestone and activity receive ranks.
118
+ * Tasks do not.
119
+ *
120
+ * ------------------------------------------------------------
121
+ * Example
122
+ * ------------------------------------------------------------
123
+ *
124
+ * Parsed input:
125
+ *
126
+ * Phase 1
127
+ * Milestone 1
128
+ * Activity 1
129
+ * Task 1
130
+ * Activity 2
131
+ * Phase 2
132
+ *
133
+ * Output:
134
+ *
135
+ * [
136
+ * {
137
+ * name: 'Phase 1',
138
+ * rank: '<rank after existing phases>',
139
+ * milestones: [
140
+ * {
141
+ * name: 'Milestone 1',
142
+ * rank: '<first milestone rank>',
143
+ * activities: [
144
+ * {
145
+ * name: 'Activity 1',
146
+ * rank: '<first activity rank>',
147
+ * tasks: [
148
+ * {
149
+ * name: 'Task 1'
150
+ * }
151
+ * ]
152
+ * },
153
+ * {
154
+ * name: 'Activity 2',
155
+ * rank: '<next activity rank>'
156
+ * }
157
+ * ]
158
+ * }
159
+ * ]
160
+ * },
161
+ * {
162
+ * name: 'Phase 2',
163
+ * rank: '<next phase rank>'
164
+ * }
165
+ * ]
166
+ *
167
+ * Overall responsibility of this file:
168
+ *
169
+ * parsed generic hierarchy
170
+ * -> add frontend-owned ranks
171
+ * -> produce GraphQL/domain hierarchy payload
172
+ *
173
+ * The backend remains responsible for IDs, foreign keys, defaults,
174
+ * slugs, statuses and persistence.
175
+ */
8
176
  export declare function buildPhaseHierarchy(nodes: BulkStructureNode[], existingPhases: RankedItem[]): BulkPhaseHierarchyPayload[];
9
177
  export {};
@@ -143,6 +143,12 @@ export interface Sprint extends Entity {
143
143
  color?: string;
144
144
  active: boolean;
145
145
  }
146
+ export interface SprintMilestone extends Entity {
147
+ name: string;
148
+ rank: string;
149
+ important: boolean;
150
+ color?: string;
151
+ }
146
152
  export interface SprintPlanningUser {
147
153
  userId: string;
148
154
  fullName: string;
@@ -447,6 +453,7 @@ export declare const feedFilterTypes: {
447
453
  readonly project: "projectId";
448
454
  readonly assignee: "assigneeId";
449
455
  readonly sprint: "sprintId";
456
+ readonly milestone: "milestoneId";
450
457
  };
451
458
  export type FeedFilterTypeKeys = keyof typeof feedFilterTypes;
452
459
  export type FeedFilterType = (typeof feedFilterTypes)[FeedFilterTypeKeys];
@@ -1,11 +1,15 @@
1
1
  import type { Attachment, TimeTracking } from '../types';
2
- import { type Activity, type ActivityDevStatus, type ActivityStatus, type ActivityType, type AddActivityFeedPayload, type AddCommentPayload, type AddFilesPayload, type AddSubtaskPayload, type ChangeFeedActivitiesPayload, type FeedFilters, type Id, type Project, type RemoveCommentPayload, type RemoveFilePayload, type Sprint, type StartTimerPayload, type Subtask, type UpdateActivityPayload, type UpdateCommentPayload, type UpdateSubtaskFieldPayload, type User } from '../types';
2
+ import { type Activity, type ActivityDevStatus, type ActivityStatus, type ActivityType, type AddActivityFeedPayload, type AddCommentPayload, type AddFilesPayload, type AddSubtaskPayload, type ChangeFeedActivitiesPayload, type FeedFilters, type Id, type Milestone, type Project, type RemoveCommentPayload, type RemoveFilePayload, type Sprint, type StartTimerPayload, type Subtask, type UpdateActivityPayload, type UpdateCommentPayload, type UpdateSubtaskFieldPayload, type User } from '../types';
3
3
  export type FeedMode = 'standard' | 'dev';
4
4
  declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
5
  filters: {
6
6
  type: import("vue").PropType<FeedFilters>;
7
7
  required: true;
8
8
  };
9
+ milestones: {
10
+ type: import("vue").PropType<Milestone[]>;
11
+ default: () => never[];
12
+ };
9
13
  activities: {
10
14
  type: import("vue").PropType<Activity[]>;
11
15
  required: true;
@@ -146,6 +150,10 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
146
150
  type: import("vue").PropType<FeedFilters>;
147
151
  required: true;
148
152
  };
153
+ milestones: {
154
+ type: import("vue").PropType<Milestone[]>;
155
+ default: () => never[];
156
+ };
149
157
  activities: {
150
158
  type: import("vue").PropType<Activity[]>;
151
159
  required: true;
@@ -282,6 +290,7 @@ declare const __VLS_publicComponent: import("vue").DefineComponent<import("vue")
282
290
  "onUpdate:showsOnlyImportant"?: ((value: boolean) => any) | undefined;
283
291
  "onUpdate:showsOnlyNonAssigned"?: ((value: boolean) => any) | undefined;
284
292
  }>, {
293
+ milestones: Milestone[];
285
294
  project: Project;
286
295
  activityTypes: ActivityType[];
287
296
  isTaskCheckable: (task: Subtask) => boolean;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "license": "CC-BY-NC-ND-4.0",
6
6
  "author": "26lights <dev@26lights.com> (https://www.26lights.com)",
7
- "version": "0.42.186",
7
+ "version": "0.42.188",
8
8
  "workspaces": [
9
9
  "packages/*"
10
10
  ],