@outbuild-company/schedule-core 1.17.0 → 1.17.2

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/dist/index.d.cts CHANGED
@@ -739,6 +739,8 @@ declare const GROUP_ID_SEPARATOR: ":";
739
739
  declare const UNASSIGNED_GROUP_LABEL: "Unassigned";
740
740
  /** Smallest grouping depth that materializes a band. */
741
741
  declare const MINIMUM_GROUP_DEPTH: 1;
742
+ /** Shallowest outline level a band tree can start at. */
743
+ declare const MINIMUM_GROUP_LEVEL: 1;
742
744
  /** Single node in a hierarchical view-attribute outline. */
743
745
  interface ViewAttributeValueInput {
744
746
  readonly id: string;
@@ -759,21 +761,50 @@ interface ViewAttributeCatalogInput {
759
761
  readonly values: ReadonlyArray<ViewAttributeValueInput>;
760
762
  readonly assignments: ReadonlyArray<ViewAttributeAssignmentInput>;
761
763
  }
762
- /** Runtime grouping configuration active on a schedule. */
763
- interface GroupState {
764
- readonly attributeKey: string;
764
+ /**
765
+ * Inclusive window of outline levels that become bands, both bounds 1-based.
766
+ *
767
+ * `startLevel` lets a grouping skip the top of a hierarchy: on a four-level code,
768
+ * `{ startLevel: 3, depth: 4 }` bands only levels 3 and 4 and ignores 1 and 2. It
769
+ * is what makes the level choice independent of how deep the attribute happens to
770
+ * be. A value that sits above `startLevel` has nothing to show in the window and
771
+ * falls into the unassigned bucket.
772
+ */
773
+ interface GroupLevelWindow {
774
+ readonly startLevel: number;
765
775
  readonly depth: number;
776
+ }
777
+ /**
778
+ * One grouping level below the primary one. Nesting more than a second level is
779
+ * expressed through the level window on a hierarchical attribute, not by chaining
780
+ * these.
781
+ */
782
+ interface GroupCriterion extends GroupLevelWindow {
783
+ readonly attributeKey: string;
766
784
  readonly direction: OrderDirection;
785
+ }
786
+ /** Runtime grouping configuration active on a schedule. */
787
+ interface GroupState extends GroupCriterion {
767
788
  readonly includeWbs: boolean;
768
789
  readonly collapsedIds: ReadonlySet<string>;
790
+ readonly secondary: GroupCriterion | null;
769
791
  }
770
- /** JSON-friendly grouping command accepted by `group-set`. */
771
- interface GroupStateInput {
792
+ /**
793
+ * JSON-friendly criterion. `startLevel` is optional so views persisted before
794
+ * level windows existed keep deserializing; it defaults to the top of the
795
+ * hierarchy.
796
+ */
797
+ interface GroupCriterionInput {
772
798
  readonly attributeKey: string;
799
+ readonly startLevel?: number;
773
800
  readonly depth: number;
774
801
  readonly direction: OrderDirection;
802
+ }
803
+ /** JSON-friendly grouping command accepted by `group-set`. */
804
+ interface GroupStateInput extends GroupCriterionInput {
775
805
  readonly includeWbs: boolean;
776
806
  readonly collapsedIds: ReadonlyArray<string>;
807
+ readonly secondary?: GroupCriterionInput | null;
777
808
  }
778
809
  /** A single display row: either a synthetic group band or a real activity. */
779
810
  type VisualRow = {
@@ -789,6 +820,12 @@ type VisualRow = {
789
820
  };
790
821
  /** Builds the stable synthetic identifier for a group row (`g:{key}:{valueId}`). */
791
822
  declare function buildGroupRowId(attributeKey: string, valueId: string): string;
823
+ /**
824
+ * Extends a band id with a nested level. The parent path has to stay in the id
825
+ * because the same secondary value shows up under several primary bands, and
826
+ * consumers key rows (and persisted collapse state) by this id.
827
+ */
828
+ declare function appendGroupRowId(parentRowId: string, attributeKey: string, valueId: string): string;
792
829
 
793
830
  /** Low-level dependency operation accepted by the canonical dispatcher. */
794
831
  type LinksBatchOperation = {
@@ -2794,4 +2831,4 @@ declare const DISPATCH_TRACK_EVENT: {
2794
2831
  /** Consumer analytics event name emitted by a schedule mutation. */
2795
2832
  type DispatchTrackEvent = (typeof DISPATCH_TRACK_EVENT)[keyof typeof DISPATCH_TRACK_EVENT];
2796
2833
 
2797
- export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, type ActivityBaselineSnapshot, type ActivityBatchAction, type ActivityBatchInput, type ActivityBatchItem, type ActivityBatchItemInput, type ActivityBatchLinkInput$1 as ActivityBatchLinkInput, type ActivityBatchMode, type ActivityBatchParentReference, type ActivityBatchReference, type ActivityBulkEdit, type ActivityCreateInput, type ActivityCreationOverrides, type ActivityCreter, type ActivityDateEdge, type ActivityDateEdit, type ActivityField, type ActivityFieldEdit, type ActivityFieldValue, type ActivityId, type ActivityLookaheadSyncInput, type ActivityMoveInput, type ActivityStatus, type ActivityType, type ApplyLookaheadConversionInput, type BackendActivityInput, type BackendCalendarExceptionInput, type BackendCalendarInput, type BackendLinkInput, type BackendScheduleInput, type BackendSectorInput, type BackendShiftInput, type BaselinePoint, type BaselineVersion, type BranchOrderChange, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, type Calendar, type CalendarId, type CalendarLike, type CalendarUnit, type CalendarWorktime, type ChangeSet, type ChangeSetSource, type ColumnName, type ConstraintType, type ConstraintWarning, type CoreActivity, type CoreBaselinePoint, type CreationKind, type CriticalPathResult, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, type DateGesture, type DateGestureKind, type DateGesturePreview, type DatesBatchVerdict, type DeletedActivitySnapshot, type DeletedLinkSnapshot, type DispatchAction, type DispatchActionKind, type DispatchManyAction, type DispatchManyChangeSetSource, type DispatchManyResult, type DispatchOptions, type DispatchRejectReason, type DispatchResult, type DispatchTrackEvent, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, type EditAlertKey, type EditDenialReason, type EditResult, type EditableColumnName, type EffectiveGraphAudit, type EntityChange, type ActivityBatchLinkInput as ErgonomicActivityBatchLinkInput, type ExpectedProgressAdapter, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, type FilterCriterion, type FilterCriterionGroup, type FilterCriterionValue, type FilterDateRange, type FilterField, type FilterLogic, type FilterOperator, type FilterRejection, type FilterState, type FilterValueKind, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, type GroupState, type GroupStateInput, type ImpactRequestSyncInput, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, type Link, type LinkBatchOperationKind, type LinkBatchRequest, type LinkBatchVerdict, type LinkCreateRequest, type LinkId, type LinkPatchRequest, type LinkRejection, type LinkRelationship, type LinkType, type LinkTypeCode, type LinkUpdateAction, type LinksBatchOperation, type LoadDiagnostic, type LoadDiagnosticCode, type LookaheadConversionFormerParent, type LookaheadConversionGroup, type LookaheadConversionInput, type LookaheadConversionMilestoneMove, type LookaheadConversionPlan, type LookaheadConversionResult, MINIMUM_GROUP_DEPTH, type MutationContext, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, type OrderDirection, type OrderMode, type OrderRule, type OrderState, type ParsedInput, type PendingRequest, type PersistableActivityField, type PersistedEntityIdentity, type PersistenceCheckpoint, type PipelineColumnName, type ProjectWorkHours, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, type ScheduleActivitiesApi, type ScheduleApiNamespaces, type ScheduleAutoScheduleAction, type ScheduleBaselinesApi, type ScheduleCalendarsApi, ScheduleCore, type ScheduleCoreInput, type ScheduleCoreReporter, type ScheduleCoreStatus, type ScheduleCriticalPathApi, type ScheduleDiagnosticsApi, type ScheduleEffect, type ScheduleHistoryApi, type ScheduleImpactRequestsApi, type ScheduleLinksApi, type SchedulePersistenceApi, type ScheduleProjectionApi, type ScheduleSelectionApi, type ScheduleViewApi, type SectorMetadata, type SelectionToggleInput, type StaticActivityDefaults, type StatusCriteria, type TrackingEvent, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, type UndoOptions, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, type ViewAttributeAssignmentInput, type ViewAttributeCatalogInput, type ViewAttributeFilterCriterion, type ViewAttributeOrderRule, type ViewAttributeValueInput, type ViewFilterInput, type ViewStateChange, type ViewStatePropChange, type VisualRow, WORK_TIME_DIRECTION, type WithProplannerId, type WorkTimeDirection, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
2834
+ export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, type ActivityBaselineSnapshot, type ActivityBatchAction, type ActivityBatchInput, type ActivityBatchItem, type ActivityBatchItemInput, type ActivityBatchLinkInput$1 as ActivityBatchLinkInput, type ActivityBatchMode, type ActivityBatchParentReference, type ActivityBatchReference, type ActivityBulkEdit, type ActivityCreateInput, type ActivityCreationOverrides, type ActivityCreter, type ActivityDateEdge, type ActivityDateEdit, type ActivityField, type ActivityFieldEdit, type ActivityFieldValue, type ActivityId, type ActivityLookaheadSyncInput, type ActivityMoveInput, type ActivityStatus, type ActivityType, type ApplyLookaheadConversionInput, type BackendActivityInput, type BackendCalendarExceptionInput, type BackendCalendarInput, type BackendLinkInput, type BackendScheduleInput, type BackendSectorInput, type BackendShiftInput, type BaselinePoint, type BaselineVersion, type BranchOrderChange, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, type Calendar, type CalendarId, type CalendarLike, type CalendarUnit, type CalendarWorktime, type ChangeSet, type ChangeSetSource, type ColumnName, type ConstraintType, type ConstraintWarning, type CoreActivity, type CoreBaselinePoint, type CreationKind, type CriticalPathResult, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, type DateGesture, type DateGestureKind, type DateGesturePreview, type DatesBatchVerdict, type DeletedActivitySnapshot, type DeletedLinkSnapshot, type DispatchAction, type DispatchActionKind, type DispatchManyAction, type DispatchManyChangeSetSource, type DispatchManyResult, type DispatchOptions, type DispatchRejectReason, type DispatchResult, type DispatchTrackEvent, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, type EditAlertKey, type EditDenialReason, type EditResult, type EditableColumnName, type EffectiveGraphAudit, type EntityChange, type ActivityBatchLinkInput as ErgonomicActivityBatchLinkInput, type ExpectedProgressAdapter, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, type FilterCriterion, type FilterCriterionGroup, type FilterCriterionValue, type FilterDateRange, type FilterField, type FilterLogic, type FilterOperator, type FilterRejection, type FilterState, type FilterValueKind, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, type GroupCriterion, type GroupCriterionInput, type GroupLevelWindow, type GroupState, type GroupStateInput, type ImpactRequestSyncInput, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, type Link, type LinkBatchOperationKind, type LinkBatchRequest, type LinkBatchVerdict, type LinkCreateRequest, type LinkId, type LinkPatchRequest, type LinkRejection, type LinkRelationship, type LinkType, type LinkTypeCode, type LinkUpdateAction, type LinksBatchOperation, type LoadDiagnostic, type LoadDiagnosticCode, type LookaheadConversionFormerParent, type LookaheadConversionGroup, type LookaheadConversionInput, type LookaheadConversionMilestoneMove, type LookaheadConversionPlan, type LookaheadConversionResult, MINIMUM_GROUP_DEPTH, MINIMUM_GROUP_LEVEL, type MutationContext, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, type OrderDirection, type OrderMode, type OrderRule, type OrderState, type ParsedInput, type PendingRequest, type PersistableActivityField, type PersistedEntityIdentity, type PersistenceCheckpoint, type PipelineColumnName, type ProjectWorkHours, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, type ScheduleActivitiesApi, type ScheduleApiNamespaces, type ScheduleAutoScheduleAction, type ScheduleBaselinesApi, type ScheduleCalendarsApi, ScheduleCore, type ScheduleCoreInput, type ScheduleCoreReporter, type ScheduleCoreStatus, type ScheduleCriticalPathApi, type ScheduleDiagnosticsApi, type ScheduleEffect, type ScheduleHistoryApi, type ScheduleImpactRequestsApi, type ScheduleLinksApi, type SchedulePersistenceApi, type ScheduleProjectionApi, type ScheduleSelectionApi, type ScheduleViewApi, type SectorMetadata, type SelectionToggleInput, type StaticActivityDefaults, type StatusCriteria, type TrackingEvent, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, type UndoOptions, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, type ViewAttributeAssignmentInput, type ViewAttributeCatalogInput, type ViewAttributeFilterCriterion, type ViewAttributeOrderRule, type ViewAttributeValueInput, type ViewFilterInput, type ViewStateChange, type ViewStatePropChange, type VisualRow, WORK_TIME_DIRECTION, type WithProplannerId, type WorkTimeDirection, appendGroupRowId, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
package/dist/index.d.ts CHANGED
@@ -739,6 +739,8 @@ declare const GROUP_ID_SEPARATOR: ":";
739
739
  declare const UNASSIGNED_GROUP_LABEL: "Unassigned";
740
740
  /** Smallest grouping depth that materializes a band. */
741
741
  declare const MINIMUM_GROUP_DEPTH: 1;
742
+ /** Shallowest outline level a band tree can start at. */
743
+ declare const MINIMUM_GROUP_LEVEL: 1;
742
744
  /** Single node in a hierarchical view-attribute outline. */
743
745
  interface ViewAttributeValueInput {
744
746
  readonly id: string;
@@ -759,21 +761,50 @@ interface ViewAttributeCatalogInput {
759
761
  readonly values: ReadonlyArray<ViewAttributeValueInput>;
760
762
  readonly assignments: ReadonlyArray<ViewAttributeAssignmentInput>;
761
763
  }
762
- /** Runtime grouping configuration active on a schedule. */
763
- interface GroupState {
764
- readonly attributeKey: string;
764
+ /**
765
+ * Inclusive window of outline levels that become bands, both bounds 1-based.
766
+ *
767
+ * `startLevel` lets a grouping skip the top of a hierarchy: on a four-level code,
768
+ * `{ startLevel: 3, depth: 4 }` bands only levels 3 and 4 and ignores 1 and 2. It
769
+ * is what makes the level choice independent of how deep the attribute happens to
770
+ * be. A value that sits above `startLevel` has nothing to show in the window and
771
+ * falls into the unassigned bucket.
772
+ */
773
+ interface GroupLevelWindow {
774
+ readonly startLevel: number;
765
775
  readonly depth: number;
776
+ }
777
+ /**
778
+ * One grouping level below the primary one. Nesting more than a second level is
779
+ * expressed through the level window on a hierarchical attribute, not by chaining
780
+ * these.
781
+ */
782
+ interface GroupCriterion extends GroupLevelWindow {
783
+ readonly attributeKey: string;
766
784
  readonly direction: OrderDirection;
785
+ }
786
+ /** Runtime grouping configuration active on a schedule. */
787
+ interface GroupState extends GroupCriterion {
767
788
  readonly includeWbs: boolean;
768
789
  readonly collapsedIds: ReadonlySet<string>;
790
+ readonly secondary: GroupCriterion | null;
769
791
  }
770
- /** JSON-friendly grouping command accepted by `group-set`. */
771
- interface GroupStateInput {
792
+ /**
793
+ * JSON-friendly criterion. `startLevel` is optional so views persisted before
794
+ * level windows existed keep deserializing; it defaults to the top of the
795
+ * hierarchy.
796
+ */
797
+ interface GroupCriterionInput {
772
798
  readonly attributeKey: string;
799
+ readonly startLevel?: number;
773
800
  readonly depth: number;
774
801
  readonly direction: OrderDirection;
802
+ }
803
+ /** JSON-friendly grouping command accepted by `group-set`. */
804
+ interface GroupStateInput extends GroupCriterionInput {
775
805
  readonly includeWbs: boolean;
776
806
  readonly collapsedIds: ReadonlyArray<string>;
807
+ readonly secondary?: GroupCriterionInput | null;
777
808
  }
778
809
  /** A single display row: either a synthetic group band or a real activity. */
779
810
  type VisualRow = {
@@ -789,6 +820,12 @@ type VisualRow = {
789
820
  };
790
821
  /** Builds the stable synthetic identifier for a group row (`g:{key}:{valueId}`). */
791
822
  declare function buildGroupRowId(attributeKey: string, valueId: string): string;
823
+ /**
824
+ * Extends a band id with a nested level. The parent path has to stay in the id
825
+ * because the same secondary value shows up under several primary bands, and
826
+ * consumers key rows (and persisted collapse state) by this id.
827
+ */
828
+ declare function appendGroupRowId(parentRowId: string, attributeKey: string, valueId: string): string;
792
829
 
793
830
  /** Low-level dependency operation accepted by the canonical dispatcher. */
794
831
  type LinksBatchOperation = {
@@ -2794,4 +2831,4 @@ declare const DISPATCH_TRACK_EVENT: {
2794
2831
  /** Consumer analytics event name emitted by a schedule mutation. */
2795
2832
  type DispatchTrackEvent = (typeof DISPATCH_TRACK_EVENT)[keyof typeof DISPATCH_TRACK_EVENT];
2796
2833
 
2797
- export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, type ActivityBaselineSnapshot, type ActivityBatchAction, type ActivityBatchInput, type ActivityBatchItem, type ActivityBatchItemInput, type ActivityBatchLinkInput$1 as ActivityBatchLinkInput, type ActivityBatchMode, type ActivityBatchParentReference, type ActivityBatchReference, type ActivityBulkEdit, type ActivityCreateInput, type ActivityCreationOverrides, type ActivityCreter, type ActivityDateEdge, type ActivityDateEdit, type ActivityField, type ActivityFieldEdit, type ActivityFieldValue, type ActivityId, type ActivityLookaheadSyncInput, type ActivityMoveInput, type ActivityStatus, type ActivityType, type ApplyLookaheadConversionInput, type BackendActivityInput, type BackendCalendarExceptionInput, type BackendCalendarInput, type BackendLinkInput, type BackendScheduleInput, type BackendSectorInput, type BackendShiftInput, type BaselinePoint, type BaselineVersion, type BranchOrderChange, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, type Calendar, type CalendarId, type CalendarLike, type CalendarUnit, type CalendarWorktime, type ChangeSet, type ChangeSetSource, type ColumnName, type ConstraintType, type ConstraintWarning, type CoreActivity, type CoreBaselinePoint, type CreationKind, type CriticalPathResult, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, type DateGesture, type DateGestureKind, type DateGesturePreview, type DatesBatchVerdict, type DeletedActivitySnapshot, type DeletedLinkSnapshot, type DispatchAction, type DispatchActionKind, type DispatchManyAction, type DispatchManyChangeSetSource, type DispatchManyResult, type DispatchOptions, type DispatchRejectReason, type DispatchResult, type DispatchTrackEvent, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, type EditAlertKey, type EditDenialReason, type EditResult, type EditableColumnName, type EffectiveGraphAudit, type EntityChange, type ActivityBatchLinkInput as ErgonomicActivityBatchLinkInput, type ExpectedProgressAdapter, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, type FilterCriterion, type FilterCriterionGroup, type FilterCriterionValue, type FilterDateRange, type FilterField, type FilterLogic, type FilterOperator, type FilterRejection, type FilterState, type FilterValueKind, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, type GroupState, type GroupStateInput, type ImpactRequestSyncInput, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, type Link, type LinkBatchOperationKind, type LinkBatchRequest, type LinkBatchVerdict, type LinkCreateRequest, type LinkId, type LinkPatchRequest, type LinkRejection, type LinkRelationship, type LinkType, type LinkTypeCode, type LinkUpdateAction, type LinksBatchOperation, type LoadDiagnostic, type LoadDiagnosticCode, type LookaheadConversionFormerParent, type LookaheadConversionGroup, type LookaheadConversionInput, type LookaheadConversionMilestoneMove, type LookaheadConversionPlan, type LookaheadConversionResult, MINIMUM_GROUP_DEPTH, type MutationContext, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, type OrderDirection, type OrderMode, type OrderRule, type OrderState, type ParsedInput, type PendingRequest, type PersistableActivityField, type PersistedEntityIdentity, type PersistenceCheckpoint, type PipelineColumnName, type ProjectWorkHours, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, type ScheduleActivitiesApi, type ScheduleApiNamespaces, type ScheduleAutoScheduleAction, type ScheduleBaselinesApi, type ScheduleCalendarsApi, ScheduleCore, type ScheduleCoreInput, type ScheduleCoreReporter, type ScheduleCoreStatus, type ScheduleCriticalPathApi, type ScheduleDiagnosticsApi, type ScheduleEffect, type ScheduleHistoryApi, type ScheduleImpactRequestsApi, type ScheduleLinksApi, type SchedulePersistenceApi, type ScheduleProjectionApi, type ScheduleSelectionApi, type ScheduleViewApi, type SectorMetadata, type SelectionToggleInput, type StaticActivityDefaults, type StatusCriteria, type TrackingEvent, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, type UndoOptions, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, type ViewAttributeAssignmentInput, type ViewAttributeCatalogInput, type ViewAttributeFilterCriterion, type ViewAttributeOrderRule, type ViewAttributeValueInput, type ViewFilterInput, type ViewStateChange, type ViewStatePropChange, type VisualRow, WORK_TIME_DIRECTION, type WithProplannerId, type WorkTimeDirection, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
2834
+ export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, type ActivityBaselineSnapshot, type ActivityBatchAction, type ActivityBatchInput, type ActivityBatchItem, type ActivityBatchItemInput, type ActivityBatchLinkInput$1 as ActivityBatchLinkInput, type ActivityBatchMode, type ActivityBatchParentReference, type ActivityBatchReference, type ActivityBulkEdit, type ActivityCreateInput, type ActivityCreationOverrides, type ActivityCreter, type ActivityDateEdge, type ActivityDateEdit, type ActivityField, type ActivityFieldEdit, type ActivityFieldValue, type ActivityId, type ActivityLookaheadSyncInput, type ActivityMoveInput, type ActivityStatus, type ActivityType, type ApplyLookaheadConversionInput, type BackendActivityInput, type BackendCalendarExceptionInput, type BackendCalendarInput, type BackendLinkInput, type BackendScheduleInput, type BackendSectorInput, type BackendShiftInput, type BaselinePoint, type BaselineVersion, type BranchOrderChange, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, type Calendar, type CalendarId, type CalendarLike, type CalendarUnit, type CalendarWorktime, type ChangeSet, type ChangeSetSource, type ColumnName, type ConstraintType, type ConstraintWarning, type CoreActivity, type CoreBaselinePoint, type CreationKind, type CriticalPathResult, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, type DateGesture, type DateGestureKind, type DateGesturePreview, type DatesBatchVerdict, type DeletedActivitySnapshot, type DeletedLinkSnapshot, type DispatchAction, type DispatchActionKind, type DispatchManyAction, type DispatchManyChangeSetSource, type DispatchManyResult, type DispatchOptions, type DispatchRejectReason, type DispatchResult, type DispatchTrackEvent, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, type EditAlertKey, type EditDenialReason, type EditResult, type EditableColumnName, type EffectiveGraphAudit, type EntityChange, type ActivityBatchLinkInput as ErgonomicActivityBatchLinkInput, type ExpectedProgressAdapter, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, type FilterCriterion, type FilterCriterionGroup, type FilterCriterionValue, type FilterDateRange, type FilterField, type FilterLogic, type FilterOperator, type FilterRejection, type FilterState, type FilterValueKind, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, type GroupCriterion, type GroupCriterionInput, type GroupLevelWindow, type GroupState, type GroupStateInput, type ImpactRequestSyncInput, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, type Link, type LinkBatchOperationKind, type LinkBatchRequest, type LinkBatchVerdict, type LinkCreateRequest, type LinkId, type LinkPatchRequest, type LinkRejection, type LinkRelationship, type LinkType, type LinkTypeCode, type LinkUpdateAction, type LinksBatchOperation, type LoadDiagnostic, type LoadDiagnosticCode, type LookaheadConversionFormerParent, type LookaheadConversionGroup, type LookaheadConversionInput, type LookaheadConversionMilestoneMove, type LookaheadConversionPlan, type LookaheadConversionResult, MINIMUM_GROUP_DEPTH, MINIMUM_GROUP_LEVEL, type MutationContext, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, type OrderDirection, type OrderMode, type OrderRule, type OrderState, type ParsedInput, type PendingRequest, type PersistableActivityField, type PersistedEntityIdentity, type PersistenceCheckpoint, type PipelineColumnName, type ProjectWorkHours, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, type ScheduleActivitiesApi, type ScheduleApiNamespaces, type ScheduleAutoScheduleAction, type ScheduleBaselinesApi, type ScheduleCalendarsApi, ScheduleCore, type ScheduleCoreInput, type ScheduleCoreReporter, type ScheduleCoreStatus, type ScheduleCriticalPathApi, type ScheduleDiagnosticsApi, type ScheduleEffect, type ScheduleHistoryApi, type ScheduleImpactRequestsApi, type ScheduleLinksApi, type SchedulePersistenceApi, type ScheduleProjectionApi, type ScheduleSelectionApi, type ScheduleViewApi, type SectorMetadata, type SelectionToggleInput, type StaticActivityDefaults, type StatusCriteria, type TrackingEvent, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, type UndoOptions, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, type ViewAttributeAssignmentInput, type ViewAttributeCatalogInput, type ViewAttributeFilterCriterion, type ViewAttributeOrderRule, type ViewAttributeValueInput, type ViewFilterInput, type ViewStateChange, type ViewStatePropChange, type VisualRow, WORK_TIME_DIRECTION, type WithProplannerId, type WorkTimeDirection, appendGroupRowId, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
package/dist/index.js CHANGED
@@ -1288,6 +1288,24 @@ function getFieldDescriptor(field) {
1288
1288
  return FIELD_REGISTRY[field] ?? null;
1289
1289
  }
1290
1290
 
1291
+ // src/internal/view-attributes/types.ts
1292
+ var VISUAL_ROW_KIND = {
1293
+ GROUP: "group",
1294
+ ACTIVITY: "activity"
1295
+ };
1296
+ var UNASSIGNED_VALUE_ID = "unassigned";
1297
+ var GROUP_ID_PREFIX = "g";
1298
+ var GROUP_ID_SEPARATOR = ":";
1299
+ var UNASSIGNED_GROUP_LABEL = "Unassigned";
1300
+ var MINIMUM_GROUP_DEPTH = 1;
1301
+ var MINIMUM_GROUP_LEVEL = 1;
1302
+ function buildGroupRowId(attributeKey, valueId) {
1303
+ return `${GROUP_ID_PREFIX}${GROUP_ID_SEPARATOR}${attributeKey}${GROUP_ID_SEPARATOR}${valueId}`;
1304
+ }
1305
+ function appendGroupRowId(parentRowId, attributeKey, valueId) {
1306
+ return `${parentRowId}${GROUP_ID_SEPARATOR}${attributeKey}${GROUP_ID_SEPARATOR}${valueId}`;
1307
+ }
1308
+
1291
1309
  // src/internal/view-attributes/index-catalog.ts
1292
1310
  var ROOT_PARENT_SENTINEL = null;
1293
1311
  function childListKey(parentId) {
@@ -1361,10 +1379,13 @@ function expandSelectedValueIds(catalog, selectedIds) {
1361
1379
  }
1362
1380
  return expanded;
1363
1381
  }
1364
- function truncatedPath(catalog, valueId, depth) {
1382
+ function levelWindowPath(catalog, valueId, startLevel, depth) {
1383
+ const from = Math.max(startLevel, MINIMUM_GROUP_LEVEL);
1365
1384
  const path = catalog.pathByValueId.get(valueId);
1366
- if (path === void 0 || path.length === 0) return [valueId];
1367
- return path.slice(0, Math.max(depth, 1));
1385
+ if (path === void 0 || path.length === 0) {
1386
+ return from > MINIMUM_GROUP_LEVEL ? [] : [valueId];
1387
+ }
1388
+ return path.slice(from - 1, Math.max(depth, from));
1368
1389
  }
1369
1390
 
1370
1391
  // src/internal/view-attributes/match.ts
@@ -1986,21 +2007,32 @@ function normalizeParentKey(parent) {
1986
2007
  var NOT_SET_SORT_VALUE = Number.MAX_SAFE_INTEGER;
1987
2008
  function getChildrenInVisualOrder(parentId, adapter) {
1988
2009
  const children = collectChildrenSnapshots(parentId, adapter);
1989
- const userOrder = adapter.getOrderComparator?.() ?? null;
1990
- const mode = adapter.getOrderMode?.() ?? ORDER_MODE.STANDARD;
1991
- if (userOrder !== null && mode === ORDER_MODE.KEEP_WBS_IN_PLACE) {
1992
- return sortKeepWbsInPlace(children, userOrder, adapter);
2010
+ const ordered = sortSiblingsInOrderMode(
2011
+ children,
2012
+ adapter.getOrderComparator?.() ?? null,
2013
+ adapter.getOrderMode?.() ?? ORDER_MODE.STANDARD,
2014
+ (activityId) => adapter.hasChildren(activityId)
2015
+ );
2016
+ return ordered.map((activity) => String(activity.id));
2017
+ }
2018
+ function sortSiblingsInOrderMode(siblings, userOrder, mode, hasChildren) {
2019
+ if (userOrder === null) {
2020
+ siblings.sort(compareActivitiesInVisualOrder);
2021
+ return siblings;
2022
+ }
2023
+ if (mode === ORDER_MODE.KEEP_WBS_IN_PLACE) {
2024
+ return sortKeepWbsInPlace(siblings, userOrder, hasChildren);
1993
2025
  }
1994
- children.sort(
1995
- userOrder === null ? compareActivitiesInVisualOrder : (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
2026
+ siblings.sort(
2027
+ (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
1996
2028
  );
1997
- return children.map((activity) => String(activity.id));
2029
+ return siblings;
1998
2030
  }
1999
- function sortKeepWbsInPlace(children, userOrder, adapter) {
2031
+ function sortKeepWbsInPlace(siblings, userOrder, hasChildren) {
2000
2032
  const leafActivities = [];
2001
2033
  const wbsItems = [];
2002
- for (const child of children) {
2003
- if (adapter.hasChildren(child.id)) {
2034
+ for (const child of siblings) {
2035
+ if (hasChildren(child.id)) {
2004
2036
  wbsItems.push(child);
2005
2037
  } else {
2006
2038
  leafActivities.push(child);
@@ -2010,10 +2042,9 @@ function sortKeepWbsInPlace(children, userOrder, adapter) {
2010
2042
  (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
2011
2043
  );
2012
2044
  wbsItems.sort(compareActivitiesInVisualOrder);
2013
- return [
2014
- ...leafActivities.map((a) => String(a.id)),
2015
- ...wbsItems.map((a) => String(a.id))
2016
- ];
2045
+ siblings.length = 0;
2046
+ siblings.push(...leafActivities, ...wbsItems);
2047
+ return siblings;
2017
2048
  }
2018
2049
  function iterateInVisualOrder(adapter) {
2019
2050
  const result = [];
@@ -2146,44 +2177,66 @@ function dispatchSortSet(action, deps) {
2146
2177
  return { ok: true, changes };
2147
2178
  }
2148
2179
 
2149
- // src/internal/view-attributes/types.ts
2150
- var VISUAL_ROW_KIND = {
2151
- GROUP: "group",
2152
- ACTIVITY: "activity"
2153
- };
2154
- var UNASSIGNED_VALUE_ID = "unassigned";
2155
- var GROUP_ID_PREFIX = "g";
2156
- var GROUP_ID_SEPARATOR = ":";
2157
- var UNASSIGNED_GROUP_LABEL = "Unassigned";
2158
- var MINIMUM_GROUP_DEPTH = 1;
2159
- function buildGroupRowId(attributeKey, valueId) {
2160
- return `${GROUP_ID_PREFIX}${GROUP_ID_SEPARATOR}${attributeKey}${GROUP_ID_SEPARATOR}${valueId}`;
2161
- }
2162
-
2163
2180
  // src/dispatch/view-attributes.ts
2164
2181
  function isFiniteInteger(value) {
2165
2182
  return Number.isInteger(value) && Number.isFinite(value);
2166
2183
  }
2167
- function toGroupState(input) {
2168
- if (typeof input.attributeKey !== "string" || input.attributeKey.length === 0) {
2184
+ function isValidDirection(value) {
2185
+ return value === ORDER_DIRECTION.ASCENDING || value === ORDER_DIRECTION.DESCENDING;
2186
+ }
2187
+ function toLevelWindow(input) {
2188
+ const startLevel = input.startLevel ?? MINIMUM_GROUP_LEVEL;
2189
+ if (!isFiniteInteger(startLevel) || startLevel < MINIMUM_GROUP_LEVEL) {
2169
2190
  return null;
2170
2191
  }
2171
2192
  if (!isFiniteInteger(input.depth) || input.depth < MINIMUM_GROUP_DEPTH) {
2172
2193
  return null;
2173
2194
  }
2174
- if (input.direction !== ORDER_DIRECTION.ASCENDING && input.direction !== ORDER_DIRECTION.DESCENDING) {
2195
+ if (input.depth < startLevel) return null;
2196
+ return { startLevel, depth: input.depth };
2197
+ }
2198
+ var INVALID_CRITERION = /* @__PURE__ */ Symbol("invalid-group-criterion");
2199
+ function toSecondaryCriterion(input) {
2200
+ const secondary = input.secondary;
2201
+ if (secondary === void 0 || secondary === null) return null;
2202
+ if (typeof secondary !== "object") return INVALID_CRITERION;
2203
+ if (typeof secondary.attributeKey !== "string" || secondary.attributeKey.length === 0) {
2204
+ return INVALID_CRITERION;
2205
+ }
2206
+ if (secondary.attributeKey === input.attributeKey) return INVALID_CRITERION;
2207
+ const window2 = toLevelWindow(secondary);
2208
+ if (window2 === null) return INVALID_CRITERION;
2209
+ if (!isValidDirection(secondary.direction)) return INVALID_CRITERION;
2210
+ return {
2211
+ attributeKey: secondary.attributeKey,
2212
+ startLevel: window2.startLevel,
2213
+ depth: window2.depth,
2214
+ direction: secondary.direction
2215
+ };
2216
+ }
2217
+ function toGroupState(input) {
2218
+ if (typeof input.attributeKey !== "string" || input.attributeKey.length === 0) {
2219
+ return null;
2220
+ }
2221
+ const window2 = toLevelWindow(input);
2222
+ if (window2 === null) return null;
2223
+ if (!isValidDirection(input.direction)) {
2175
2224
  return null;
2176
2225
  }
2177
2226
  if (typeof input.includeWbs !== "boolean") return null;
2178
2227
  if (!Array.isArray(input.collapsedIds) || input.collapsedIds.some((id) => typeof id !== "string")) {
2179
2228
  return null;
2180
2229
  }
2230
+ const secondary = toSecondaryCriterion(input);
2231
+ if (secondary === INVALID_CRITERION) return null;
2181
2232
  return {
2182
2233
  attributeKey: input.attributeKey,
2183
- depth: input.depth,
2234
+ startLevel: window2.startLevel,
2235
+ depth: window2.depth,
2184
2236
  direction: input.direction,
2185
2237
  includeWbs: input.includeWbs,
2186
- collapsedIds: new Set(input.collapsedIds)
2238
+ collapsedIds: new Set(input.collapsedIds),
2239
+ secondary
2187
2240
  };
2188
2241
  }
2189
2242
  function emptyViewChanges(action) {
@@ -4971,6 +5024,7 @@ var POST_PROCESSOR = {
4971
5024
 
4972
5025
  // src/columns/shared/error-codes.ts
4973
5026
  var VALIDATION_REASON = {
5027
+ UNCHANGED: "unchanged",
4974
5028
  NEGATIVE_DURATION: "negative_duration"};
4975
5029
  var EDIT_DENIAL_REASON = {
4976
5030
  COMPLETED: "completed",
@@ -5444,14 +5498,6 @@ var startDatePipeline = {
5444
5498
  if (isCompletedActivity(activity)) {
5445
5499
  return cannotEdit("completed", "cant_edit_completed_activity");
5446
5500
  }
5447
- if (!isValidDate(edit.newValue)) return canEdit();
5448
- if (isSameDay(activity.startDate, edit.newValue)) return canEdit();
5449
- if (edit.newValue.getTime() > activity.startDate.getTime()) {
5450
- return cannotEdit(
5451
- "sir_start_after_progress",
5452
- "sir_cant_move_start_after_progress"
5453
- );
5454
- }
5455
5501
  return canEdit();
5456
5502
  },
5457
5503
  parseInput(rawValue, _activity, _ctx) {
@@ -15937,6 +15983,7 @@ function mergeBeforeSnapshots(beforeSnap, ids, deps) {
15937
15983
 
15938
15984
  // src/dispatch/handlers/bulk-edit.ts
15939
15985
  var CUSTOM_ID_COLUMN = COLUMN.CUSTOM_ID;
15986
+ var SIR_APPLY_EVENT_SOURCE2 = "sir-apply";
15940
15987
  async function dispatchBulkEdit(action, options, deps) {
15941
15988
  const { adapter, scheduler, sector } = deps;
15942
15989
  const editsIncludeDuration = action.edits.some(
@@ -15960,6 +16007,13 @@ async function dispatchBulkEdit(action, options, deps) {
15960
16007
  for (const edit of action.edits) {
15961
16008
  const outcome = applyOneEdit2(edit, deps, action.eventSource);
15962
16009
  verdicts.push(outcome.verdict);
16010
+ if (action.eventSource === SIR_APPLY_EVENT_SOURCE2 && !outcome.verdict.ok && outcome.verdict.reason !== VALIDATION_REASON.UNCHANGED) {
16011
+ return {
16012
+ ok: false,
16013
+ reason: outcome.verdict.reason ?? REJECTION_REASON.INVALID,
16014
+ ...outcome.verdict.alertKey ? { alertKey: outcome.verdict.alertKey } : {}
16015
+ };
16016
+ }
15963
16017
  if (!outcome.verdict.ok || !outcome.changes) continue;
15964
16018
  const constraintWarning = toConstraintWarning(
15965
16019
  edit.activityId,
@@ -20090,10 +20144,10 @@ var ViewStateStore = class {
20090
20144
  };
20091
20145
 
20092
20146
  // src/internal/view-attributes/project-rows.ts
20093
- function createNode(attributeKey, valueId, label, color, level, sequence) {
20147
+ function createNode(rowId, valueId, label, color, level, sequence) {
20094
20148
  return {
20095
20149
  valueId,
20096
- id: buildGroupRowId(attributeKey, valueId),
20150
+ id: rowId,
20097
20151
  label,
20098
20152
  color,
20099
20153
  level,
@@ -20102,6 +20156,35 @@ function createNode(attributeKey, valueId, label, color, level, sequence) {
20102
20156
  activities: []
20103
20157
  };
20104
20158
  }
20159
+ function buildGroupTree(activities, criterion, catalog, root, nestIds) {
20160
+ const { attributeKey, startLevel, depth } = criterion;
20161
+ for (const activity of activities) {
20162
+ const assignedValueId = catalog.assignmentByActivityId.get(
20163
+ String(activity.id)
20164
+ );
20165
+ const window2 = assignedValueId === void 0 ? [] : levelWindowPath(catalog, assignedValueId, startLevel, depth);
20166
+ const path = window2.length === 0 ? [UNASSIGNED_VALUE_ID] : window2;
20167
+ let cursor = root;
20168
+ path.forEach((valueId, index) => {
20169
+ let child = cursor.children.get(valueId);
20170
+ if (child === void 0) {
20171
+ const value = catalog.valueById.get(valueId);
20172
+ child = createNode(
20173
+ nestIds ? appendGroupRowId(cursor.id, attributeKey, valueId) : buildGroupRowId(attributeKey, valueId),
20174
+ valueId,
20175
+ value?.label ?? (valueId === UNASSIGNED_VALUE_ID ? UNASSIGNED_GROUP_LABEL : valueId),
20176
+ value?.color ?? null,
20177
+ root.level + 1 + index,
20178
+ value?.sequence ?? Number.MAX_SAFE_INTEGER
20179
+ );
20180
+ cursor.children.set(valueId, child);
20181
+ }
20182
+ cursor = child;
20183
+ });
20184
+ cursor.activities.push(activity);
20185
+ }
20186
+ return root;
20187
+ }
20105
20188
  function countActivities(node) {
20106
20189
  let total = node.activities.length;
20107
20190
  for (const child of node.children.values()) total += countActivities(child);
@@ -20138,7 +20221,31 @@ function emitWbsOrderedActivities(memberActivities, activitiesInVisualOrder, par
20138
20221
  });
20139
20222
  }
20140
20223
  }
20141
- function emitNode(node, group, activitiesInVisualOrder, parentOf, rows) {
20224
+ function emitActivities(node, context) {
20225
+ const { rows } = context;
20226
+ if (context.group.includeWbs) {
20227
+ emitWbsOrderedActivities(
20228
+ node.activities,
20229
+ context.activitiesInVisualOrder,
20230
+ context.parentOf,
20231
+ rows
20232
+ );
20233
+ return;
20234
+ }
20235
+ for (const activity of sortSiblingsInOrderMode(
20236
+ [...node.activities],
20237
+ context.comparator,
20238
+ context.orderMode,
20239
+ context.hasChildren
20240
+ )) {
20241
+ rows.push({
20242
+ kind: VISUAL_ROW_KIND.ACTIVITY,
20243
+ activityId: String(activity.id)
20244
+ });
20245
+ }
20246
+ }
20247
+ function emitNode(node, childDirection, allowSecondary, context) {
20248
+ const { group, rows } = context;
20142
20249
  rows.push({
20143
20250
  kind: VISUAL_ROW_KIND.GROUP,
20144
20251
  id: node.id,
@@ -20148,25 +20255,25 @@ function emitNode(node, group, activitiesInVisualOrder, parentOf, rows) {
20148
20255
  activityCount: countActivities(node)
20149
20256
  });
20150
20257
  if (group.collapsedIds.has(node.id)) return;
20151
- for (const child of sortedChildNodes(node, group.direction)) {
20152
- emitNode(child, group, activitiesInVisualOrder, parentOf, rows);
20258
+ for (const child of sortedChildNodes(node, childDirection)) {
20259
+ emitNode(child, childDirection, allowSecondary, context);
20153
20260
  }
20154
20261
  if (node.activities.length === 0) return;
20155
- if (group.includeWbs) {
20156
- emitWbsOrderedActivities(
20262
+ const secondary = group.secondary;
20263
+ if (allowSecondary && secondary != null && context.secondaryCatalog != null) {
20264
+ const secondaryRoot = buildGroupTree(
20157
20265
  node.activities,
20158
- activitiesInVisualOrder,
20159
- parentOf,
20160
- rows
20266
+ secondary,
20267
+ context.secondaryCatalog,
20268
+ createNode(node.id, "", "", null, node.level, 0),
20269
+ true
20161
20270
  );
20271
+ for (const child of sortedChildNodes(secondaryRoot, secondary.direction)) {
20272
+ emitNode(child, secondary.direction, false, context);
20273
+ }
20162
20274
  return;
20163
20275
  }
20164
- for (const activity of node.activities) {
20165
- rows.push({
20166
- kind: VISUAL_ROW_KIND.ACTIVITY,
20167
- activityId: String(activity.id)
20168
- });
20169
- }
20276
+ emitActivities(node, context);
20170
20277
  }
20171
20278
  function projectVisualRows(input) {
20172
20279
  const visibleActivities = input.activitiesInVisualOrder.filter(
@@ -20179,34 +20286,26 @@ function projectVisualRows(input) {
20179
20286
  }));
20180
20287
  }
20181
20288
  const { group, catalog } = input;
20182
- const root = createNode(group.attributeKey, "", "", null, -1, 0);
20183
- for (const activity of visibleActivities) {
20184
- const assignedValueId = catalog.assignmentByActivityId.get(
20185
- String(activity.id)
20186
- );
20187
- const path = assignedValueId === void 0 ? [UNASSIGNED_VALUE_ID] : truncatedPath(catalog, assignedValueId, group.depth);
20188
- let cursor = root;
20189
- path.forEach((valueId, index) => {
20190
- let child = cursor.children.get(valueId);
20191
- if (child === void 0) {
20192
- const value = catalog.valueById.get(valueId);
20193
- child = createNode(
20194
- group.attributeKey,
20195
- valueId,
20196
- value?.label ?? (valueId === UNASSIGNED_VALUE_ID ? UNASSIGNED_GROUP_LABEL : valueId),
20197
- value?.color ?? null,
20198
- index,
20199
- value?.sequence ?? Number.MAX_SAFE_INTEGER
20200
- );
20201
- cursor.children.set(valueId, child);
20202
- }
20203
- cursor = child;
20204
- });
20205
- cursor.activities.push(activity);
20206
- }
20289
+ const root = buildGroupTree(
20290
+ visibleActivities,
20291
+ group,
20292
+ catalog,
20293
+ createNode("", "", "", null, -1, 0),
20294
+ false
20295
+ );
20207
20296
  const rows = [];
20297
+ const context = {
20298
+ group,
20299
+ activitiesInVisualOrder: input.activitiesInVisualOrder,
20300
+ parentOf: input.parentOf,
20301
+ hasChildren: input.hasChildren,
20302
+ comparator: input.comparator,
20303
+ orderMode: input.orderMode,
20304
+ secondaryCatalog: input.secondaryCatalog,
20305
+ rows
20306
+ };
20208
20307
  for (const child of sortedChildNodes(root, group.direction)) {
20209
- emitNode(child, group, input.activitiesInVisualOrder, input.parentOf, rows);
20308
+ emitNode(child, group.direction, true, context);
20210
20309
  }
20211
20310
  return rows;
20212
20311
  }
@@ -20482,6 +20581,7 @@ var ScheduleState = class _ScheduleState {
20482
20581
  if (this._cache.visualRows) return this._cache.visualRows;
20483
20582
  const group = this._viewAttributes.getGroup();
20484
20583
  const catalog = group === null ? null : this._viewAttributes.getCatalog(group.attributeKey);
20584
+ const secondaryCatalog = group?.secondary == null ? null : this._viewAttributes.getCatalog(group.secondary.attributeKey);
20485
20585
  const activitiesInVisualOrder = [];
20486
20586
  for (const activityId of this.getVisualOrderIds()) {
20487
20587
  const activity = this.getActivity(activityId);
@@ -20491,8 +20591,12 @@ var ScheduleState = class _ScheduleState {
20491
20591
  activitiesInVisualOrder,
20492
20592
  isVisible: (activityId) => this.isVisible(activityId),
20493
20593
  parentOf: (activityId) => this.getParentId(activityId),
20594
+ hasChildren: (activityId) => this.hasChildren(activityId),
20494
20595
  group,
20495
- catalog
20596
+ catalog,
20597
+ secondaryCatalog,
20598
+ comparator: this.getOrderComparator(),
20599
+ orderMode: this.getOrderMode()
20496
20600
  });
20497
20601
  return this._cache.visualRows;
20498
20602
  }
@@ -25284,6 +25388,6 @@ var CREATION_KIND = {
25284
25388
  ROOT: "root"
25285
25389
  };
25286
25390
 
25287
- export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, MINIMUM_GROUP_DEPTH, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, WORK_TIME_DIRECTION, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
25391
+ export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, MINIMUM_GROUP_DEPTH, MINIMUM_GROUP_LEVEL, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, WORK_TIME_DIRECTION, appendGroupRowId, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
25288
25392
  //# sourceMappingURL=index.js.map
25289
25393
  //# sourceMappingURL=index.js.map