@masmarino/gabarit 1.0.3 → 1.1.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, input, computed, ChangeDetectionStrategy, Component, output, signal, viewChild, HostListener, booleanAttribute, ElementRef, forwardRef, effect, contentChildren, viewChildren, model, InjectionToken, isDevMode, Injector, afterNextRender, TemplateRef } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, input, computed, ChangeDetectionStrategy, Component, output, signal, viewChild, HostListener, booleanAttribute, ElementRef, forwardRef, effect, contentChildren, viewChildren, model, InjectionToken, isDevMode, Injector, afterNextRender, TemplateRef, DestroyRef, afterRenderEffect } from '@angular/core';
|
|
3
3
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
@@ -7,7 +7,7 @@ import { NG_VALUE_ACCESSOR, FormControl, ReactiveFormsModule, FormsModule } from
|
|
|
7
7
|
import { NgTemplateOutlet } from '@angular/common';
|
|
8
8
|
import { isObservable } from 'rxjs';
|
|
9
9
|
|
|
10
|
-
const GABARIT_VERSION = '1.0
|
|
10
|
+
const GABARIT_VERSION = '1.1.0';
|
|
11
11
|
|
|
12
12
|
const BUILT_IN_ICONS = {
|
|
13
13
|
search: `<path d="m21 21-4.34-4.34" />
|
|
@@ -1598,12 +1598,12 @@ function formatPercent(ratio, locale, decimals = 0) {
|
|
|
1598
1598
|
}).format(ratio);
|
|
1599
1599
|
}
|
|
1600
1600
|
|
|
1601
|
-
const round = (n) => Number(n.toFixed(2));
|
|
1601
|
+
const round$1 = (n) => Number(n.toFixed(2));
|
|
1602
1602
|
function linePath(points) {
|
|
1603
1603
|
if (points.length === 0)
|
|
1604
1604
|
return '';
|
|
1605
1605
|
return points
|
|
1606
|
-
.map((point, index) => `${index === 0 ? 'M' : 'L'}${round(point.x)},${round(point.y)}`)
|
|
1606
|
+
.map((point, index) => `${index === 0 ? 'M' : 'L'}${round$1(point.x)},${round$1(point.y)}`)
|
|
1607
1607
|
.join('');
|
|
1608
1608
|
}
|
|
1609
1609
|
function areaPath(points, baseline) {
|
|
@@ -1611,13 +1611,13 @@ function areaPath(points, baseline) {
|
|
|
1611
1611
|
return '';
|
|
1612
1612
|
const last = points[points.length - 1];
|
|
1613
1613
|
const first = points[0];
|
|
1614
|
-
return `${linePath(points)}L${round(last.x)},${round(baseline)}L${round(first.x)},${round(baseline)}Z`;
|
|
1614
|
+
return `${linePath(points)}L${round$1(last.x)},${round$1(baseline)}L${round$1(first.x)},${round$1(baseline)}Z`;
|
|
1615
1615
|
}
|
|
1616
1616
|
function arcPoint(radius, angle) {
|
|
1617
1617
|
return { x: radius * Math.sin(angle), y: -radius * Math.cos(angle) };
|
|
1618
1618
|
}
|
|
1619
1619
|
function point(p) {
|
|
1620
|
-
return `${round(p.x)},${round(p.y)}`;
|
|
1620
|
+
return `${round$1(p.x)},${round$1(p.y)}`;
|
|
1621
1621
|
}
|
|
1622
1622
|
const FULL_CIRCLE = Math.PI * 2;
|
|
1623
1623
|
function arcPath(arc) {
|
|
@@ -1633,13 +1633,13 @@ function arcPath(arc) {
|
|
|
1633
1633
|
const largeArc = span > Math.PI ? 1 : 0;
|
|
1634
1634
|
const outerStart = arcPoint(outerRadius, startAngle);
|
|
1635
1635
|
const outerEnd = arcPoint(outerRadius, endAngle);
|
|
1636
|
-
const outerArc = `A${round(outerRadius)},${round(outerRadius)} 0 ${largeArc},1 ${point(outerEnd)}`;
|
|
1636
|
+
const outerArc = `A${round$1(outerRadius)},${round$1(outerRadius)} 0 ${largeArc},1 ${point(outerEnd)}`;
|
|
1637
1637
|
if (innerRadius <= 0) {
|
|
1638
1638
|
return `M0,0L${point(outerStart)}${outerArc}Z`;
|
|
1639
1639
|
}
|
|
1640
1640
|
const innerStart = arcPoint(innerRadius, startAngle);
|
|
1641
1641
|
const innerEnd = arcPoint(innerRadius, endAngle);
|
|
1642
|
-
const innerArc = `A${round(innerRadius)},${round(innerRadius)} 0 ${largeArc},0 ${point(innerStart)}`;
|
|
1642
|
+
const innerArc = `A${round$1(innerRadius)},${round$1(innerRadius)} 0 ${largeArc},0 ${point(innerStart)}`;
|
|
1643
1643
|
return `M${point(outerStart)}${outerArc}L${point(innerEnd)}${innerArc}Z`;
|
|
1644
1644
|
}
|
|
1645
1645
|
|
|
@@ -4958,6 +4958,17 @@ class Stepper {
|
|
|
4958
4958
|
...(ngDevMode ? [{ debugName: "completedLabel" }] : /* istanbul ignore next */ []));
|
|
4959
4959
|
errorLabel = input('Error', /* @ts-ignore */
|
|
4960
4960
|
...(ngDevMode ? [{ debugName: "errorLabel" }] : /* istanbul ignore next */ []));
|
|
4961
|
+
interactive = input(false, { ...(ngDevMode ? { debugName: "interactive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4962
|
+
selectedIndex = model(null, /* @ts-ignore */
|
|
4963
|
+
...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
|
|
4964
|
+
selectedLabel = input('Selected', /* @ts-ignore */
|
|
4965
|
+
...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
|
|
4966
|
+
select(index) {
|
|
4967
|
+
this.selectedIndex.set(index);
|
|
4968
|
+
}
|
|
4969
|
+
isSelected(index) {
|
|
4970
|
+
return this.interactive() && this.selectedIndex() === index;
|
|
4971
|
+
}
|
|
4961
4972
|
statusOf(index) {
|
|
4962
4973
|
const step = this.steps()[index];
|
|
4963
4974
|
const active = this.activeIndex();
|
|
@@ -4973,12 +4984,104 @@ class Stepper {
|
|
|
4973
4984
|
return 'upcoming';
|
|
4974
4985
|
}
|
|
4975
4986
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Stepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4976
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: Stepper, isStandalone: true, selector: "gbt-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, completedLabel: { classPropertyName: "completedLabel", publicName: "completedLabel", isSignal: true, isRequired: false, transformFunction: null }, errorLabel: { classPropertyName: "errorLabel", publicName: "errorLabel", isSignal: true, isRequired: false, transformFunction: null }
|
|
4987
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: Stepper, isStandalone: true, selector: "gbt-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, completedLabel: { classPropertyName: "completedLabel", publicName: "completedLabel", isSignal: true, isRequired: false, transformFunction: null }, errorLabel: { classPropertyName: "errorLabel", publicName: "errorLabel", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedLabel: { classPropertyName: "selectedLabel", publicName: "selectedLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange", selectedIndex: "selectedIndexChange" }, ngImport: i0, template: "<ng-template #content let-index=\"index\" let-step=\"step\">\n <span class=\"gbt-stepper__indicator\">\n @switch (statusOf(index)) {\n @case ('completed') {\n <gbt-icon name=\"check\" aria-hidden=\"true\" />\n }\n @case ('error') {\n <gbt-icon name=\"alert-triangle\" aria-hidden=\"true\" />\n }\n @default {\n {{ index + 1 }}\n }\n }\n </span>\n <span class=\"gbt-stepper__label\">\n {{ step.label }}\n @if (statusOf(index) === 'completed') {\n <span class=\"sr-only\"> \u2014 {{ completedLabel() }}</span>\n } @else if (statusOf(index) === 'error') {\n <span class=\"sr-only\"> \u2014 {{ errorLabel() }}</span>\n }\n @if (isSelected(index)) {\n <span class=\"sr-only\"> \u2014 {{ selectedLabel() }}</span>\n }\n </span>\n</ng-template>\n\n<ol class=\"gbt-stepper\" [attr.data-orientation]=\"orientation()\">\n @for (step of steps(); track $index) {\n <li\n class=\"gbt-stepper__step\"\n [attr.data-status]=\"statusOf($index)\"\n [attr.data-selected]=\"isSelected($index) ? '' : null\"\n [attr.aria-current]=\"statusOf($index) === 'current' ? 'step' : null\"\n >\n @if (interactive()) {\n <button type=\"button\" class=\"gbt-stepper__button\" (click)=\"select($index)\">\n <ng-container *ngTemplateOutlet=\"content; context: { index: $index, step: step }\" />\n </button>\n } @else {\n <ng-container *ngTemplateOutlet=\"content; context: { index: $index, step: step }\" />\n }\n </li>\n }\n</ol>\n", styles: [".gbt-stepper{display:flex;margin:0;padding:0;list-style:none}.gbt-stepper[data-orientation=horizontal]{flex-direction:row}.gbt-stepper[data-orientation=vertical]{flex-direction:column;gap:.5rem}.gbt-stepper__step{position:relative;display:flex;flex:1;align-items:center;gap:.5rem}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step{flex-direction:column}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step:not(:first-child):before{content:\"\";position:absolute;top:15px;right:calc(50% + 16px);left:calc(-50% + 16px);height:2px;background:var(--border-color)}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step[data-status=completed]:not(:first-child):before{background:var(--primary)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step{flex:none;flex-direction:row}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step:not(:last-child):before{content:\"\";position:absolute;top:32px;bottom:-8px;left:15px;width:2px;background:var(--border-color)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step[data-status=completed]:not(:last-child):before{background:var(--primary)}.gbt-stepper__indicator{position:relative;z-index:1;box-sizing:border-box;display:flex;flex-shrink:0;align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg-principal);border:2px solid var(--border-color);border-radius:50%;color:var(--text-secondary);font-size:13px;font-weight:600}.gbt-stepper__step[data-status=current] .gbt-stepper__indicator{border-color:var(--primary);color:var(--primary)}.gbt-stepper__step[data-status=completed] .gbt-stepper__indicator{background:var(--primary);border-color:var(--primary);color:var(--text-on-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__indicator{border-color:var(--color-error-text);color:var(--color-error-text)}.gbt-stepper__label{font-size:13px;font-weight:600;color:var(--text-secondary);text-align:center}.gbt-stepper[data-orientation=vertical] .gbt-stepper__label{text-align:left}.gbt-stepper__step[data-status=current] .gbt-stepper__label{color:var(--text-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__label{color:var(--color-error-text)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.gbt-stepper__button{display:flex;align-items:center;gap:.5rem;padding:0;background:none;border:0;border-radius:4px;font:inherit;color:inherit;cursor:pointer}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__button{flex-direction:column}.gbt-stepper[data-orientation=vertical] .gbt-stepper__button{flex-direction:row}.gbt-stepper__button:focus-visible{outline:2px solid var(--primary);outline-offset:4px}.gbt-stepper__step[data-selected] .gbt-stepper__indicator{box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 30%,transparent)}.gbt-stepper__step[data-selected] .gbt-stepper__label{text-decoration:underline;text-underline-offset:4px}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4977
4988
|
}
|
|
4978
4989
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Stepper, decorators: [{
|
|
4979
4990
|
type: Component,
|
|
4980
|
-
args: [{ selector: 'gbt-stepper', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<
|
|
4981
|
-
}], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], completedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "completedLabel", required: false }] }], errorLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorLabel", required: false }] }] } });
|
|
4991
|
+
args: [{ selector: 'gbt-stepper', standalone: true, imports: [Icon, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #content let-index=\"index\" let-step=\"step\">\n <span class=\"gbt-stepper__indicator\">\n @switch (statusOf(index)) {\n @case ('completed') {\n <gbt-icon name=\"check\" aria-hidden=\"true\" />\n }\n @case ('error') {\n <gbt-icon name=\"alert-triangle\" aria-hidden=\"true\" />\n }\n @default {\n {{ index + 1 }}\n }\n }\n </span>\n <span class=\"gbt-stepper__label\">\n {{ step.label }}\n @if (statusOf(index) === 'completed') {\n <span class=\"sr-only\"> \u2014 {{ completedLabel() }}</span>\n } @else if (statusOf(index) === 'error') {\n <span class=\"sr-only\"> \u2014 {{ errorLabel() }}</span>\n }\n @if (isSelected(index)) {\n <span class=\"sr-only\"> \u2014 {{ selectedLabel() }}</span>\n }\n </span>\n</ng-template>\n\n<ol class=\"gbt-stepper\" [attr.data-orientation]=\"orientation()\">\n @for (step of steps(); track $index) {\n <li\n class=\"gbt-stepper__step\"\n [attr.data-status]=\"statusOf($index)\"\n [attr.data-selected]=\"isSelected($index) ? '' : null\"\n [attr.aria-current]=\"statusOf($index) === 'current' ? 'step' : null\"\n >\n @if (interactive()) {\n <button type=\"button\" class=\"gbt-stepper__button\" (click)=\"select($index)\">\n <ng-container *ngTemplateOutlet=\"content; context: { index: $index, step: step }\" />\n </button>\n } @else {\n <ng-container *ngTemplateOutlet=\"content; context: { index: $index, step: step }\" />\n }\n </li>\n }\n</ol>\n", styles: [".gbt-stepper{display:flex;margin:0;padding:0;list-style:none}.gbt-stepper[data-orientation=horizontal]{flex-direction:row}.gbt-stepper[data-orientation=vertical]{flex-direction:column;gap:.5rem}.gbt-stepper__step{position:relative;display:flex;flex:1;align-items:center;gap:.5rem}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step{flex-direction:column}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step:not(:first-child):before{content:\"\";position:absolute;top:15px;right:calc(50% + 16px);left:calc(-50% + 16px);height:2px;background:var(--border-color)}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step[data-status=completed]:not(:first-child):before{background:var(--primary)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step{flex:none;flex-direction:row}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step:not(:last-child):before{content:\"\";position:absolute;top:32px;bottom:-8px;left:15px;width:2px;background:var(--border-color)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step[data-status=completed]:not(:last-child):before{background:var(--primary)}.gbt-stepper__indicator{position:relative;z-index:1;box-sizing:border-box;display:flex;flex-shrink:0;align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg-principal);border:2px solid var(--border-color);border-radius:50%;color:var(--text-secondary);font-size:13px;font-weight:600}.gbt-stepper__step[data-status=current] .gbt-stepper__indicator{border-color:var(--primary);color:var(--primary)}.gbt-stepper__step[data-status=completed] .gbt-stepper__indicator{background:var(--primary);border-color:var(--primary);color:var(--text-on-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__indicator{border-color:var(--color-error-text);color:var(--color-error-text)}.gbt-stepper__label{font-size:13px;font-weight:600;color:var(--text-secondary);text-align:center}.gbt-stepper[data-orientation=vertical] .gbt-stepper__label{text-align:left}.gbt-stepper__step[data-status=current] .gbt-stepper__label{color:var(--text-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__label{color:var(--color-error-text)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.gbt-stepper__button{display:flex;align-items:center;gap:.5rem;padding:0;background:none;border:0;border-radius:4px;font:inherit;color:inherit;cursor:pointer}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__button{flex-direction:column}.gbt-stepper[data-orientation=vertical] .gbt-stepper__button{flex-direction:row}.gbt-stepper__button:focus-visible{outline:2px solid var(--primary);outline-offset:4px}.gbt-stepper__step[data-selected] .gbt-stepper__indicator{box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 30%,transparent)}.gbt-stepper__step[data-selected] .gbt-stepper__label{text-decoration:underline;text-underline-offset:4px}\n"] }]
|
|
4992
|
+
}], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], completedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "completedLabel", required: false }] }], errorLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorLabel", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }, { type: i0.Output, args: ["selectedIndexChange"] }], selectedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedLabel", required: false }] }] } });
|
|
4993
|
+
|
|
4994
|
+
function graphEdges(stages) {
|
|
4995
|
+
const names = new Set(stages.flatMap((stage) => stage.jobs.map((job) => job.name)));
|
|
4996
|
+
return stages.flatMap((stage) => stage.jobs.flatMap((job) => job.needs.filter((need) => names.has(need)).map((need) => ({ from: need, to: job.name }))));
|
|
4997
|
+
}
|
|
4998
|
+
const round = (value) => Math.round(value * 10) / 10;
|
|
4999
|
+
function linkPath(from, to) {
|
|
5000
|
+
const x1 = from.left + from.width;
|
|
5001
|
+
const y1 = from.top + from.height / 2;
|
|
5002
|
+
const x2 = to.left;
|
|
5003
|
+
const y2 = to.top + to.height / 2;
|
|
5004
|
+
const dx = Math.max(24, (x2 - x1) / 2);
|
|
5005
|
+
return `M ${round(x1)} ${round(y1)} C ${round(x1 + dx)} ${round(y1)}, ${round(x2 - dx)} ${round(y2)}, ${round(x2)} ${round(y2)}`;
|
|
5006
|
+
}
|
|
5007
|
+
|
|
5008
|
+
const DEFAULT_STATUS_LABELS = {
|
|
5009
|
+
pending: 'Pending',
|
|
5010
|
+
running: 'Running',
|
|
5011
|
+
success: 'Succeeded',
|
|
5012
|
+
failed: 'Failed',
|
|
5013
|
+
canceled: 'Canceled',
|
|
5014
|
+
};
|
|
5015
|
+
class JobGraph {
|
|
5016
|
+
stages = input.required(/* @ts-ignore */
|
|
5017
|
+
...(ngDevMode ? [{ debugName: "stages" }] : /* istanbul ignore next */ []));
|
|
5018
|
+
selectedJobId = input(null, /* @ts-ignore */
|
|
5019
|
+
...(ngDevMode ? [{ debugName: "selectedJobId" }] : /* istanbul ignore next */ []));
|
|
5020
|
+
statusLabels = input(DEFAULT_STATUS_LABELS, /* @ts-ignore */
|
|
5021
|
+
...(ngDevMode ? [{ debugName: "statusLabels" }] : /* istanbul ignore next */ []));
|
|
5022
|
+
needsLabel = input('Needs', /* @ts-ignore */
|
|
5023
|
+
...(ngDevMode ? [{ debugName: "needsLabel" }] : /* istanbul ignore next */ []));
|
|
5024
|
+
ariaLabel = input('Pipeline jobs', /* @ts-ignore */
|
|
5025
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
5026
|
+
jobSelected = output();
|
|
5027
|
+
links = signal([], /* @ts-ignore */
|
|
5028
|
+
...(ngDevMode ? [{ debugName: "links" }] : /* istanbul ignore next */ []));
|
|
5029
|
+
graph = viewChild('graph', /* @ts-ignore */
|
|
5030
|
+
...(ngDevMode ? [{ debugName: "graph" }] : /* istanbul ignore next */ []));
|
|
5031
|
+
destroyRef = inject(DestroyRef);
|
|
5032
|
+
constructor() {
|
|
5033
|
+
afterRenderEffect(() => {
|
|
5034
|
+
this.stages();
|
|
5035
|
+
this.measure();
|
|
5036
|
+
});
|
|
5037
|
+
afterNextRender(() => {
|
|
5038
|
+
const root = this.graph()?.nativeElement;
|
|
5039
|
+
if (!root || typeof ResizeObserver === 'undefined') {
|
|
5040
|
+
return;
|
|
5041
|
+
}
|
|
5042
|
+
const observer = new ResizeObserver(() => this.measure());
|
|
5043
|
+
observer.observe(root);
|
|
5044
|
+
this.destroyRef.onDestroy(() => observer.disconnect());
|
|
5045
|
+
});
|
|
5046
|
+
}
|
|
5047
|
+
measure() {
|
|
5048
|
+
const root = this.graph()?.nativeElement;
|
|
5049
|
+
if (!root) {
|
|
5050
|
+
return;
|
|
5051
|
+
}
|
|
5052
|
+
const origin = root.getBoundingClientRect();
|
|
5053
|
+
const boxes = new Map();
|
|
5054
|
+
root.querySelectorAll('[data-job-name]').forEach((node) => {
|
|
5055
|
+
const rect = node.getBoundingClientRect();
|
|
5056
|
+
boxes.set(node.dataset['jobName'] ?? '', {
|
|
5057
|
+
left: rect.left - origin.left + root.scrollLeft,
|
|
5058
|
+
top: rect.top - origin.top + root.scrollTop,
|
|
5059
|
+
width: rect.width,
|
|
5060
|
+
height: rect.height,
|
|
5061
|
+
});
|
|
5062
|
+
});
|
|
5063
|
+
const statuses = new Map(this.stages().flatMap((s) => s.jobs.map((j) => [j.name, j.status])));
|
|
5064
|
+
this.links.set(graphEdges(this.stages()).flatMap((edge) => {
|
|
5065
|
+
const from = boxes.get(edge.from);
|
|
5066
|
+
const to = boxes.get(edge.to);
|
|
5067
|
+
return from && to
|
|
5068
|
+
? [
|
|
5069
|
+
{
|
|
5070
|
+
key: `${edge.from}->${edge.to}`,
|
|
5071
|
+
d: linkPath(from, to),
|
|
5072
|
+
done: statuses.get(edge.from) === 'success',
|
|
5073
|
+
},
|
|
5074
|
+
]
|
|
5075
|
+
: [];
|
|
5076
|
+
}));
|
|
5077
|
+
}
|
|
5078
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: JobGraph, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5079
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: JobGraph, isStandalone: true, selector: "gbt-job-graph", inputs: { stages: { classPropertyName: "stages", publicName: "stages", isSignal: true, isRequired: true, transformFunction: null }, selectedJobId: { classPropertyName: "selectedJobId", publicName: "selectedJobId", isSignal: true, isRequired: false, transformFunction: null }, statusLabels: { classPropertyName: "statusLabels", publicName: "statusLabels", isSignal: true, isRequired: false, transformFunction: null }, needsLabel: { classPropertyName: "needsLabel", publicName: "needsLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { jobSelected: "jobSelected" }, viewQueries: [{ propertyName: "graph", first: true, predicate: ["graph"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"gbt-job-graph\" #graph>\n <ol class=\"gbt-job-graph__stages\" [attr.aria-label]=\"ariaLabel()\">\n @for (stage of stages(); track stage.name) {\n <li class=\"gbt-job-graph__stage\">\n <h3 class=\"gbt-job-graph__stage-name\">{{ stage.name }}</h3>\n <ul class=\"gbt-job-graph__jobs\">\n @for (job of stage.jobs; track job.id) {\n <li>\n <button\n type=\"button\"\n class=\"gbt-job-graph__node\"\n [attr.data-job-name]=\"job.name\"\n [attr.data-status]=\"job.status\"\n [attr.aria-current]=\"job.id === selectedJobId() ? 'true' : null\"\n (click)=\"jobSelected.emit(job.id)\"\n >\n <span class=\"gbt-job-graph__glyph\" data-glyph aria-hidden=\"true\">\n @switch (job.status) {\n @case ('success') {\n <gbt-icon name=\"check-circle\" />\n }\n @case ('failed') {\n <gbt-icon name=\"alert-circle\" />\n }\n @case ('canceled') {\n <gbt-icon name=\"x\" />\n }\n @default {\n <span class=\"gbt-job-graph__dot\"></span>\n }\n }\n </span>\n <span class=\"gbt-job-graph__name\">{{ job.name }}</span>\n @if (job.durationLabel) {\n <span class=\"gbt-job-graph__duration\">{{ job.durationLabel }}</span>\n }\n <span class=\"sr-only\">\n \u2014 {{ statusLabels()[job.status] }}@if (job.needs.length > 0) {. {{ needsLabel() }}: {{ job.needs.join(', ') }}}\n </span>\n </button>\n </li>\n }\n </ul>\n </li>\n }\n </ol>\n <svg class=\"gbt-job-graph__links\" aria-hidden=\"true\" focusable=\"false\">\n @for (link of links(); track link.key) {\n <path [attr.d]=\"link.d\" [attr.data-done]=\"link.done ? '' : null\" />\n }\n </svg>\n</div>\n", styles: [".gbt-job-graph{position:relative;overflow-x:auto}.gbt-job-graph__stages{position:relative;z-index:1;display:flex;gap:4rem;margin:0;padding:.5rem;list-style:none}.gbt-job-graph__stage-name{margin:0 0 .75rem;font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-secondary)}.gbt-job-graph__jobs{display:flex;flex-direction:column;gap:.75rem;margin:0;padding:0;list-style:none}.gbt-job-graph__node{display:flex;align-items:center;gap:.5rem;min-width:13rem;padding:.5rem .75rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:8px;color:var(--text-primary);font:inherit;text-align:left;cursor:pointer}.gbt-job-graph__node:hover{border-color:var(--primary)}.gbt-job-graph__node:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-job-graph__node[aria-current=true]{border-color:var(--primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--primary) 30%,transparent)}.gbt-job-graph__glyph{display:inline-flex;flex-shrink:0}.gbt-job-graph__node[data-status=success] .gbt-job-graph__glyph{color:var(--color-success-text)}.gbt-job-graph__node[data-status=failed] .gbt-job-graph__glyph{color:var(--color-error-text)}.gbt-job-graph__node[data-status=canceled] .gbt-job-graph__glyph{color:var(--text-secondary)}.gbt-job-graph__dot{box-sizing:border-box;width:16px;height:16px;border:2px solid var(--border-color);border-radius:50%}.gbt-job-graph__node[data-status=running] .gbt-job-graph__dot{border-color:var(--primary);border-top-color:transparent;animation:gbt-job-graph-spin .9s linear infinite}@media(prefers-reduced-motion:reduce){.gbt-job-graph__node[data-status=running] .gbt-job-graph__dot{animation:none;border-top-color:var(--primary);background:var(--primary)}}@keyframes gbt-job-graph-spin{to{transform:rotate(360deg)}}.gbt-job-graph__name{flex:1;font-weight:600}.gbt-job-graph__duration{font-size:12px;color:var(--text-secondary)}.gbt-job-graph__links{position:absolute;inset:0;z-index:0;width:100%;height:100%;pointer-events:none;overflow:visible}.gbt-job-graph__links path{fill:none;stroke:var(--border-color);stroke-width:2}.gbt-job-graph__links path[data-done]{stroke:var(--color-success-base)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5080
|
+
}
|
|
5081
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: JobGraph, decorators: [{
|
|
5082
|
+
type: Component,
|
|
5083
|
+
args: [{ selector: 'gbt-job-graph', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-job-graph\" #graph>\n <ol class=\"gbt-job-graph__stages\" [attr.aria-label]=\"ariaLabel()\">\n @for (stage of stages(); track stage.name) {\n <li class=\"gbt-job-graph__stage\">\n <h3 class=\"gbt-job-graph__stage-name\">{{ stage.name }}</h3>\n <ul class=\"gbt-job-graph__jobs\">\n @for (job of stage.jobs; track job.id) {\n <li>\n <button\n type=\"button\"\n class=\"gbt-job-graph__node\"\n [attr.data-job-name]=\"job.name\"\n [attr.data-status]=\"job.status\"\n [attr.aria-current]=\"job.id === selectedJobId() ? 'true' : null\"\n (click)=\"jobSelected.emit(job.id)\"\n >\n <span class=\"gbt-job-graph__glyph\" data-glyph aria-hidden=\"true\">\n @switch (job.status) {\n @case ('success') {\n <gbt-icon name=\"check-circle\" />\n }\n @case ('failed') {\n <gbt-icon name=\"alert-circle\" />\n }\n @case ('canceled') {\n <gbt-icon name=\"x\" />\n }\n @default {\n <span class=\"gbt-job-graph__dot\"></span>\n }\n }\n </span>\n <span class=\"gbt-job-graph__name\">{{ job.name }}</span>\n @if (job.durationLabel) {\n <span class=\"gbt-job-graph__duration\">{{ job.durationLabel }}</span>\n }\n <span class=\"sr-only\">\n \u2014 {{ statusLabels()[job.status] }}@if (job.needs.length > 0) {. {{ needsLabel() }}: {{ job.needs.join(', ') }}}\n </span>\n </button>\n </li>\n }\n </ul>\n </li>\n }\n </ol>\n <svg class=\"gbt-job-graph__links\" aria-hidden=\"true\" focusable=\"false\">\n @for (link of links(); track link.key) {\n <path [attr.d]=\"link.d\" [attr.data-done]=\"link.done ? '' : null\" />\n }\n </svg>\n</div>\n", styles: [".gbt-job-graph{position:relative;overflow-x:auto}.gbt-job-graph__stages{position:relative;z-index:1;display:flex;gap:4rem;margin:0;padding:.5rem;list-style:none}.gbt-job-graph__stage-name{margin:0 0 .75rem;font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-secondary)}.gbt-job-graph__jobs{display:flex;flex-direction:column;gap:.75rem;margin:0;padding:0;list-style:none}.gbt-job-graph__node{display:flex;align-items:center;gap:.5rem;min-width:13rem;padding:.5rem .75rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:8px;color:var(--text-primary);font:inherit;text-align:left;cursor:pointer}.gbt-job-graph__node:hover{border-color:var(--primary)}.gbt-job-graph__node:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-job-graph__node[aria-current=true]{border-color:var(--primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--primary) 30%,transparent)}.gbt-job-graph__glyph{display:inline-flex;flex-shrink:0}.gbt-job-graph__node[data-status=success] .gbt-job-graph__glyph{color:var(--color-success-text)}.gbt-job-graph__node[data-status=failed] .gbt-job-graph__glyph{color:var(--color-error-text)}.gbt-job-graph__node[data-status=canceled] .gbt-job-graph__glyph{color:var(--text-secondary)}.gbt-job-graph__dot{box-sizing:border-box;width:16px;height:16px;border:2px solid var(--border-color);border-radius:50%}.gbt-job-graph__node[data-status=running] .gbt-job-graph__dot{border-color:var(--primary);border-top-color:transparent;animation:gbt-job-graph-spin .9s linear infinite}@media(prefers-reduced-motion:reduce){.gbt-job-graph__node[data-status=running] .gbt-job-graph__dot{animation:none;border-top-color:var(--primary);background:var(--primary)}}@keyframes gbt-job-graph-spin{to{transform:rotate(360deg)}}.gbt-job-graph__name{flex:1;font-weight:600}.gbt-job-graph__duration{font-size:12px;color:var(--text-secondary)}.gbt-job-graph__links{position:absolute;inset:0;z-index:0;width:100%;height:100%;pointer-events:none;overflow:visible}.gbt-job-graph__links path{fill:none;stroke:var(--border-color);stroke-width:2}.gbt-job-graph__links path[data-done]{stroke:var(--color-success-base)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}\n"] }]
|
|
5084
|
+
}], ctorParameters: () => [], propDecorators: { stages: [{ type: i0.Input, args: [{ isSignal: true, alias: "stages", required: true }] }], selectedJobId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedJobId", required: false }] }], statusLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusLabels", required: false }] }], needsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "needsLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], jobSelected: [{ type: i0.Output, args: ["jobSelected"] }], graph: [{ type: i0.ViewChild, args: ['graph', { isSignal: true }] }] } });
|
|
4982
5085
|
|
|
4983
5086
|
let nextId$1 = 0;
|
|
4984
5087
|
function formatFileSize(bytes) {
|
|
@@ -5405,5 +5508,5 @@ function cssEscape(value) {
|
|
|
5405
5508
|
* Generated bundle index. Do not edit.
|
|
5406
5509
|
*/
|
|
5407
5510
|
|
|
5408
|
-
export { Accordion, AccordionItem, Alert, AppShell, Autocomplete, Avatar, AvatarGroup, Badge, BarChart, BarSeries, Breadcrumb, Button, CHART_CONTEXT, Card, ChartAxis, ChartEmpty, ChartFrame, ChartLegend, ChartTable, ChartTooltip, Checkbox, ConfirmDangerModal, DatePicker, DateRangePicker, DescriptionList, DimensionCard, Divider, Drawer, EmptyState, FileUpload, FunnelChart, GABARIT_VERSION, GaugeBar, GbtInput, Icon, IconRegistry, LineChart, LineSeries, ListToolbar, Menu, Modal, NotificationDot, Pagination, PieChart, Popover, RadioGroup, SearchBar, SegmentedControl, Select, Skeleton, Slider, Sparkline, Spinner, Stepper, Switch, Tab, Table, Tabs, Tag, TagInput, Textarea, TimelineChart, TimelineSeries, Toaster, Tooltip, Tree, arcPath, areaPath, bandScale, formatCompact, formatDuration, formatNumber, formatPercent, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, timeScale, timeTicks };
|
|
5511
|
+
export { Accordion, AccordionItem, Alert, AppShell, Autocomplete, Avatar, AvatarGroup, Badge, BarChart, BarSeries, Breadcrumb, Button, CHART_CONTEXT, Card, ChartAxis, ChartEmpty, ChartFrame, ChartLegend, ChartTable, ChartTooltip, Checkbox, ConfirmDangerModal, DatePicker, DateRangePicker, DescriptionList, DimensionCard, Divider, Drawer, EmptyState, FileUpload, FunnelChart, GABARIT_VERSION, GaugeBar, GbtInput, Icon, IconRegistry, JobGraph, LineChart, LineSeries, ListToolbar, Menu, Modal, NotificationDot, Pagination, PieChart, Popover, RadioGroup, SearchBar, SegmentedControl, Select, Skeleton, Slider, Sparkline, Spinner, Stepper, Switch, Tab, Table, Tabs, Tag, TagInput, Textarea, TimelineChart, TimelineSeries, Toaster, Tooltip, Tree, arcPath, areaPath, bandScale, formatCompact, formatDuration, formatNumber, formatPercent, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, timeScale, timeTicks };
|
|
5409
5512
|
//# sourceMappingURL=masmarino-gabarit.mjs.map
|