Skip to content

Commit

Permalink
feat(site-status): add site-status
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroedin committed Mar 28, 2024
1 parent 1d16407 commit 13089d1
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 0 deletions.
11 changes: 11 additions & 0 deletions elements/rh-site-status/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Site Status
Add a description of the component here.

## Usage
Describe how best to use this web component along with best practices.

```html
<rh-site-status>

</rh-site-status>
```
3 changes: 3 additions & 0 deletions elements/rh-site-status/demo/demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
rh-site-status {
/* insert demo styles */
}
4 changes: 4 additions & 0 deletions elements/rh-site-status/demo/rh-site-status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<link rel="stylesheet" href="demo.css">
<script type="module" src="rh-site-status.js"></script>

<rh-site-status></rh-site-status>
1 change: 1 addition & 0 deletions elements/rh-site-status/demo/rh-site-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@rhds/elements/rh-site-status/rh-site-status.js';
17 changes: 17 additions & 0 deletions elements/rh-site-status/docs/rh-site-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% renderOverview %}
<rh-site-status></rh-site-status>
{% endrenderOverview %}

{% band header="Usage" %}{% endband %}

{% renderSlots %}{% endrenderSlots %}

{% renderAttributes %}{% endrenderAttributes %}

{% renderMethods %}{% endrenderMethods %}

{% renderEvents %}{% endrenderEvents %}

{% renderCssCustomProperties %}{% endrenderCssCustomProperties %}

{% renderCssParts %}{% endrenderCssParts %}
10 changes: 10 additions & 0 deletions elements/rh-site-status/rh-site-status.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
:host {
display: inline-flex;
font-size: var(--rh-font-size-body-text-sm, 0.875rem);
padding: var(--rh-space-lg, 16px);
align-items: center;
gap: var(--rh-space-md, 8px);
background: var(--rh-color-surface-dark, #383838);
border-radius: var(--rh-border-radius-default, 3px);
color: var(--rh-color-text-primary-on-dark, #ffffff);
}
108 changes: 108 additions & 0 deletions elements/rh-site-status/rh-site-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { LitElement, type TemplateResult, html, svg } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';

import { Logger } from '@patternfly/pfe-core/controllers/logger.js';

import '../rh-spinner/rh-spinner';

import styles from './rh-site-status.css';

const statusIconsMap: Record<string, TemplateResult> = {
'ok': svg`
<path d="M8 16.5C12.4183 16.5 16 12.9183 16 8.5C16 4.08172 12.4183 0.5 8 0.5C3.58172 0.5 0 4.08172 0 8.5C0 12.9183 3.58172 16.5 8 16.5Z" fill="#63993D"/>
<path d="M6.89999 12.1C6.69999 12.1 6.49999 12 6.39999 11.9L3.49999 9.00001C3.19999 8.70001 3.19999 8.30001 3.49999 8.00001C3.79999 7.70001 4.19999 7.70001 4.49999 8.00001L6.89999 10.4L11.5 5.80001C11.8 5.50001 12.2 5.50001 12.5 5.80001C12.8 6.10001 12.8 6.50001 12.5 6.80001L7.39999 11.9C7.19999 12 6.99999 12.1 6.89999 12.1Z" fill="white"/>
`,
'warn': svg`
<path d="M0 14.6H16L8 0.400024L0 14.6Z" fill="#F5921B"/>
<path d="M8.00005 9.80007C7.60005 9.80007 7.30005 9.50007 7.30005 9.10007V5.90007C7.30005 5.50007 7.60005 5.20007 8.00005 5.20007C8.40005 5.20007 8.70005 5.50007 8.70005 5.90007V9.20007C8.70005 9.50007 8.40005 9.80007 8.00005 9.80007ZM8.20005 12.7001C8.30005 12.7001 8.30005 12.7001 8.40005 12.7001C8.40005 12.7001 8.50005 12.7001 8.50005 12.6001L8.60005 12.5001C8.80005 12.3001 8.80005 12.1001 8.80005 11.9001C8.80005 11.7001 8.70005 11.5001 8.60005 11.3001L8.50005 11.2001L8.40005 11.1001C8.30005 11.1001 8.30005 11.1001 8.20005 11.1001C7.90005 11.0001 7.70005 11.1001 7.50005 11.3001C7.30005 11.5001 7.30005 11.7001 7.30005 11.9001C7.30005 12.1001 7.40005 12.3001 7.50005 12.5001C7.70005 12.7001 7.90005 12.7001 8.10005 12.7001C8.10005 12.7001 8.10005 12.7001 8.20005 12.7001Z" fill="white"/>
`,
'danger': svg`
<path d="M8 16.5C12.4183 16.5 16 12.9183 16 8.5C16 4.08172 12.4183 0.5 8 0.5C3.58172 0.5 0 4.08172 0 8.5C0 12.9183 3.58172 16.5 8 16.5Z" fill="#F4784A"/>
<path d="M8.0001 9.80005C7.6001 9.80005 7.3001 9.50005 7.3001 9.10005V4.50005C7.3001 4.10005 7.6001 3.80005 8.0001 3.80005C8.4001 3.80005 8.7001 4.10005 8.7001 4.50005V9.10005C8.7001 9.50005 8.4001 9.80005 8.0001 9.80005ZM8.2001 12.8C8.3001 12.8 8.3001 12.8 8.4001 12.7C8.5001 12.7 8.5001 12.7 8.5001 12.6C8.6001 12.6 8.6001 12.5 8.6001 12.5C8.8001 12.3 8.9001 12.1 8.9001 11.9C8.9001 11.7 8.8001 11.5 8.6001 11.3L8.5001 11.2L8.4001 11.1C8.3001 11.1 8.3001 11.1 8.2001 11.1C7.9001 11 7.6001 11.1 7.4001 11.3L7.3001 11.4L7.2001 11.5C7.2001 11.6 7.2001 11.6 7.1001 11.7C7.1001 11.8 7.1001 11.8 7.1001 11.9C7.1001 12.1 7.2001 12.3 7.4001 12.5C7.6001 12.7 7.8001 12.8 8.0001 12.8C8.1001 12.8 8.1001 12.8 8.2001 12.8Z" fill="white"/>
`
};

// map statuspage.io's text to our text; at least one of their status
// strings is too long for the space we have
const textMap: Record<string, string> = {
'Partially Degraded Service': 'Partial service',
};

// map statuspage.io's statuses to colorful css keys for icon svg
const statusMap: Record<string, string> = {
'maintenance': 'warn',
'critical': 'danger',
'major': 'warn',
'minor': 'warn',
'none': 'ok',
};

interface Summary {
status: {
description: string;
indicator: string;
};
indicator: string;
statusIconClassName: string;
}

/**
* Site Status
* @slot - Place element content here
*/
@customElement('rh-site-status')
class RhSiteStatus extends LitElement {
static readonly styles = [styles];

#logger = new Logger(this);

#text = 'Loading';

#icon: TemplateResult = html``;

#isLoading = true;

async connectedCallback() {
super.connectedCallback();
await this._getStatus();
}

render() {
return html`
${this.#isLoading ? html`<rh-spinner size="sm"></rh-spinner>` : html`
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
${this.#icon}
</svg>
`}
${this.#text}
`;
}

async _getStatus() {
await fetch('https://status.redhat.com/index.json', {
mode: 'cors',
cache: 'no-cache',
})
.then(response => response.json())
.then((data: Summary) => {
const statusText = data.status.description;
this.#text = textMap[statusText] || statusText.charAt(0).toUpperCase() + statusText.substring(1).toLowerCase();
this.#icon = statusIconsMap[statusMap[data.status.indicator]];
this.#isLoading = false;
this.requestUpdate();
})
.catch( error => {
this.#logger.warn('Error loading site status:', error);
this.#text = 'Error loading status';
this.#icon = statusIconsMap['danger'];
this.#isLoading = false;
this.requestUpdate();
});
}
}

declare global {
interface HTMLElementTagNameMap {
'rh-site-status': RhSiteStatus;
}
}
12 changes: 12 additions & 0 deletions elements/rh-site-status/test/rh-site-status.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { test } from '@playwright/test';
import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js';

const tagName = 'rh-site-status';

test.describe(tagName, () => {
test('snapshot', async ({ page }) => {
const componentPage = new PfeDemoPage(page, tagName);
await componentPage.navigate();
await componentPage.snapshot();
});
});
17 changes: 17 additions & 0 deletions elements/rh-site-status/test/rh-site-status.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect, html } from '@open-wc/testing';
import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js';
import { RhSiteStatus } from '@rhds/elements/rh-site-status/rh-site-status.js';

describe('<rh-site-status>', function() {
describe('simply instantiating', function() {
let element: RhSiteStatus;
it('should upgrade', async function() {
element = await createFixture<RhSiteStatus>(html`<rh-site-status></rh-site-status>`);
const klass = customElements.get('rh-site-status');
expect(element)
.to.be.an.instanceOf(klass)
.and
.to.be.an.instanceOf(RhSiteStatus);
});
})
});

0 comments on commit 13089d1

Please sign in to comment.