@salesforcedevs/arch-components 1.20.17-alpha6 → 1.20.17-alpha7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/arch-components",
3
- "version": "1.20.17-alpha6",
3
+ "version": "1.20.17-alpha7",
4
4
  "description": "Architecture Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -1,35 +0,0 @@
1
- @import 'tds/reset';
2
-
3
- :host {
4
- font-size: var(--tds-font-size-md);
5
- }
6
-
7
- .coverage-header {
8
- display: flex;
9
- align-items: center;
10
- justify-content: space-between;
11
- }
12
-
13
- .coverage-title {
14
- display: inline-block;
15
- margin-right: var(--tds-spacing-8);
16
- }
17
-
18
- .coverage-header h2 {
19
- font-size: var(--tds-font-size-lg);
20
- }
21
-
22
- .chartContainer {
23
- display: flex;
24
- justify-content: space-evenly;
25
- align-items: center;
26
- height: 350px;
27
- margin-bottom: 80px;
28
- }
29
-
30
- .chartContainer div {
31
- flex: 1;
32
- max-width: 50%;
33
- height: 100%;
34
- text-align: center;
35
- }
@@ -1,15 +0,0 @@
1
- <template>
2
- <div class="coverage-header">
3
- <h2 class="coverage-title">Roadmap Coverage</h2>
4
- </div>
5
- <div class="chartContainer">
6
- <div>
7
- <p>Product Areas</p>
8
- <canvas id="chartCanvas"></canvas>
9
- </div>
10
- <div>
11
- <p>Feature Areas</p>
12
- <canvas id="barCanvas"></canvas>
13
- </div>
14
- </div>
15
- </template>
@@ -1,404 +0,0 @@
1
- import { LightningElement, api, track } from 'lwc';
2
- import { ProductArea, FeatureArea } from './types';
3
- import { RoadmapFeature } from '../roadmap/types'
4
-
5
- export default class coverage extends LightningElement {
6
-
7
- // get the inputs from the config
8
- _portfolio;
9
- _covered;
10
- _selected;
11
-
12
- // hold the coverage data
13
- portfolioData: ProductArea[] = [];
14
- roadmapData: RoadmapFeature[] = [];
15
- totalProductAreas;
16
- totalFeatureAreas;
17
- paCoverageCount: number = 0;
18
- faCoverageCount: number = 0;
19
- paCoveragePct: number = 0;
20
- faCoveragePct: number = 0;
21
-
22
- // used to check if the chartjs script loaded
23
- scriptLoaded = false;
24
-
25
- // holds the chartjs components
26
- donutChart;
27
- barChart;
28
- @track productAreaTitle;
29
- @track featureAreaTitle;
30
-
31
- // chart settings
32
- xlightCloudBlue: string = '#eaf5fe';
33
- lightCloudBlue: string = '#90d0fe';
34
- medCloudBlue: string = '#0d9dda';
35
- inactiveBg: string = '#dbdbdb';
36
- inactiveHover: string = '#d3d3d3';
37
- selectedPA: ProductArea;
38
-
39
- constructor() {
40
- super();
41
- }
42
-
43
- /// this function fires when a component is inserted into the DOM
44
- /// we use this function to collect initial data and set up the page:
45
- /// gets product and feature json data
46
- /// gets roadmap feature data
47
- /// adds the chartjs library
48
- async connectedCallback() {
49
-
50
- }
51
-
52
- setupCharts() {
53
- if (this._covered && this._portfolio) {
54
- try {
55
-
56
- this.portfolioData = [...this._portfolio] as ProductArea[];
57
- this.portfolioData.sort((a, b) => a.name.localeCompare(b.name));
58
- this.roadmapData = [...this._covered] as RoadmapFeature[];
59
-
60
- this.totalProductAreas = this.portfolioData.length;
61
- this.totalFeatureAreas = this.portfolioData.reduce((total, productArea) => {
62
- return total + productArea.feature_areas.length;
63
- }, 0);
64
-
65
- // now update the coverage values in the portfolio data
66
- this.paCoverageCount = this.portfolioData.filter(pa => pa.covered == true).length;
67
- this.paCoveragePct = this.paCoverageCount / this.totalProductAreas * 100;
68
-
69
- // add the chartsjs library to the dom
70
- var script = document.createElement('script');
71
- script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
72
- document.head.appendChild(script);
73
- script.onload = () => {
74
- this.scriptLoaded = true;
75
- this.registerCenterLabelPlugin();
76
- this.initializeProductAreaChart();
77
- this.initializeFeatureAreaChart();
78
- this.updateSelectedProductArea(this.donutChart);
79
- };
80
-
81
- } catch (error) {
82
- console.error("An error occurred getting the portfolio data:", error.message);
83
- }
84
- }
85
- }
86
-
87
- /// set up the donut chart for product areas
88
- initializeProductAreaChart() {
89
-
90
- // Data for the donut chart
91
- const dataDonut = {
92
- labels: this.portfolioData.map(area => area.name),
93
- datasets: [{
94
- data: Array.from({ length: this.totalProductAreas }, () => 100/this.totalProductAreas),
95
- backgroundColor: this.portfolioData.map(area => area.covered ? area.colors.light : this.inactiveBg),
96
- hoverBackgroundColor: this.portfolioData.map(area => area.covered ? area.colors.xlight : this.inactiveHover),
97
- hoverOffset: 10,
98
- cutout: "25%"
99
- }]
100
- };
101
-
102
- // options for donut chart
103
- const optionsDonut = {
104
- responsive: true,
105
- maintainAspectRatio: false,
106
- autoPadding: false,
107
- hover: false,
108
- layout: {
109
- padding: {
110
- bottom: 15
111
- }
112
- },
113
- plugins: {
114
- legend: {
115
- display: true,
116
- position: "left",
117
- onClick: () => {}
118
- },
119
- title: {
120
- display: false,
121
- anchor: 'center',
122
- clamp: true,
123
- align: 'center',
124
- fullSize: true,
125
- font: {
126
- family: "Salesforce Sans",
127
- size: 15,
128
- weight: 'normal'
129
- }
130
- },
131
- tooltip: {
132
- enabled: true,
133
- label: {
134
- display: false
135
- },
136
- callbacks: {
137
- title: function(context) {
138
- return context.label;
139
- },
140
- label: function(context) {
141
- return '';
142
- }
143
- }
144
- }
145
- }
146
- };
147
-
148
- // config for donut
149
- const configDonut = {
150
- type: 'doughnut',
151
- data: dataDonut,
152
- options: optionsDonut
153
- };
154
-
155
- // Create the Donut chart
156
- const chartCanvas = this.template.querySelector("#chartCanvas") as HTMLCanvasElement;
157
- if (chartCanvas) {
158
- this.donutChart = new Chart(chartCanvas, configDonut);
159
- }
160
- }
161
-
162
- // set up the plugin to place the % at the center of the donut
163
- registerCenterLabelPlugin() {
164
- Chart.register({
165
- id: 'center-label',
166
- afterDatasetsDraw: function(chart) {
167
- if (chart.config.type == 'doughnut') {
168
- var text = chart.config.options.plugins.title.text;
169
- const ctx = chart.ctx;
170
- ctx.save();
171
- const x = chart.getDatasetMeta(0).data[0].x;
172
- const y = chart.getDatasetMeta(0).data[0].y;
173
- ctx.textAlign = 'center';
174
- ctx.textBaseline = 'middle';
175
- ctx.font = '18px Salesforce Sans';
176
- ctx.fillText(text, x, y);
177
- }
178
- }
179
- });
180
- }
181
-
182
- // build the datasets for the bar chart when All Product Areas is selected
183
- getFeatureAreaChartForEntirePortfolio() {
184
- return {
185
- labels: this.portfolioData.map(pa => pa.name),
186
- datasets: [{
187
- data: this.portfolioData.map(pa => pa.feature_area_coverage),
188
- backgroundColor: this.portfolioData.map(pa => (pa.covered) ? pa.colors.light : this.inactiveBg)
189
- }]
190
- };
191
- }
192
-
193
- // build the datasets for the bar chart when one Prod Area is selected
194
- getFeatureAreaChartForSelectedProductArea() {
195
-
196
- let dataVal = 100/this.selectedPA.feature_areas.length;
197
- return {
198
- labels: [`${this.selectedPA.feature_areas_covered} of ${this.selectedPA.feature_areas.length}`],
199
- datasets: this.selectedPA.feature_areas.map(fa => ({
200
- data: [dataVal],
201
- label: fa.name,
202
- backgroundColor: (fa.covered) ? this.selectedPA.colors.light : this.inactiveBg,
203
- borderWidth: 2,
204
- borderColor: 'white'
205
- }))
206
- };
207
- }
208
-
209
- // set up the bar chart for feature area coverage
210
- initializeFeatureAreaChart() {
211
-
212
- // options for feature bar
213
- const optionsBar = {
214
- indexAxis: 'y',
215
- hover: false,
216
- scales: {
217
- x: {
218
- display: true,
219
- begingAtZero: true,
220
- min: 0,
221
- max: 100,
222
- stacked: true,
223
- ticks: {
224
- // forces step size to be 50 units
225
- stepSize: 25,
226
- callback: function (value) {
227
- return value + '%'; // Appending '%' to the tick value
228
- }
229
- }
230
- },
231
- y: {
232
- stacked: true,
233
- display: true,
234
- begingAtZero: true,
235
- grouped: false
236
- }
237
- },
238
- plugins: {
239
- legend: {
240
- display: false
241
- },
242
- title: {
243
- display: false,
244
- text: `${this.faCoveragePct.toFixed(0)}% of all feature areas are in this roadmap`,
245
- fullSize: true,
246
- align: 'end',
247
- font: {
248
- family: "Salesforce Sans",
249
- size: 16,
250
- weight: 'normal'
251
- }
252
- }
253
- ,tooltip: {
254
- enabled: true,
255
- label: {
256
- display: false
257
- },
258
- callbacks: {
259
- title: function(context) {
260
- if (context[0].label.includes(' of ')){
261
- return context[0].dataset.label;
262
- } else {
263
- return context.label;
264
- }
265
- },
266
- label: function(context) {
267
- if (context.dataset.label) {
268
- return '';
269
- } else {
270
- return `${context.formattedValue}%`;
271
- }
272
- }
273
- }
274
- }
275
- }
276
- };
277
-
278
- // config for features bar
279
- const configBar = {
280
- type: 'bar',
281
- data: this.getFeatureAreaChartForEntirePortfolio(),
282
- options: optionsBar
283
- };
284
-
285
- const barCanvas = this.template.querySelector("#barCanvas") as HTMLCanvasElement;
286
- if (barCanvas) {
287
- this.featureAreaTitle = `${this.faCoveragePct.toFixed(0)}% of all feature areas are in this roadmap`;
288
- this.barChart = new Chart(barCanvas, configBar);
289
- }
290
-
291
- }
292
-
293
- // handle product area selection change event
294
- updateSelectedProductArea(chart) {
295
-
296
- // reset the Donut chart
297
- if (chart.getActiveElements().length > 0) {
298
- chart.setActiveElements([]);
299
- chart.tooltip.setActiveElements([]);
300
- }
301
-
302
- // now lets mimic a hover based on the selected product area
303
- // first get the selected product area
304
- let selectedIndex = -1;
305
- selectedIndex = chart.config.data.labels.indexOf(this._selected) as number;
306
-
307
- // check if there is a selection
308
- if (selectedIndex != -1) {
309
- // hide the center value
310
- chart.config.options.plugins.title.text = '';
311
-
312
- // now lets set the active settings on the selected prod area
313
- this.selectedPA = this.portfolioData.find(area => area.name === this._selected) as ProductArea;
314
- if (this.selectedPA) {
315
-
316
- // update the non active items
317
- chart.config.data.datasets[0].backgroundColor = this.portfolioData.map(area => area.covered ? area.colors.xlight : this.inactiveBg);
318
- chart.config.data.datasets[0].backgroundColor[selectedIndex] = this.selectedPA.colors.light;
319
- chart.legend.legendItems[selectedIndex].fillStyle = this.selectedPA.colors.light;
320
-
321
- // update the selected offset and tooltip
322
- chart.setActiveElements([
323
- {
324
- datasetIndex: 0,
325
- index: selectedIndex
326
- }
327
- ]);
328
- chart.tooltip.setActiveElements([
329
- {
330
- datasetIndex: 0,
331
- index: selectedIndex
332
- }
333
- ]);
334
- }
335
-
336
- } else {
337
- // show the center value
338
- chart.config.options.plugins.title.text = `${this.paCoveragePct.toFixed(0)}%`;
339
- // update the all the items to active
340
- chart.config.data.datasets[0].backgroundColor = this.portfolioData.map(area => area.covered ? area.colors.light : this.inactiveBg);
341
- }
342
-
343
- // now update the donut chart and the bar chart
344
- chart.update();
345
- this.updateSelectedFeatureArea(this.barChart);
346
- }
347
-
348
- // update the bar chart when product area selection changes
349
- updateSelectedFeatureArea(chart) {
350
-
351
- // reset the chart
352
- if (chart.getActiveElements().length > 0) {
353
- chart.setActiveElements([]);
354
- chart.tooltip.setActiveElements([]);
355
- }
356
-
357
- // check if there is a product area selected
358
- if (this.selectedPA && this._selected != '') {
359
- chart.config.data = this.getFeatureAreaChartForSelectedProductArea();
360
- } else {
361
- chart.config.data = this.getFeatureAreaChartForEntirePortfolio();
362
- }
363
-
364
- // always update the bar
365
- chart.update();
366
-
367
- }
368
-
369
- /// Below is the getters and setters for inputs
370
- @api
371
- set portfolio(value) {
372
- if(this._portfolio !== value && value.length > 0) {
373
- this._portfolio = [...value];
374
- this.setupCharts();
375
- }
376
- }
377
- get portfolio() {
378
- return this._portfolio;
379
- }
380
-
381
- @api
382
- set covered(value) {
383
- if(this._covered !== value && value.length > 0) {
384
- this._covered = [...value];
385
- this.setupCharts();
386
- }
387
- }
388
- get covered() {
389
- return this._covered;
390
- }
391
-
392
- @api
393
- set selected(value) {
394
- if(this._selected !== value) {
395
- this._selected = value;
396
- if (this.scriptLoaded) {
397
- this.updateSelectedProductArea(this.donutChart);
398
- }
399
- }
400
- }
401
- get selected() {
402
- return this._selected;
403
- }
404
- }
@@ -1,22 +0,0 @@
1
- export type ProductArea = {
2
- name: string;
3
- colors: Colors;
4
- covered: boolean;
5
- feature_areas_covered: number;
6
- feature_area_coverage: number;
7
- feature_areas: FeatureArea[];
8
- };
9
-
10
- export type FeatureArea = {
11
- name: string;
12
- covered: boolean;
13
- productArea: string;
14
- activeColor: string;
15
- inactiveColor: string;
16
- features: string[];
17
- }
18
-
19
- export type Colors = {
20
- xlight: string;
21
- light: string;
22
- }
@@ -1,24 +0,0 @@
1
- @import 'tds/reset';
2
-
3
- .section-title {
4
- display: flex;
5
- align-items: center;
6
- }
7
-
8
- .section-content {
9
- display: none;
10
- }
11
-
12
- .is-open .section-content {
13
- padding-top: 0.5rem;
14
- display: block;
15
- }
16
-
17
- .icon {
18
- transform: rotate(-90deg);
19
- transition: transform 300ms;
20
- }
21
-
22
- .is-open .icon {
23
- transform: rotate(0deg);
24
- }
@@ -1,20 +0,0 @@
1
- <template>
2
- <div class={sectionClass}>
3
- <h3 class="section-title">
4
- <tds-button-icon
5
- size="small"
6
- aria-label="Expand/Collapse"
7
- variant="bare"
8
- aria-controls="expand"
9
- aria-expanded={_isOpen}
10
- onclick={handleExpandClick}
11
- >
12
- <tds-icon class="icon" size="small" symbol="switch"></tds-icon>
13
- </tds-button-icon>
14
- <slot name="title"></slot>
15
- </h3>
16
- <div aria-hidden={isClosed} class="section-content" id="expand">
17
- <slot></slot>
18
- </div>
19
- </div>
20
- </template>
@@ -1,37 +0,0 @@
1
- import { html } from 'lit-html';
2
-
3
- export default {
4
- title: 'sa/sa-expandable-section',
5
- parameters: {
6
- modules: ['/modules/sa-expandable-section.js']
7
- }
8
- };
9
-
10
- export const Base = () =>
11
- html`
12
- <sa-expandable-section>
13
- <span slot="title">Section Title</span>
14
- <p>
15
- Aenean eu leo quam. Pellentesque ornare sem lacinia quam
16
- venenatis vestibulum. Fusce dapibus, tellus ac cursus commodo,
17
- tortor mauris condimentum nibh, ut fermentum massa justo sit
18
- amet risus. Lorem ipsum dolor sit amet, consectetur adipiscing
19
- elit. Nullam quis risus eget urna mollis ornare vel eu leo.
20
- Nulla vitae elit libero, a pharetra augue.
21
- </p>
22
- </sa-expandable-section>
23
- `;
24
-
25
- export const Open = () => html`
26
- <sa-expandable-section is-open="false">
27
- <span slot="title">Section Title</span>
28
- <p>
29
- Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis
30
- vestibulum. Fusce dapibus, tellus ac cursus commodo, tortor mauris
31
- condimentum nibh, ut fermentum massa justo sit amet risus. Lorem
32
- ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis risus
33
- eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a
34
- pharetra augue.
35
- </p>
36
- </sa-expandable-section>
37
- `;
@@ -1,24 +0,0 @@
1
- import { LightningElement, api } from 'lwc';
2
-
3
- export default class ExpandableSection extends LightningElement {
4
- @api
5
- get isOpen() {
6
- return this._isOpen;
7
- }
8
- set isOpen(value) {
9
- this._isOpen = value;
10
- }
11
- _isOpen = false;
12
-
13
- handleExpandClick() {
14
- this._isOpen = !this._isOpen;
15
- }
16
-
17
- get sectionClass() {
18
- return `section ${this._isOpen ? 'is-open' : ''}`;
19
- }
20
-
21
- get isClosed() {
22
- return !this._isOpen;
23
- }
24
- }