@openmfp/webcomponents 0.6.1 → 0.6.7

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.
Files changed (142) hide show
  1. package/mfp-wc-dashboard.js +153 -0
  2. package/mfp-webcomponents.js +573 -0
  3. package/package.json +14 -68
  4. package/.github/workflows/pipeline.yaml +0 -41
  5. package/.storybook/main.ts +0 -34
  6. package/.storybook/preview.ts +0 -29
  7. package/.storybook/tsconfig.json +0 -11
  8. package/AGENTS.md +0 -153
  9. package/CODEOWNERS +0 -6
  10. package/CONTRIBUTING.md +0 -95
  11. package/LICENSE +0 -201
  12. package/LICENSES/Apache-2.0.txt +0 -73
  13. package/README.md +0 -91
  14. package/REUSE.toml +0 -9
  15. package/angular.json +0 -157
  16. package/docs/dashboard.md +0 -358
  17. package/docs/declarative-form.md +0 -178
  18. package/docs/declarative-table-card.md +0 -235
  19. package/docs/declarative-table.md +0 -315
  20. package/eslint.config.js +0 -41
  21. package/projects/ngx/cards/favorites/favorites.component.html +0 -12
  22. package/projects/ngx/cards/favorites/favorites.component.scss +0 -50
  23. package/projects/ngx/cards/favorites/favorites.component.ts +0 -19
  24. package/projects/ngx/cards/public-api.ts +0 -4
  25. package/projects/ngx/cards/service-status/service-status-card.component.html +0 -15
  26. package/projects/ngx/cards/service-status/service-status-card.component.scss +0 -87
  27. package/projects/ngx/cards/service-status/service-status-card.component.ts +0 -36
  28. package/projects/ngx/cards/stories/visited-service-card.stories.ts +0 -149
  29. package/projects/ngx/cards/visited-service-card/visited-service-card.component.html +0 -17
  30. package/projects/ngx/cards/visited-service-card/visited-service-card.component.scss +0 -34
  31. package/projects/ngx/cards/visited-service-card/visited-service-card.component.ts +0 -22
  32. package/projects/ngx/cards/whats-new/whats-new.component.html +0 -10
  33. package/projects/ngx/cards/whats-new/whats-new.component.scss +0 -25
  34. package/projects/ngx/cards/whats-new/whats-new.component.ts +0 -46
  35. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.html +0 -28
  36. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.scss +0 -44
  37. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.spec.ts +0 -85
  38. package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.ts +0 -58
  39. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.html +0 -29
  40. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.scss +0 -63
  41. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.spec.ts +0 -255
  42. package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.ts +0 -75
  43. package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.spec.ts +0 -76
  44. package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.ts +0 -109
  45. package/projects/ngx/declarative-ui/dashboard/card/utils/index.ts +0 -4
  46. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.spec.ts +0 -141
  47. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.ts +0 -44
  48. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.spec.ts +0 -142
  49. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.ts +0 -52
  50. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.spec.ts +0 -107
  51. package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.ts +0 -22
  52. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.html +0 -134
  53. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.scss +0 -88
  54. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.spec.ts +0 -354
  55. package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.ts +0 -238
  56. package/projects/ngx/declarative-ui/dashboard/dashboard/index.ts +0 -1
  57. package/projects/ngx/declarative-ui/dashboard/index.ts +0 -5
  58. package/projects/ngx/declarative-ui/dashboard/models/constants.ts +0 -2
  59. package/projects/ngx/declarative-ui/dashboard/models/dashboard.model.ts +0 -50
  60. package/projects/ngx/declarative-ui/dashboard/models/index.ts +0 -1
  61. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.html +0 -28
  62. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.scss +0 -85
  63. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.spec.ts +0 -104
  64. package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.ts +0 -23
  65. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.html +0 -62
  66. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.scss +0 -12
  67. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.spec.ts +0 -301
  68. package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.ts +0 -166
  69. package/projects/ngx/declarative-ui/form/declarative-form/index.ts +0 -1
  70. package/projects/ngx/declarative-ui/form/index.ts +0 -2
  71. package/projects/ngx/declarative-ui/form/models/form-field-definition.ts +0 -15
  72. package/projects/ngx/declarative-ui/form/models/index.ts +0 -1
  73. package/projects/ngx/declarative-ui/form/utils/set-property-by-path.ts +0 -30
  74. package/projects/ngx/declarative-ui/models/index.ts +0 -2
  75. package/projects/ngx/declarative-ui/models/resource.ts +0 -5
  76. package/projects/ngx/declarative-ui/models/ui-definition.ts +0 -95
  77. package/projects/ngx/declarative-ui/public-api.ts +0 -4
  78. package/projects/ngx/declarative-ui/stories/add-card-dialog.stories.ts +0 -91
  79. package/projects/ngx/declarative-ui/stories/background-lightblue.png +0 -0
  80. package/projects/ngx/declarative-ui/stories/dashboard.cards.ts +0 -107
  81. package/projects/ngx/declarative-ui/stories/dashboard.stories.ts +0 -296
  82. package/projects/ngx/declarative-ui/stories/declarative-form.stories.ts +0 -149
  83. package/projects/ngx/declarative-ui/stories/declarative-table-card.stories.ts +0 -358
  84. package/projects/ngx/declarative-ui/stories/declarative-table.stories.ts +0 -363
  85. package/projects/ngx/declarative-ui/stories/pods-table.config.ts +0 -188
  86. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.html +0 -138
  87. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.scss +0 -21
  88. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.spec.ts +0 -345
  89. package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.ts +0 -61
  90. package/projects/ngx/declarative-ui/table/declarative-table/index.ts +0 -1
  91. package/projects/ngx/declarative-ui/table/index.ts +0 -2
  92. package/projects/ngx/declarative-ui/table/models/index.ts +0 -14
  93. package/projects/ngx/declarative-ui/table/models/table.model.ts +0 -17
  94. package/projects/ngx/declarative-ui/table/utils/cssRules.engine.spec.ts +0 -146
  95. package/projects/ngx/declarative-ui/table/utils/cssRules.engine.ts +0 -69
  96. package/projects/ngx/declarative-ui/table/utils/field-definition.utils.spec.ts +0 -70
  97. package/projects/ngx/declarative-ui/table/utils/field-definition.utils.ts +0 -13
  98. package/projects/ngx/declarative-ui/table/utils/proccess-fields.spec.ts +0 -511
  99. package/projects/ngx/declarative-ui/table/utils/proccess-fields.ts +0 -71
  100. package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.spec.ts +0 -372
  101. package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.ts +0 -98
  102. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-cell.constants.ts +0 -5
  103. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.html +0 -1
  104. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.scss +0 -0
  105. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.spec.ts +0 -119
  106. package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.ts +0 -35
  107. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.html +0 -7
  108. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.scss +0 -0
  109. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.spec.ts +0 -114
  110. package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.ts +0 -19
  111. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.html +0 -7
  112. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.scss +0 -10
  113. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.spec.ts +0 -188
  114. package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.ts +0 -16
  115. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.html +0 -59
  116. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.scss +0 -33
  117. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.spec.ts +0 -316
  118. package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.ts +0 -115
  119. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.html +0 -156
  120. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.scss +0 -123
  121. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.spec.ts +0 -786
  122. package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.ts +0 -286
  123. package/projects/ngx/declarative-ui/table-card/index.ts +0 -2
  124. package/projects/ngx/declarative-ui/table-card/models/configs.ts +0 -46
  125. package/projects/ngx/declarative-ui/tsconfig.lib.json +0 -11
  126. package/projects/ngx/declarative-ui/tsconfig.lib.prod.json +0 -9
  127. package/projects/ngx/declarative-ui/tsconfig.spec.json +0 -9
  128. package/projects/ngx/ng-package.json +0 -8
  129. package/projects/ngx/package.json +0 -22
  130. package/projects/ngx/public-api.ts +0 -2
  131. package/projects/ngx/tsconfig.lib.json +0 -11
  132. package/projects/ngx/tsconfig.lib.prod.json +0 -9
  133. package/projects/webcomponents/main.ts +0 -92
  134. package/projects/webcomponents/tsconfig.app.json +0 -9
  135. package/projects/webcomponents-dashboard/main.ts +0 -15
  136. package/projects/webcomponents-dashboard/tsconfig.app.json +0 -9
  137. package/renovate.json +0 -6
  138. package/scripts/bundle-wc.mjs +0 -79
  139. package/tsconfig.json +0 -37
  140. package/tsconfig.spec.json +0 -8
  141. package/tsconfig.storybook.json +0 -16
  142. package/vitest.config.ts +0 -26
@@ -1,87 +0,0 @@
1
- :host {
2
- display: block;
3
- height: 100%;
4
- }
5
-
6
- .service-status {
7
- display: flex;
8
- flex-direction: column;
9
- height: 100%;
10
- background: var(--sapTile_Background, #fff);
11
- border-radius: var(--_ui5_card_border-radius, 0.5rem);
12
- border: var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));
13
- box-shadow: var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));
14
- overflow: hidden;
15
-
16
- &__title {
17
- padding: 1rem 1rem 0.5rem;
18
- flex-shrink: 0;
19
- }
20
-
21
- &__list {
22
- display: flex;
23
- flex-direction: column;
24
- flex: 1;
25
- overflow-y: auto;
26
- }
27
-
28
- &__item {
29
- display: flex;
30
- align-items: center;
31
- gap: 0.75rem;
32
- padding: 0.5rem 1rem;
33
- border-bottom: 1px solid var(--sapList_BorderColor, #e5e5e5);
34
-
35
- &:last-child {
36
- border-bottom: none;
37
- }
38
- }
39
-
40
- &__icon {
41
- flex-shrink: 0;
42
- color: var(--sapHighlightColor, #0070f2);
43
- }
44
-
45
- &__name {
46
- flex: 1;
47
- font-size: var(--sapFontSize, 0.875rem);
48
- color: var(--sapTextColor, #32363a);
49
- }
50
-
51
- &__status {
52
- display: flex;
53
- align-items: center;
54
- gap: 0.25rem;
55
- flex-shrink: 0;
56
- font-size: 0.75rem;
57
- font-weight: 500;
58
- border-radius: 0.75rem;
59
- padding: 0.125rem 0.5rem;
60
-
61
- &--operational {
62
- color: var(--sapPositiveColor, #256f3a);
63
- background: var(--sapPositiveBackground, #f1fdf6);
64
- }
65
-
66
- &--degraded {
67
- color: var(--sapCriticalColor, #e76500);
68
- background: var(--sapCriticalBackground, #fef7f1);
69
- }
70
-
71
- &--outage {
72
- color: var(--sapNegativeColor, #aa0808);
73
- background: var(--sapNegativeBackground, #fff1f1);
74
- }
75
-
76
- &--maintenance {
77
- color: var(--sapNeutralColor, #5b738b);
78
- background: var(--sapNeutralBackground, #f5f6f7);
79
- }
80
- }
81
-
82
- &__status-icon {
83
- font-size: 0.75rem;
84
- width: 0.875rem;
85
- height: 0.875rem;
86
- }
87
- }
@@ -1,36 +0,0 @@
1
- import { Component, ViewEncapsulation } from '@angular/core';
2
- import { Icon } from '@fundamental-ngx/ui5-webcomponents/icon';
3
- import { Title } from '@fundamental-ngx/ui5-webcomponents/title';
4
-
5
- export type ServiceStatusValue = 'operational' | 'degraded' | 'outage' | 'maintenance';
6
-
7
- export interface ServiceStatusItem {
8
- name: string;
9
- icon: string;
10
- status: ServiceStatusValue;
11
- }
12
-
13
- @Component({
14
- selector: 'mfp-service-status-card',
15
- templateUrl: './service-status-card.component.html',
16
- styleUrls: ['./service-status-card.component.scss'],
17
- encapsulation: ViewEncapsulation.ShadowDom,
18
- imports: [Icon, Title],
19
- })
20
- export class ServiceStatusCard {
21
- readonly services: ServiceStatusItem[] = [
22
- { name: 'API Gateway', icon: 'connected', status: 'operational' },
23
- { name: 'Identity Service', icon: 'customer', status: 'operational' },
24
- { name: 'Database Cluster', icon: 'database', status: 'degraded' },
25
- { name: 'Message Queue', icon: 'email', status: 'operational' },
26
- { name: 'Object Storage', icon: 'storage', status: 'maintenance' },
27
- { name: 'Audit Log', icon: 'log', status: 'outage' },
28
- ];
29
-
30
- readonly statusConfig: Record<ServiceStatusValue, { label: string; icon: string; colorClass: string }> = {
31
- operational: { label: 'Operational', icon: 'status-positive', colorClass: 'status--operational' },
32
- degraded: { label: 'Degraded', icon: 'status-critical', colorClass: 'status--degraded' },
33
- outage: { label: 'Outage', icon: 'status-negative', colorClass: 'status--outage' },
34
- maintenance: { label: 'Maintenance', icon: 'status-inactive', colorClass: 'status--maintenance' },
35
- };
36
- }
@@ -1,149 +0,0 @@
1
- import { VisitedServiceCard } from '../visited-service-card/visited-service-card.component';
2
- import {
3
- CUSTOM_ELEMENTS_SCHEMA,
4
- Component,
5
- EventEmitter,
6
- Input,
7
- Output,
8
- } from '@angular/core';
9
- import { MessageStrip } from '@fundamental-ngx/ui5-webcomponents/message-strip';
10
- import type { Meta, StoryObj } from '@storybook/angular';
11
-
12
- @Component({
13
- selector: 'visited-service-card-story',
14
- template: `
15
- <mfp-visited-service-card
16
- [serviceType]="serviceType"
17
- [serviceName]="serviceName"
18
- [serviceIcon]="serviceIcon"
19
- [serviceDescription]="serviceDescription"
20
- [path]="path"
21
- (click)="onCardClick()"
22
- ></mfp-visited-service-card>
23
- @if (clicked) {
24
- <ui5-message-strip design="Information" style="margin-top: 1rem;">
25
- Card clicked — would navigate to: {{ path }}
26
- </ui5-message-strip>
27
- }
28
- `,
29
- imports: [MessageStrip, VisitedServiceCard],
30
- })
31
- class VisitedServiceCardStory {
32
- @Input() serviceType = '';
33
- @Input() serviceName = '';
34
- @Input() serviceIcon = '';
35
- @Input() serviceDescription = '';
36
- @Input() path = '';
37
- @Output() click = new EventEmitter<string>();
38
- clicked = false;
39
- onCardClick() {
40
- this.clicked = true;
41
- setTimeout(() => (this.clicked = false), 3000);
42
- }
43
- }
44
-
45
- const meta: Meta<VisitedServiceCardStory> = {
46
- title: 'Cards / VisitedServiceCard',
47
- component: VisitedServiceCardStory,
48
- tags: ['autodocs'],
49
- parameters: { layout: 'padded' },
50
- argTypes: {
51
- serviceType: { control: 'text' },
52
- serviceName: { control: 'text' },
53
- serviceIcon: { control: 'text' },
54
- serviceDescription: { control: 'text' },
55
- path: { control: 'text' },
56
- },
57
- };
58
-
59
- export default meta;
60
- type Story = StoryObj<VisitedServiceCardStory>;
61
-
62
- export const HanaCloud: Story = {
63
- args: {
64
- serviceType: 'SAP HANA Cloud',
65
- serviceName: 'olc-hana-db',
66
- serviceIcon: 'database',
67
- serviceDescription: 'My Subaccount 1/Space dev',
68
- path: '/hana/olc-hana-db',
69
- },
70
- };
71
-
72
- export const CloudIdentityService: Story = {
73
- args: {
74
- serviceType: 'Cloud Identity Service',
75
- serviceName: 'Cloud Identity Service',
76
- serviceIcon: 'customer',
77
- serviceDescription: 'My Subaccount 1/Space dev',
78
- path: '/identity/cloud-identity-service',
79
- },
80
- };
81
-
82
- export const HanaCloudTest: Story = {
83
- args: {
84
- serviceType: 'SAP HANA Cloud',
85
- serviceName: 'olc-hana-db-test',
86
- serviceIcon: 'database',
87
- serviceDescription: 'My Subaccount 1/Space dev',
88
- path: '/hana/olc-hana-db-test',
89
- },
90
- };
91
-
92
- export const ApplicationAutoscaler: Story = {
93
- args: {
94
- serviceType: 'Application Autoscaler',
95
- serviceName: 'applicationtest',
96
- serviceIcon: 'accelerated',
97
- serviceDescription: 'My Subaccount 2/Space prod',
98
- path: '/autoscaler/applicationtest',
99
- },
100
- };
101
-
102
- export const CloudIdentityLongPath: Story = {
103
- args: {
104
- serviceType: 'Cloud Identity Service',
105
- serviceName: 'Cloud Identity Service',
106
- serviceIcon: 'customer',
107
- serviceDescription: 'Long text Subaccount 1/Space',
108
- path: '/identity/cloud-identity-service',
109
- },
110
- };
111
-
112
- export const AuditLogService: Story = {
113
- args: {
114
- serviceType: 'Audit Log Service',
115
- serviceName: 'auditlog-name',
116
- serviceIcon: 'log',
117
- serviceDescription: 'My Subaccount 4/Space dev',
118
- path: '/auditlog/auditlog-name',
119
- },
120
- };
121
-
122
- export const AllCards: Story = {
123
- render: () => ({
124
- props: {
125
- clicked: false,
126
- clickedPath: '',
127
- onCardClick(path: string) {
128
- this['clickedPath'] = path;
129
- this['clicked'] = true;
130
- setTimeout(() => (this['clicked'] = false), 3000);
131
- },
132
- },
133
- template: `
134
- <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; padding: 1rem;">
135
- <mfp-visited-service-card serviceType="SAP HANA Cloud" serviceName="olc-hana-db" serviceIcon="database" serviceDescription="My Subaccount 1/Space dev" path="/hana/olc-hana-db" (click)="onCardClick('/hana/olc-hana-db')"></mfp-visited-service-card>
136
- <mfp-visited-service-card serviceType="Cloud Identity Service" serviceName="Cloud Identity Service" serviceIcon="customer" serviceDescription="My Subaccount 1/Space dev" path="/identity/cloud-identity-service" (click)="onCardClick('/identity/cloud-identity-service')"></mfp-visited-service-card>
137
- <mfp-visited-service-card serviceType="SAP HANA Cloud" serviceName="olc-hana-db-test" serviceIcon="database" serviceDescription="My Subaccount 1/Space dev" path="/hana/olc-hana-db-test" (click)="onCardClick('/hana/olc-hana-db-test')"></mfp-visited-service-card>
138
- <mfp-visited-service-card serviceType="Application Autoscaler" serviceName="applicationtest" serviceIcon="accelerated" serviceDescription="My Subaccount 2/Space prod" path="/autoscaler/applicationtest" (click)="onCardClick('/autoscaler/applicationtest')"></mfp-visited-service-card>
139
- <mfp-visited-service-card serviceType="Cloud Identity Service" serviceName="Cloud Identity Service" serviceIcon="customer" serviceDescription="Long text Subaccount 1/Space" path="/identity/cloud-identity-service" (click)="onCardClick('/identity/cloud-identity-service')"></mfp-visited-service-card>
140
- <mfp-visited-service-card serviceType="Audit Log Service" serviceName="auditlog-name" serviceIcon="log" serviceDescription="My Subaccount 4/Space dev" path="/auditlog/auditlog-name" (click)="onCardClick('/auditlog/auditlog-name')"></mfp-visited-service-card>
141
- </div>
142
- @if (clicked) {
143
- <ui5-message-strip design="Information" style="margin-top: 1rem;">
144
- Card clicked — would navigate to: {{ clickedPath }}
145
- </ui5-message-strip>
146
- }
147
- `,
148
- }),
149
- };
@@ -1,17 +0,0 @@
1
- <div class="visited-card-wrapper" (click)="click.emit(path())">
2
- <span class="visited-card__type-badge">{{ serviceType() }}</span>
3
- <ui5-card class="visited-card">
4
- <ui5-card-header
5
- slot="header"
6
- [titleText]="serviceName()"
7
- [subtitleText]="serviceDescription()"
8
- [interactive]="true"
9
- >
10
- <ui5-icon
11
- slot="avatar"
12
- [name]="serviceIcon()"
13
- class="visited-card__icon"
14
- ></ui5-icon>
15
- </ui5-card-header>
16
- </ui5-card>
17
- </div>
@@ -1,34 +0,0 @@
1
- :host {
2
- display: block;
3
- }
4
-
5
- .visited-card-wrapper {
6
- position: relative;
7
- padding-top: 0.625rem;
8
- cursor: pointer;
9
- }
10
-
11
- .visited-card {
12
- width: 100%;
13
- }
14
-
15
- .visited-card__type-badge {
16
- position: absolute;
17
- top: 0;
18
- right: 0.75rem;
19
- display: inline-block;
20
- padding: 0.125rem 0.625rem;
21
- border-radius: 0.75rem;
22
- background-color: #e8f3ff;
23
- color: #0070f2;
24
- font-size: var(--sapFontSmallSize, 0.75rem);
25
- font-weight: 700;
26
- white-space: nowrap;
27
- z-index: 1;
28
- }
29
-
30
- .visited-card__icon {
31
- width: 2.5rem;
32
- height: 2.5rem;
33
- color: var(--sapHighlightColor, #0070f2);
34
- }
@@ -1,22 +0,0 @@
1
- import { Component, ViewEncapsulation, input, output } from '@angular/core';
2
- import { Card } from '@fundamental-ngx/ui5-webcomponents/card';
3
- import { CardHeader } from '@fundamental-ngx/ui5-webcomponents/card-header';
4
- import { Icon } from '@fundamental-ngx/ui5-webcomponents/icon';
5
- import '@ui5/webcomponents-icons/dist/AllIcons.js';
6
-
7
- @Component({
8
- selector: 'mfp-visited-service-card',
9
- templateUrl: './visited-service-card.component.html',
10
- styleUrls: ['./visited-service-card.component.scss'],
11
- encapsulation: ViewEncapsulation.ShadowDom,
12
- imports: [Card, CardHeader, Icon],
13
- })
14
- export class VisitedServiceCard {
15
- serviceType = input.required<string>();
16
- serviceName = input.required<string>();
17
- serviceDescription = input.required<string>();
18
- serviceIcon = input.required<string>();
19
- path = input.required<string>();
20
-
21
- click = output<string>();
22
- }
@@ -1,10 +0,0 @@
1
- <div class="whats-new">
2
- <ui5-title level="H5" class="whats-new__title">What's New</ui5-title>
3
- <ui5-list separators="Inner" class="whats-new__list">
4
- @for (item of headlines; track item.title) {
5
- <ui5-li icon="{{ item.icon }}" description="{{ item.description }}">
6
- {{ item.title }}
7
- </ui5-li>
8
- }
9
- </ui5-list>
10
- </div>
@@ -1,25 +0,0 @@
1
- :host {
2
- display: block;
3
- height: 100%;
4
- }
5
-
6
- .whats-new {
7
- display: flex;
8
- flex-direction: column;
9
- height: 100%;
10
- background: var(--sapTile_Background, #fff);
11
- border-radius: var(--_ui5_card_border-radius, 0.5rem);
12
- border: var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));
13
- box-shadow: var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));
14
- overflow: hidden;
15
-
16
- &__title {
17
- padding: 1rem 1rem 0.5rem;
18
- flex-shrink: 0;
19
- }
20
-
21
- &__list {
22
- flex: 1;
23
- overflow-y: auto;
24
- }
25
- }
@@ -1,46 +0,0 @@
1
- import { Component, ViewEncapsulation } from '@angular/core';
2
- import { List } from '@fundamental-ngx/ui5-webcomponents/list';
3
- import { ListItemStandard } from '@fundamental-ngx/ui5-webcomponents/list-item-standard';
4
- import { Title } from '@fundamental-ngx/ui5-webcomponents/title';
5
-
6
- @Component({
7
- selector: 'mfp-whats-new',
8
- templateUrl: './whats-new.component.html',
9
- styleUrls: ['./whats-new.component.scss'],
10
- encapsulation: ViewEncapsulation.ShadowDom,
11
- imports: [List, ListItemStandard, Title],
12
- })
13
- export class WhatsNew {
14
- readonly headlines = [
15
- {
16
- title: 'Kubernetes 1.32 Released',
17
- description: 'Improved scheduling, new APIs and graduated features.',
18
- icon: 'cloud',
19
- },
20
- {
21
- title: 'Angular 20 Signals Stable',
22
- description: 'Signal-based reactivity is now production-ready.',
23
- icon: 'developer-settings',
24
- },
25
- {
26
- title: 'WebAssembly WASI 2.0 Preview',
27
- description: 'System interface advances bring server-side WASM closer.',
28
- icon: 'technical-object',
29
- },
30
- {
31
- title: 'OpenTelemetry Hits 1.0',
32
- description: 'Unified observability standard lands in enterprise stacks.',
33
- icon: 'monitor-payments',
34
- },
35
- {
36
- title: 'Rust Enters Linux Kernel Mainstream',
37
- description: 'More subsystems accept Rust driver contributions.',
38
- icon: 'settings',
39
- },
40
- {
41
- title: 'TypeScript 5.8 Performance Boost',
42
- description: 'Declaration emit is up to 10x faster in large projects.',
43
- icon: 'accelerated',
44
- },
45
- ];
46
- }
@@ -1,28 +0,0 @@
1
- <ui5-dialog [open]="open()" (ui5BeforeClose)="cancel.emit()">
2
- <div slot="header" class="add-card-dialog__header">
3
- <ui5-title level="H5">Add Card</ui5-title>
4
- </div>
5
- <div class="add-card-dialog">
6
- @if (availableCards().length === 0) {
7
- <p class="add-card-dialog__empty">No cards available.</p>
8
- }
9
- @for (ac of availableCards(); track ac.id) {
10
- @let alreadyAdded = addedCardsIds().has(ac.id);
11
- <div
12
- class="add-card-dialog__item"
13
- [class.add-card-dialog__item--disabled]="alreadyAdded"
14
- >
15
- <ui5-checkbox
16
- [checked]="alreadyAdded || selectedIds().has(ac.id)"
17
- [disabled]="alreadyAdded"
18
- (ui5Change)="toggle(ac.id)"
19
- [text]="ac.label || ac.component"
20
- />
21
- </div>
22
- }
23
- </div>
24
- <div slot="footer" class="add-card-dialog__footer">
25
- <ui5-button design="Emphasized" (click)="confirmAdd()">Add</ui5-button>
26
- <ui5-button design="Transparent" (click)="cancel.emit()">Cancel</ui5-button>
27
- </div>
28
- </ui5-dialog>
@@ -1,44 +0,0 @@
1
- :host {
2
- display: contents;
3
- }
4
-
5
- .add-card-dialog {
6
- margin: -1rem;
7
- min-width: 300px;
8
-
9
- &__header {
10
- display: flex;
11
- align-items: flex-start;
12
- padding: 0.75rem 1rem;
13
- }
14
-
15
- &__item {
16
- display: flex;
17
- align-items: center;
18
- padding: 0.5rem 1rem;
19
- border-bottom: 1px solid var(--sapList_BorderColor, #e5e5e5);
20
-
21
- &:last-child {
22
- border-bottom: none;
23
- }
24
-
25
- &--disabled {
26
- opacity: 0.8;
27
- }
28
- }
29
-
30
- &__empty {
31
- padding: 1rem;
32
- margin: 0;
33
- color: var(--sapContent_LabelColor, #6a6d70);
34
- font-size: 0.875rem;
35
- }
36
- }
37
-
38
- .add-card-dialog__footer {
39
- display: flex;
40
- justify-content: flex-end;
41
- gap: 0.5rem;
42
- padding: 0.5rem 1rem;
43
- margin: 0 -1rem;
44
- }
@@ -1,85 +0,0 @@
1
- import { CardConfig } from '../models';
2
- import { AddCardDialog } from './add-card-dialog.component';
3
- import { ComponentFixture, TestBed } from '@angular/core/testing';
4
-
5
- type Fixture = ComponentFixture<AddCardDialog>;
6
-
7
- function setup(): { fixture: Fixture; component: AddCardDialog } {
8
- const fixture = TestBed.createComponent(AddCardDialog);
9
- const component = fixture.componentInstance;
10
- return { fixture, component };
11
- }
12
-
13
- function root(fixture: Fixture): ShadowRoot | HTMLElement {
14
- return fixture.nativeElement.shadowRoot ?? fixture.nativeElement;
15
- }
16
-
17
- describe('AddCardDialog', () => {
18
- beforeEach(async () => {
19
- await TestBed.configureTestingModule({
20
- imports: [AddCardDialog],
21
- }).compileComponents();
22
- });
23
-
24
- it('renders the empty state when there are no available cards', () => {
25
- const { fixture } = setup();
26
-
27
- fixture.componentRef.setInput('open', true);
28
- fixture.componentRef.setInput('availableCards', []);
29
- fixture.detectChanges();
30
-
31
- expect(root(fixture).textContent).toContain('No cards available.');
32
- });
33
-
34
- it('resets selected cards whenever the dialog is opened', () => {
35
- const { fixture, component } = setup();
36
-
37
- fixture.componentRef.setInput('availableCards', [
38
- { id: 'card-1', component: 'mfp-a' },
39
- ]);
40
- fixture.detectChanges();
41
-
42
- component.toggle('card-1');
43
- expect(component.selectedIds().has('card-1')).toBe(true);
44
-
45
- fixture.componentRef.setInput('open', true);
46
- fixture.detectChanges();
47
-
48
- expect(component.selectedIds().size).toBe(0);
49
- });
50
-
51
- it('emits only selected cards that have not already been added', () => {
52
- const { fixture, component } = setup();
53
- const availableCards: CardConfig[] = [
54
- { id: 'card-1', component: 'mfp-a', label: 'Card A' },
55
- { id: 'card-2', component: 'mfp-b', label: 'Card B' },
56
- ];
57
- const emitted: CardConfig[][] = [];
58
-
59
- component.confirm.subscribe((cards) => emitted.push(cards));
60
- fixture.componentRef.setInput('availableCards', availableCards);
61
- fixture.componentRef.setInput('addedCardsIds', new Set(['card-2']));
62
- fixture.detectChanges();
63
-
64
- component.toggle('card-1');
65
- component.toggle('card-2');
66
- component.confirmAdd();
67
-
68
- expect(emitted).toEqual([[availableCards[0]]]);
69
- });
70
-
71
- it('emits cancel when the cancel button is clicked', () => {
72
- const { fixture, component } = setup();
73
- let emitted = 0;
74
-
75
- component.cancel.subscribe(() => emitted++);
76
- fixture.componentRef.setInput('open', true);
77
- fixture.componentRef.setInput('availableCards', []);
78
- fixture.detectChanges();
79
-
80
- const buttons = root(fixture).querySelectorAll('ui5-button');
81
- buttons[1]?.dispatchEvent(new Event('click'));
82
-
83
- expect(emitted).toBe(1);
84
- });
85
- });
@@ -1,58 +0,0 @@
1
- import { CardConfig } from '../models';
2
- import {
3
- Component,
4
- ViewEncapsulation,
5
- effect,
6
- input,
7
- output,
8
- signal,
9
- } from '@angular/core';
10
- import { Button } from '@fundamental-ngx/ui5-webcomponents/button';
11
- import { CheckBox } from '@fundamental-ngx/ui5-webcomponents/check-box';
12
- import { Dialog } from '@fundamental-ngx/ui5-webcomponents/dialog';
13
- import { Title } from '@fundamental-ngx/ui5-webcomponents/title';
14
-
15
- @Component({
16
- selector: 'mfp-add-card-dialog',
17
- templateUrl: './add-card-dialog.component.html',
18
- styleUrls: ['./add-card-dialog.component.scss'],
19
- encapsulation: ViewEncapsulation.ShadowDom,
20
- imports: [Button, CheckBox, Dialog, Title],
21
- })
22
- export class AddCardDialog {
23
- availableCards = input<CardConfig[]>([]);
24
- addedCardsIds = input<Set<string>>(new Set());
25
- open = input<boolean>(false);
26
-
27
- confirm = output<CardConfig[]>();
28
- cancel = output<void>();
29
-
30
- selectedIds = signal<Set<string>>(new Set());
31
-
32
- constructor() {
33
- effect(() => {
34
- if (this.open()) {
35
- this.selectedIds.set(new Set());
36
- }
37
- });
38
- }
39
-
40
- toggle(id: string): void {
41
- this.selectedIds.update((set) => {
42
- const next = new Set(set);
43
- if (next.has(id)) {
44
- next.delete(id);
45
- } else {
46
- next.add(id);
47
- }
48
- return next;
49
- });
50
- }
51
-
52
- confirmAdd(): void {
53
- const toAdd = this.availableCards().filter(
54
- (ac) => this.selectedIds().has(ac.id) && !this.addedCardsIds().has(ac.id),
55
- );
56
- this.confirm.emit(toAdd);
57
- }
58
- }
@@ -1,29 +0,0 @@
1
- @if (card().component) {
2
- <div class="component-card">
3
- @if (editMode()) {
4
- <div class="remove-wrapper">
5
- <ui5-button
6
- class="card__remove"
7
- design="Default"
8
- icon="decline"
9
- (click)="removeCard.emit()"
10
- />
11
- </div>
12
- }
13
- <div
14
- [style.pointer-events]="editMode() ? 'none' : 'auto'"
15
- class="component-host"
16
- >
17
- <div #elementHost></div>
18
- </div>
19
- </div>
20
- } @else {
21
- <div class="card">
22
- <div
23
- [style.pointer-events]="editMode() ? 'none' : 'auto'"
24
- class="card__body"
25
- >
26
- <ng-content />
27
- </div>
28
- </div>
29
- }