',
7 | component: 'cc-addon-option',
8 | };
9 |
10 | const htmlExample = `
11 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed libero risus,
12 | porttitor et turpis sed, mollis ultricies quam. Sed quis fermentum sem, sed dictum sapien.
13 | Donec rutrum ante vel dolor bibendum, eu pretium velit gravida
14 |
15 |
Nullam non nulla convallis, tincidunt nibh at, blandit eros. Cras arcu quam, faucibus eget neque id,
16 | scelerisque ornare neque
17 |
18 | `;
19 |
20 | const optionExample = {
21 | heading: 'My Option',
22 | logo: 'https://assets.clever-cloud.com/logos/elasticsearch-kibana.svg',
23 | };
24 |
25 | const conf = {
26 | component: 'cc-addon-option',
27 | };
28 |
29 | export const defaultStory = makeStory(conf, {
30 | items: [
31 | {
32 | ...optionExample,
33 | innerHTML: htmlExample,
34 | },
35 | ],
36 | });
37 |
38 | export const defaultWithIcon = makeStory(conf, {
39 | items: [
40 | {
41 | ...optionExample,
42 | icon: iconEncryptionAtRest,
43 | logo: null,
44 | innerHTML: htmlExample,
45 | },
46 | ],
47 | });
48 |
49 | export const defaultEnabled = makeStory(conf, {
50 | items: [
51 | {
52 | ...optionExample,
53 | enabled: true,
54 | innerHTML: htmlExample,
55 | },
56 | ],
57 | });
58 |
--------------------------------------------------------------------------------
/src/components/cc-addon-postgresql-options/cc-addon-postgresql-options.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-addon-postgresql-options.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🛠 Addon/',
7 | component: 'cc-addon-postgresql-options',
8 | };
9 |
10 | const conf = {
11 | component: 'cc-addon-postgresql-options',
12 | };
13 |
14 | export const defaultStory = makeStory(conf, {
15 | items: [{ options: [{ name: 'encryption', enabled: false }] }],
16 | });
17 |
18 | export const encryptionEnabled = makeStory(conf, {
19 | items: [{ options: [{ name: 'encryption', enabled: true }] }],
20 | });
21 |
22 | // This component isn't used when there are no options => no story for this case.
23 |
--------------------------------------------------------------------------------
/src/components/cc-addon-redis-options/cc-addon-redis-options.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-addon-redis-options.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🛠 Addon/',
7 | component: 'cc-addon-redis-options',
8 | };
9 |
10 | const conf = {
11 | component: 'cc-addon-redis-options',
12 | };
13 |
14 | export const defaultStory = makeStory(conf, {
15 | items: [{ options: [{ name: 'encryption', enabled: false }] }],
16 | });
17 |
18 | export const encryptionEnabled = makeStory(conf, {
19 | items: [{ options: [{ name: 'encryption', enabled: true }] }],
20 | });
21 |
22 | // This component isn't used when there are no options => no story for this case.
23 |
--------------------------------------------------------------------------------
/src/components/cc-article-card/cc-article-card.types.d.ts:
--------------------------------------------------------------------------------
1 | export type ArticleCardState = ArticleCardStateLoaded | ArticleCardStateLoading;
2 |
3 | export interface ArticleCardStateLoaded extends ArticleCard {
4 | type: 'loaded';
5 | }
6 |
7 | export interface ArticleCardStateLoading {
8 | type: 'loading';
9 | }
10 |
11 | export interface ArticleCard {
12 | banner: string;
13 | date: string;
14 | description: string;
15 | link: string;
16 | title: string;
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/cc-article-list/cc-article-list.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ArticleCard } from '../cc-article-card/cc-article-card.types.js';
2 |
3 | export type ArticleListState = ArticleListStateLoaded | ArticleListStateLoading | ArticleListStateError;
4 |
5 | export interface ArticleListStateLoaded {
6 | type: 'loaded';
7 | articles: ArticleCard[];
8 | }
9 |
10 | export interface ArticleListStateLoading {
11 | type: 'loading';
12 | }
13 |
14 | export interface ArticleListStateError {
15 | type: 'error';
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-badge/cc-badge.types.d.ts:
--------------------------------------------------------------------------------
1 | export type BadgeIntent = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
2 |
3 | export type BadgeWeight = 'strong' | 'dimmed' | 'outlined';
4 |
--------------------------------------------------------------------------------
/src/components/cc-beta/cc-beta.types.d.ts:
--------------------------------------------------------------------------------
1 | export type PositionType = 'top-left' | 'bottom-left' | 'top-right' | 'bottom-right';
2 |
--------------------------------------------------------------------------------
/src/components/cc-block/cc-block.types.d.ts:
--------------------------------------------------------------------------------
1 | export type BlockToggleState = 'off' | 'open' | 'close';
2 |
--------------------------------------------------------------------------------
/src/components/cc-button/cc-button.types.d.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverCloud/clever-components/d26069222d113921ee49ad1fa31e0bfdeedaea02/src/components/cc-button/cc-button.types.d.ts
--------------------------------------------------------------------------------
/src/components/cc-datetime-relative/cc-datetime-relative.types.d.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverCloud/clever-components/d26069222d113921ee49ad1fa31e0bfdeedaea02/src/components/cc-datetime-relative/cc-datetime-relative.types.d.ts
--------------------------------------------------------------------------------
/src/components/cc-doc-card/cc-doc-card.types.d.ts:
--------------------------------------------------------------------------------
1 | export type DocCardState = DocCardStateLoaded | DocCardStateLoading;
2 |
3 | export interface DocCardStateLoaded extends DocCard {
4 | type: 'loaded';
5 | }
6 |
7 | export interface DocCardStateLoading {
8 | type: 'loading';
9 | }
10 |
11 | export interface DocCard {
12 | description: string;
13 | heading: string;
14 | icons: string[];
15 | link: string;
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-doc-list/cc-doc-list.types.d.ts:
--------------------------------------------------------------------------------
1 | import { DocCard } from '../cc-doc-card/cc-doc-card.types.js';
2 |
3 | export type DocListState = DocListStateLoaded | DocListStateLoading | DocListStateError;
4 |
5 | export interface DocListStateLoaded {
6 | type: 'loaded';
7 | docs: DocCard[];
8 | }
9 |
10 | export interface DocListStateLoading {
11 | type: 'loading';
12 | }
13 |
14 | export interface DocListStateError {
15 | type: 'error';
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-elasticsearch-info/cc-elasticsearch-info.types.d.ts:
--------------------------------------------------------------------------------
1 | export type ElasticSearchInfoState =
2 | | ElasticSearchInfoStateLoaded
3 | | ElasticSearchInfoStateLoading
4 | | ElasticSearchInfoStateError;
5 |
6 | export interface ElasticSearchInfoStateLoaded {
7 | type: 'loaded';
8 | links: LinkLoaded[];
9 | }
10 |
11 | export interface ElasticSearchInfoStateLoading {
12 | type: 'loading';
13 | links: LinkLoading[];
14 | }
15 |
16 | export interface ElasticSearchInfoStateError {
17 | type: 'error';
18 | }
19 |
20 | export interface LinkLoaded {
21 | type: LinkType;
22 | href: string;
23 | }
24 |
25 | export interface LinkLoading {
26 | type: LinkType;
27 | href?: null;
28 | }
29 |
30 | export type LinkType = 'elasticsearch' | 'kibana' | 'apm';
31 |
--------------------------------------------------------------------------------
/src/components/cc-email-list/cc-email-list.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when an email address addition is requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcEmailAddEvent extends CcEvent {
8 | static TYPE = 'cc-email-add';
9 |
10 | /**
11 | * @param {string} detail
12 | */
13 | constructor(detail) {
14 | super(CcEmailAddEvent.TYPE, detail);
15 | }
16 | }
17 |
18 | /**
19 | * Dispatched when an email address deletion is requested.
20 | * @extends {CcEvent}
21 | */
22 | export class CcEmailDeleteEvent extends CcEvent {
23 | static TYPE = 'cc-email-delete';
24 |
25 | /**
26 | * @param {string} detail
27 | */
28 | constructor(detail) {
29 | super(CcEmailDeleteEvent.TYPE, detail);
30 | }
31 | }
32 |
33 | /**
34 | * Dispatched when a primary email address change is requested.
35 | * @extends {CcEvent}
36 | */
37 | export class CcEmailMarkAsPrimaryEvent extends CcEvent {
38 | static TYPE = 'cc-email-mark-as-primary';
39 |
40 | /**
41 | * @param {string} detail
42 | */
43 | constructor(detail) {
44 | super(CcEmailMarkAsPrimaryEvent.TYPE, detail);
45 | }
46 | }
47 |
48 | /**
49 | * Dispatched when a confirmation email send is requested.
50 | * @extends {CcEvent}
51 | */
52 | export class CcEmailSendConfirmationEvent extends CcEvent {
53 | static TYPE = 'cc-email-send-confirmation';
54 |
55 | /**
56 | * @param {string} detail
57 | */
58 | constructor(detail) {
59 | super(CcEmailSendConfirmationEvent.TYPE, detail);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/components/cc-email-list/cc-email-list.types.d.ts:
--------------------------------------------------------------------------------
1 | //# region state
2 | interface EmailListStateLoading {
3 | type: 'loading';
4 | }
5 |
6 | interface EmailListStateError {
7 | type: 'error';
8 | }
9 |
10 | interface EmailListStateLoaded {
11 | type: 'loaded';
12 | emailList: EmailList;
13 | }
14 |
15 | export type EmailListState = EmailListStateLoading | EmailListStateError | EmailListStateLoaded;
16 | //#endregion
17 |
18 | //#region data model
19 | interface EmailList {
20 | primaryAddress: PrimaryAddressState;
21 | secondaryAddresses: SecondaryAddressState[];
22 | }
23 |
24 | export interface PrimaryAddressState extends EmailAddress {
25 | type: 'idle' | 'sending-confirmation-email';
26 | }
27 |
28 | export interface SecondaryAddressState extends EmailAddress {
29 | type: 'idle' | 'marking-as-primary' | 'deleting';
30 | }
31 |
32 | interface EmailAddress {
33 | address: string;
34 | verified: boolean;
35 | }
36 | //#endregion
37 |
38 | export interface AddEmailFormState {
39 | type: 'idle' | 'adding';
40 | errors?: {
41 | email: AddEmailError;
42 | };
43 | }
44 |
45 | export type AddEmailError = 'invalid' | 'already-defined' | 'used';
46 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-create/cc-env-var-create.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when an env var creation is requested.
5 | * @extends {CcEvent<{name: string, value: string}>}
6 | */
7 | export class CcEnvVarCreateEvent extends CcEvent {
8 | static TYPE = 'cc-env-var-create';
9 |
10 | /**
11 | * @param {{name: string, value: string}} detail
12 | */
13 | constructor(detail) {
14 | super(CcEnvVarCreateEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-create/cc-env-var-create.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-env-var-create.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🛠 Environment variables/',
7 | component: 'cc-env-var-create',
8 | };
9 |
10 | const conf = {
11 | component: 'cc-env-var-create',
12 | };
13 |
14 | export const defaultStory = makeStory(conf, {
15 | items: [{}],
16 | });
17 |
18 | export const validationWithExistingNames = makeStory(conf, {
19 | docs: 'In this example `FOO` and `BAR` are already defined and cannot be used as a variable name again.',
20 | items: [{ variablesNames: ['FOO', 'BAR'] }],
21 | });
22 |
23 | export const validationWithStrictMode = makeStory(conf, {
24 | items: [{ validationMode: 'strict' }],
25 | });
26 |
27 | export const disabled = makeStory(conf, {
28 | items: [{ disabled: true }],
29 | });
30 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-form/cc-env-var-form.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('../common.types.js').EnvVar} EnvVar
5 | */
6 |
7 | /**
8 | * Dispatched when the env var form is submitted.
9 | * @extends {CcEvent>}
10 | */
11 | export class CcEnvVarFormSubmitEvent extends CcEvent {
12 | static TYPE = 'cc-env-var-form-submit';
13 |
14 | /**
15 | * @param {Array} detail
16 | */
17 | constructor(detail) {
18 | super(CcEnvVarFormSubmitEvent.TYPE, detail);
19 | }
20 | }
21 |
22 | /**
23 | * Dispatched when env changes.
24 | * @extends {CcEvent>}
25 | */
26 | export class CcEnvChangeEvent extends CcEvent {
27 | static TYPE = 'cc-env-change';
28 |
29 | /**
30 | * @param {Array} detail
31 | */
32 | constructor(detail) {
33 | super(CcEnvChangeEvent.TYPE, detail);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-form/cc-env-var-form.types.d.ts:
--------------------------------------------------------------------------------
1 | import { EnvVar, EnvVarValidationMode } from '../common.types.js';
2 |
3 | export type EnvVarFormState =
4 | | EnvVarFormStateLoading
5 | | EnvVarFormStateLoaded
6 | | EnvVarFormStateSaving
7 | | EnvVarFormStateError;
8 |
9 | export interface EnvVarFormStateLoading {
10 | type: 'loading';
11 | }
12 |
13 | export interface EnvVarFormStateLoaded {
14 | type: 'loaded';
15 | variables: Array;
16 | validationMode: EnvVarValidationMode;
17 | }
18 |
19 | export interface EnvVarFormStateSaving {
20 | type: 'saving';
21 | variables: Array;
22 | validationMode: EnvVarValidationMode;
23 | }
24 |
25 | export interface EnvVarFormStateError {
26 | type: 'error';
27 | }
28 |
29 | type EnvVarFormContextType = 'env-var' | 'env-var-simple' | 'env-var-addon' | 'exposed-config' | 'config-provider';
30 |
31 | export type EnvVarFormMode = 'SIMPLE' | 'EXPERT' | 'JSON';
32 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-input/cc-env-var-input.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-env-var-input.types.js').EnvVarName} EnvVarName
5 | */
6 |
7 | /**
8 | * Dispatched when an env var value changes.
9 | * @extends {CcEvent<{name: string, value: string}>}
10 | */
11 | export class CcEnvVarChangeEvent extends CcEvent {
12 | static TYPE = 'cc-env-var-change';
13 |
14 | /**
15 | * @param {{name: string, value: string}} detail
16 | */
17 | constructor(detail) {
18 | super(CcEnvVarChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
22 | /**
23 | * Dispatched when an env var deletion is requested.
24 | * @extends {CcEvent}
25 | */
26 | export class CcEnvVarDeleteEvent extends CcEvent {
27 | static TYPE = 'cc-env-var-delete';
28 |
29 | /**
30 | * @param {EnvVarName} detail
31 | */
32 | constructor(detail) {
33 | super(CcEnvVarDeleteEvent.TYPE, detail);
34 | }
35 | }
36 |
37 | /**
38 | * Dispatched when an env var restoration is requested.
39 | * @extends {CcEvent}
40 | */
41 | export class CcEnvVarKeepEvent extends CcEvent {
42 | static TYPE = 'cc-env-var-keep';
43 |
44 | /**
45 | * @param {EnvVarName} detail
46 | */
47 | constructor(detail) {
48 | super(CcEnvVarKeepEvent.TYPE, detail);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-input/cc-env-var-input.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface EnvVarName {
2 | name: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/cc-env-var-linked-services/cc-env-var-linked-services.types.d.ts:
--------------------------------------------------------------------------------
1 | import { EnvVar } from '../common.types.js';
2 |
3 | export type EnvVarLinkedServicesState =
4 | | EnvVarLinkedServicesStateLoading
5 | | EnvVarLinkedServicesStateLoaded
6 | | EnvVarLinkedServicesStateError;
7 |
8 | interface EnvVarLinkedServicesStateLoading {
9 | type: 'loading';
10 | }
11 |
12 | interface EnvVarLinkedServicesStateLoaded {
13 | type: 'loaded';
14 | servicesStates: Array;
15 | }
16 |
17 | interface EnvVarLinkedServicesStateError {
18 | type: 'error';
19 | }
20 |
21 | type EnvVarLinkedServicesType = 'addon' | 'app';
22 |
23 | export type LinkedServiceState = LinkedServiceStateLoading | LinkedServiceStateLoaded | LinkedServiceStateError;
24 |
25 | interface LinkedServiceStateLoading {
26 | type: 'loading';
27 | name: string;
28 | }
29 |
30 | interface LinkedServiceStateLoaded {
31 | type: 'loaded';
32 | name: string;
33 | variables: Array;
34 | }
35 |
36 | interface LinkedServiceStateError {
37 | type: 'error';
38 | name: string;
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/cc-grafana-info/cc-grafana-info.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatch when grafana activation or deactivation is requested.
5 | * @extends {CcEvent<{isEnabled: boolean}>}
6 | */
7 | export class CcGrafanaToggleEvent extends CcEvent {
8 | static TYPE = 'cc-grafana-toggle';
9 |
10 | /**
11 | * @param {{isEnabled: boolean}} detail
12 | */
13 | constructor(detail) {
14 | super(CcGrafanaToggleEvent.TYPE, detail);
15 | }
16 | }
17 |
18 | /**
19 | * Dispatch when grafana reset is requested.
20 | * @extends {CcEvent}
21 | */
22 | export class CcGrafanaResetEvent extends CcEvent {
23 | static TYPE = 'cc-grafana-reset';
24 |
25 | constructor() {
26 | super(CcGrafanaResetEvent.TYPE);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/cc-grafana-info/cc-grafana-info.types.d.ts:
--------------------------------------------------------------------------------
1 | export type GrafanaInfoState = GrafanaInfoStateLoading | GrafanaInfoStateLoadingError | GrafanaInfoStateLoaded;
2 |
3 | export interface GrafanaInfoStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | export interface GrafanaInfoStateLoadingError {
8 | type: 'error';
9 | }
10 |
11 | export interface GrafanaInfoStateLoaded {
12 | type: 'loaded';
13 | info: GrafanaInfo;
14 | }
15 |
16 | export type GrafanaInfo = GrafanaInfoEnabled | GrafanaInfoDisabled;
17 |
18 | export interface GrafanaInfoEnabled {
19 | status: 'enabled';
20 | link?: string;
21 | action?: 'disabling' | 'resetting' | null;
22 | }
23 |
24 | export interface GrafanaInfoDisabled {
25 | status: 'disabled';
26 | action?: 'enabling' | null;
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/cc-header-addon/cc-header-addon.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Addon, Zone } from '../common.types.js';
2 |
3 | export type HeaderAddonState =
4 | | HeaderAddonStateLoaded
5 | | HeaderAddonStateLoadedWithVersion
6 | | HeaderAddonStateLoading
7 | | HeaderAddonStateError;
8 |
9 | export interface HeaderAddonStateLoaded extends Addon {
10 | type: 'loaded';
11 | hasVersion: false;
12 | zone: Zone;
13 | }
14 |
15 | export interface HeaderAddonStateLoadedWithVersion extends Addon {
16 | type: 'loaded';
17 | hasVersion: true;
18 | version: string;
19 | zone: Zone;
20 | }
21 |
22 | export interface HeaderAddonStateLoading {
23 | type: 'loading';
24 | hasVersion: boolean;
25 | }
26 |
27 | export interface HeaderAddonStateError {
28 | type: 'error';
29 | hasVersion: boolean;
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/cc-header-app/cc-header-app.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when a deployment cancellation is requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcDeploymentCancelEvent extends CcEvent {
8 | static TYPE = 'cc-deployment-cancel';
9 |
10 | constructor() {
11 | super(CcDeploymentCancelEvent.TYPE);
12 | }
13 | }
14 |
15 | /**
16 | * Dispatch when an application restart is requested.
17 | * @extends {CcEvent<'normal'|'rebuild'|'last-commit'>}
18 | */
19 | export class CcApplicationRestartEvent extends CcEvent {
20 | static TYPE = 'cc-application-restart';
21 |
22 | /**
23 | * @param {'normal'|'rebuild'|'last-commit'} [detail='normal']
24 | */
25 | constructor(detail) {
26 | super(CcApplicationRestartEvent.TYPE, detail ?? 'normal');
27 | }
28 | }
29 |
30 | /**
31 | * Dispatch when an application start is requested.
32 | * @extends {CcEvent<'normal'|'rebuild'|'last-commit'>}
33 | */
34 | export class CcApplicationStartEvent extends CcEvent {
35 | static TYPE = 'cc-application-start';
36 |
37 | /**
38 | * @param {'normal'|'rebuild'|'last-commit'} [detail='normal']
39 | */
40 | constructor(detail) {
41 | super(CcApplicationStartEvent.TYPE, detail ?? 'normal');
42 | }
43 | }
44 |
45 | /**
46 | * Dispatch when an application stop is requested.
47 | * @extends {CcEvent}
48 | */
49 | export class CcApplicationStopEvent extends CcEvent {
50 | static TYPE = 'cc-application-stop';
51 |
52 | constructor() {
53 | super(CcApplicationStopEvent.TYPE);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/cc-header-app/cc-header-app.types.d.ts:
--------------------------------------------------------------------------------
1 | import { App, AppStatus, Zone } from '../common.types.js';
2 |
3 | export type HeaderAppState = HeaderAppStateLoaded | HeaderAppStateLoading | HeaderAppStateError;
4 |
5 | export interface HeaderAppStateLoaded extends App {
6 | type: 'loaded';
7 | status: AppStatus;
8 | runningCommit?: string | null;
9 | startingCommit?: string | null;
10 | zone: Zone;
11 | }
12 |
13 | export interface HeaderAppStateLoading {
14 | type: 'loading';
15 | }
16 |
17 | export interface HeaderAppStateError {
18 | type: 'error';
19 | }
20 |
21 | export type LastUserAction = 'start' | 'restart' | 'cancel' | 'stop';
22 |
--------------------------------------------------------------------------------
/src/components/cc-header-orga/cc-header-orga.types.d.ts:
--------------------------------------------------------------------------------
1 | export type HeaderOrgaState = HeaderOrgaStateLoaded | HeaderOrgaStateLoading | HeaderOrgaStateError;
2 |
3 | export interface HeaderOrgaStateLoaded {
4 | type: 'loaded';
5 | name: string;
6 | avatar?: string;
7 | cleverEnterprise?: boolean;
8 | emergencyNumber?: string;
9 | }
10 |
11 | export interface HeaderOrgaStateLoading {
12 | type: 'loading';
13 | }
14 |
15 | export interface HeaderOrgaStateError {
16 | type: 'error';
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/cc-heptapod-info/cc-heptapod-info.types.d.ts:
--------------------------------------------------------------------------------
1 | export type HeptapodInfoState =
2 | | HeptapodInfoStateLoaded
3 | | HeptapodInfoStateLoading
4 | | HeptapodInfoStateError
5 | | HeptapodInfoStateNotUsed;
6 |
7 | export interface HeptapodInfoStateLoaded {
8 | type: 'loaded';
9 | statistics: Statistics;
10 | }
11 |
12 | export interface HeptapodInfoStateLoading {
13 | type: 'loading';
14 | }
15 |
16 | export interface HeptapodInfoStateError {
17 | type: 'error';
18 | }
19 |
20 | export interface HeptapodInfoStateNotUsed {
21 | type: 'not-used';
22 | }
23 |
24 | export interface Statistics {
25 | privateActiveUsers: number;
26 | publicActiveUsers: number;
27 | storage: number;
28 | price: number;
29 | }
30 |
--------------------------------------------------------------------------------
/src/components/cc-html-frame/cc-html-frame.types.d.ts:
--------------------------------------------------------------------------------
1 | export type IframeSandbox =
2 | | 'allow-forms'
3 | | 'allow-modals'
4 | | 'allow-pointer-lock'
5 | | 'allow-popups'
6 | | 'allow-popups-to-escape-sandbox'
7 | | 'allow-same-origin'
8 | | 'allow-scripts'
9 | | 'allow-top-navigation';
10 |
--------------------------------------------------------------------------------
/src/components/cc-icon/cc-icon.types.d.ts:
--------------------------------------------------------------------------------
1 | export type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
2 |
--------------------------------------------------------------------------------
/src/components/cc-input-date/cc-input-date.types.d.ts:
--------------------------------------------------------------------------------
1 | export type InputDateValueState = InputDateValueStateEmpty | InputDateValueStateNaD | InputDateValueStateValid;
2 |
3 | export interface InputDateValueStateEmpty {
4 | type: 'empty';
5 | }
6 |
7 | export interface InputDateValueStateNaD {
8 | type: 'NaD';
9 | value: string;
10 | }
11 |
12 | export interface InputDateValueStateValid {
13 | type: 'valid';
14 | value: string;
15 | date: Date;
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-input-text/cc-input-text.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when tags have changed.
5 | * @extends {CcEvent>}
6 | */
7 | export class CcTagsChangeEvent extends CcEvent {
8 | static TYPE = 'cc-tags-change';
9 |
10 | /**
11 | * @param {Array} detail
12 | */
13 | constructor(detail) {
14 | super(CcTagsChangeEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-invoice-list/cc-invoice-list.smart.js:
--------------------------------------------------------------------------------
1 | import { fetchAllInvoices } from '../../lib/api-helpers.js';
2 | import { defineSmartComponent } from '../../lib/smart/define-smart-component.js';
3 | import '../cc-smart-container/cc-smart-container.js';
4 | import './cc-invoice-list.js';
5 |
6 | /**
7 | * @typedef {import('./cc-invoice-list.js').CcInvoiceList} CcInvoiceList
8 | * @typedef {import('../common.types.js').Invoice} Invoice
9 | * @typedef {import('../../lib/send-to-api.types.js').ApiConfig} ApiConfig
10 | * @typedef {import('../../lib/smart/smart-component.types.js').OnContextUpdateArgs} OnContextUpdateArgs
11 | */
12 |
13 | defineSmartComponent({
14 | selector: 'cc-invoice-list',
15 | params: {
16 | apiConfig: { type: Object },
17 | ownerId: { type: String },
18 | },
19 | /**
20 | * @param {OnContextUpdateArgs} args
21 | */
22 | onContextUpdate({ context, updateComponent, signal }) {
23 | updateComponent('state', { type: 'loading' });
24 |
25 | const { apiConfig, ownerId } = context;
26 |
27 | fetchAllInvoices({ apiConfig, ownerId, signal })
28 | .then(
29 | /** @param {Invoice[]} invoices */
30 | (invoices) => {
31 | updateComponent('state', { type: 'loaded', invoices });
32 | },
33 | )
34 | .catch((error) => {
35 | console.error(error);
36 | updateComponent('state', { type: 'error' });
37 | });
38 | },
39 | });
40 |
--------------------------------------------------------------------------------
/src/components/cc-invoice-list/cc-invoice-list.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Invoice } from '../common.types.js';
2 |
3 | export type InvoiceListState = InvoiceListStateLoading | InvoiceListStateError | InvoiceListStateLoaded;
4 |
5 | export interface InvoiceListStateLoading {
6 | type: 'loading';
7 | }
8 |
9 | export interface InvoiceListStateError {
10 | type: 'error';
11 | }
12 |
13 | export interface InvoiceListStateLoaded {
14 | type: 'loaded';
15 | invoices: Array;
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-invoice-table/cc-invoice-table.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Invoice } from '../common.types.js';
2 |
3 | export type InvoiceTableState = InvoiceTableStateLoaded | InvoiceTableStateLoading;
4 |
5 | export interface InvoiceTableStateLoaded {
6 | type: 'loaded';
7 | invoices: Invoice[];
8 | }
9 |
10 | export interface InvoiceTableStateLoading {
11 | type: 'loading';
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/cc-invoice/cc-invoice.types.d.ts:
--------------------------------------------------------------------------------
1 | export type InvoiceState = InvoiceStateLoading | InvoiceStateError | InvoiceStateLoaded;
2 |
3 | interface InvoiceStateLoading {
4 | type: 'loading';
5 | number?: string;
6 | }
7 |
8 | interface InvoiceStateError {
9 | type: 'error';
10 | number: string;
11 | }
12 |
13 | interface InvoiceStateLoaded {
14 | type: 'loaded';
15 | number: string;
16 | downloadUrl: string;
17 | emissionDate: string;
18 | amount: number;
19 | currency: string; // ISO 4217 currency code
20 | invoiceHtml: string;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/cc-jenkins-info/cc-jenkins-info.types.d.ts:
--------------------------------------------------------------------------------
1 | export type JenkinsInfoState = JenkinsInfoStateLoading | JenkinsInfoStateError | JenkinsInfoStateLoaded;
2 |
3 | interface JenkinsInfoStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | interface JenkinsInfoStateError {
8 | type: 'error';
9 | }
10 |
11 | interface JenkinsInfoStateLoaded {
12 | type: 'loaded';
13 | jenkinsLink: string;
14 | jenkinsManageLink: string;
15 | versions: JenkinsInfoVersions;
16 | }
17 |
18 | interface JenkinsInfoVersions {
19 | current: string;
20 | available: string;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/cc-kv-explorer/cc-kv-explorer.smart.md:
--------------------------------------------------------------------------------
1 | ---
2 | kind: '🚧 Beta/🛠 Kv Explorer/'
3 | title: '💡 Smart'
4 | ---
5 | # 💡 Smart ``
6 |
7 | ## ℹ️ Details
8 |
9 |
14 |
15 | ## ⚙️ Params
16 |
17 | | Name | Type | Details | Default |
18 | |---------------|---------------|-------------------------------|---------|
19 | | `kvApiConfig` | `KvApiConfig` | Object with API configuration | |
20 |
21 |
22 | ```typescript
23 |
24 | interface KvApiConfig {
25 | url: string;
26 | backendUrl: string;
27 | }
28 | ```
29 |
30 | ## 🌐 API endpoints
31 |
32 | TBD!
33 |
34 | ## ⬇️️ Examples
35 |
36 | ```html
37 |
43 |
44 |
45 | ```
46 |
--------------------------------------------------------------------------------
/src/components/cc-kv-list-input/cc-kv-list-input.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-kv-list-input.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🚧 Beta/🛠 Kv Explorer/',
7 | component: 'cc-kv-list-input-beta',
8 | };
9 |
10 | /**
11 | * @typedef {import('./cc-kv-list-input.js').CcKvListInput} CcKvListInput
12 | */
13 |
14 | const conf = {
15 | component: 'cc-kv-list-input-beta',
16 | beta: true,
17 | };
18 |
19 | export const defaultStory = makeStory(conf, {
20 | /** @type {Array>} */
21 | items: [
22 | {
23 | value: ['first value', 'second value', 'third value', 'fourth value'],
24 | },
25 | ],
26 | });
27 |
28 | export const withEmptyValue = makeStory(conf, {
29 | /** @type {Array>} */
30 | items: [
31 | {
32 | value: [],
33 | },
34 | ],
35 | });
36 |
37 | export const disabled = makeStory(conf, {
38 | /** @type {Array>} */
39 | items: [
40 | {
41 | value: ['first value', 'second value', 'third value', 'fourth value'],
42 | disabled: true,
43 | },
44 | ],
45 | });
46 |
47 | export const readonly = makeStory(conf, {
48 | /** @type {Array>} */
49 | items: [
50 | {
51 | value: ['first value', 'second value', 'third value', 'fourth value'],
52 | readonly: true,
53 | },
54 | ],
55 | });
56 |
--------------------------------------------------------------------------------
/src/components/cc-kv-set-explorer/cc-kv-set-explorer.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when more KV set elements loading is requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcKvSetLoadMoreEvent extends CcEvent {
8 | static TYPE = 'cc-kv-set-load-more';
9 |
10 | constructor() {
11 | super(CcKvSetLoadMoreEvent.TYPE);
12 | }
13 | }
14 |
15 | /**
16 | * Dispatched when a KV set element deletion is requested.
17 | * @extends {CcEvent}
18 | */
19 | export class CcKvSetElementDeleteEvent extends CcEvent {
20 | static TYPE = 'cc-kv-set-element-delete';
21 |
22 | /**
23 | * @param {string} detail
24 | */
25 | constructor(detail) {
26 | super(CcKvSetElementDeleteEvent.TYPE, detail);
27 | }
28 | }
29 |
30 | /**
31 | * Dispatched when KV set elements filter changes.
32 | * @extends {CcEvent}
33 | */
34 | export class CcKvSetFilterChangeEvent extends CcEvent {
35 | static TYPE = 'cc-kv-set-filter-change';
36 |
37 | /**
38 | * @param {string} detail
39 | */
40 | constructor(detail) {
41 | super(CcKvSetFilterChangeEvent.TYPE, detail);
42 | }
43 | }
44 |
45 | /**
46 | * Dispatched when a KV set element creation is requested.
47 | * @extends {CcEvent}
48 | */
49 | export class CcKvSetElementAddEvent extends CcEvent {
50 | static TYPE = 'cc-kv-set-element-add';
51 |
52 | /**
53 | * @param {string} detail
54 | */
55 | constructor(detail) {
56 | super(CcKvSetElementAddEvent.TYPE, detail);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/cc-kv-set-explorer/cc-kv-set-explorer.types.d.ts:
--------------------------------------------------------------------------------
1 | export type CcKvSetExplorerState =
2 | | CcKvSetExplorerStateLoading
3 | | CcKvSetExplorerStateLoaded
4 | | CcKvSetExplorerStateLoadingMore
5 | | CcKvSetExplorerStateFiltering;
6 |
7 | export interface CcKvSetExplorerStateLoading {
8 | type: 'loading';
9 | }
10 |
11 | export interface CcKvSetExplorerStateLoaded {
12 | type: 'loaded';
13 | elements: Array;
14 | addForm: CcKvSetExplorerAddFormState;
15 | }
16 |
17 | export interface CcKvSetExplorerStateLoadingMore {
18 | type: 'loading-more';
19 | elements: Array;
20 | addForm: CcKvSetExplorerAddFormState;
21 | }
22 |
23 | export interface CcKvSetExplorerStateFiltering {
24 | type: 'filtering';
25 | elements: Array;
26 | addForm: CcKvSetExplorerAddFormState;
27 | }
28 |
29 | export type CcKvSetElementState = CcKvSetElementStateIdle | CcKvSetElementStateDeleting | CcKvSetElementStateEditing;
30 |
31 | export interface CcKvSetElementStateIdle extends CcKvSetElement {
32 | type: 'idle';
33 | }
34 |
35 | export interface CcKvSetElementStateDeleting extends CcKvSetElement {
36 | type: 'deleting';
37 | }
38 |
39 | export interface CcKvSetElementStateEditing extends CcKvSetElement {
40 | type: 'editing';
41 | }
42 |
43 | export interface CcKvSetElement {
44 | value: string;
45 | }
46 |
47 | // - add form
48 |
49 | export type CcKvSetExplorerAddFormState = CcKvSetExplorerAddFormStateIdle | CcKvSetExplorerAddFormStateAdding;
50 |
51 | export interface CcKvSetExplorerAddFormStateIdle {
52 | type: 'idle';
53 | }
54 |
55 | export interface CcKvSetExplorerAddFormStateAdding {
56 | type: 'adding';
57 | }
58 |
--------------------------------------------------------------------------------
/src/components/cc-kv-string-editor/cc-kv-string-editor.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when a KV string key modification is requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcKvStringValueUpdateEvent extends CcEvent {
8 | static TYPE = 'cc-kv-string-value-update';
9 |
10 | /**
11 | * @param {string} detail
12 | */
13 | constructor(detail) {
14 | super(CcKvStringValueUpdateEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-kv-string-editor/cc-kv-string-editor.types.d.ts:
--------------------------------------------------------------------------------
1 | export type CcKvKeyStringEditorState =
2 | | CcKvKeyStringEditorStateLoading
3 | | CcKvKeyStringEditorStateIdle
4 | | CcKvKeyStringEditorStateSaving;
5 |
6 | export interface CcKvKeyStringEditorStateLoading {
7 | type: 'loading';
8 | }
9 |
10 | export interface CcKvKeyStringEditorStateIdle {
11 | type: 'idle';
12 | value: string;
13 | }
14 |
15 | export interface CcKvKeyStringEditorStateSaving {
16 | type: 'saving';
17 | value: string;
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/cc-kv-terminal/cc-kv-terminal.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-kv-terminal.types.js').CcKvTerminalState} CcKvTerminalState
5 | */
6 |
7 | /**
8 | * Dispatched when KV terminal state changes.
9 | * @extends {CcEvent}
10 | */
11 | export class CcKvTerminalStateChangeEvent extends CcEvent {
12 | static TYPE = 'cc-kv-terminal-state-change';
13 |
14 | /**
15 | * @param {CcKvTerminalState} detail
16 | */
17 | constructor(detail) {
18 | super(CcKvTerminalStateChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
22 | /**
23 | * Dispatched when a KV command execution is requested.
24 | * @extends {CcEvent}
25 | */
26 | export class CcKvCommandExecuteEvent extends CcEvent {
27 | static TYPE = 'cc-kv-command-execute';
28 |
29 | /**
30 | * @param {string} detail
31 | */
32 | constructor(detail) {
33 | super(CcKvCommandExecuteEvent.TYPE, detail);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/cc-kv-terminal/cc-kv-terminal.types.d.ts:
--------------------------------------------------------------------------------
1 | export type CcKvTerminalState = CcKvTerminalStateIdle | CcKvTerminalStateRunning;
2 |
3 | export interface CcKvTerminalStateIdle {
4 | type: 'idle';
5 | history: Array;
6 | }
7 |
8 | export interface CcKvTerminalStateRunning {
9 | type: 'running';
10 | commandLine: string;
11 | history: Array;
12 | }
13 |
14 | export interface CcKvCommandHistoryEntry {
15 | commandLine: string;
16 | result: Array;
17 | success: boolean;
18 | }
19 |
20 | export type CcKvCommandContentItem = CcKvCommandContentItemCommandLine | CcKvCommandContentItemResultLine;
21 |
22 | interface CcKvCommandContentItemCommandLine {
23 | id: string;
24 | type: 'commandLine';
25 | line: string;
26 | hasResult: boolean;
27 | }
28 |
29 | interface CcKvCommandContentItemResultLine {
30 | id: string;
31 | type: 'resultLine';
32 | line: string;
33 | success: boolean;
34 | last: boolean;
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/cc-logs-addon-runtime/cc-logs-addon-runtime.types.d.ts:
--------------------------------------------------------------------------------
1 | import { LogsStreamState } from '../../lib/logs/logs-stream.types.js';
2 |
3 | export interface LogsAddonRuntimeState {
4 | type: 'loaded';
5 | streamState: LogsStreamState;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/cc-logs-app-access/cc-logs-app-access.types.d.ts:
--------------------------------------------------------------------------------
1 | import { LogsStreamState } from '../../lib/logs/logs-stream.types.js';
2 |
3 | export interface LogsAppAccessState {
4 | type: 'loaded';
5 | streamState: LogsStreamState;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/cc-logs-app-runtime/cc-logs-app-runtime.types.d.ts:
--------------------------------------------------------------------------------
1 | import { LogsStreamState } from '../../lib/logs/logs-stream.types.js';
2 | import { GhostInstance, Instance } from '../cc-logs-instances/cc-logs-instances.types.js';
3 |
4 | export interface LogsAppRuntimeStateLoadingInstances {
5 | type: 'loadingInstances';
6 | }
7 |
8 | export interface LogsAppRuntimeStateErrorInstances {
9 | type: 'errorInstances';
10 | }
11 |
12 | export interface LogsAppRuntimeStateLoaded {
13 | type: 'loaded';
14 | streamState: LogsStreamState;
15 | instances: Array;
16 | selection: Array;
17 | }
18 |
19 | export type LogsAppRuntimeState =
20 | | LogsAppRuntimeStateLoadingInstances
21 | | LogsAppRuntimeStateErrorInstances
22 | | LogsAppRuntimeStateLoaded;
23 |
--------------------------------------------------------------------------------
/src/components/cc-logs-control/cc-logs-control.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-logs-control.types.js').LogsOptionsChangeEventData} LogsOptionsChangeEventData
5 | */
6 |
7 | /**
8 | * Dispatched when the logs options have changed.
9 | * @extends {CcEvent}
10 | */
11 | export class CcLogsOptionsChangeEvent extends CcEvent {
12 | static TYPE = 'cc-logs-options-change';
13 |
14 | /**
15 | * @param {LogsOptionsChangeEventData} detail
16 | */
17 | constructor(detail) {
18 | super(CcLogsOptionsChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-logs-control/cc-logs-control.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Timezone } from '../../lib/date/date.types.js';
2 | import { DateDisplay } from '../cc-logs/date-display.types.js';
3 |
4 | export type LogsControlPalette = 'default' | 'One Light' | 'Tokyo Night Light' | 'Night Owl' | 'Everblush' | 'Hyoob';
5 |
6 | export interface LogsMetadataDisplay {
7 | label: string;
8 | hidden: boolean;
9 | }
10 |
11 | export interface LogsOptions {
12 | 'date-display': DateDisplay;
13 | 'metadata-display': Record;
14 | palette: LogsControlPalette;
15 | timezone: Timezone;
16 | 'wrap-lines': boolean;
17 | 'strip-ansi': boolean;
18 | }
19 |
20 | export interface LogsOptionsChangeEventData {
21 | /** The name of the option that has changed */
22 | name: keyof LogsOptions;
23 | /** The new options */
24 | options: LogsOptions;
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/cc-logs-date-range-selector/cc-logs-date-range-selector.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-logs-date-range-selector.types.js').LogsDateRangeSelectionChangeEventData} LogsDateRangeSelectionChangeEventData
5 | */
6 |
7 | /**
8 | * Dispatched when the logs date range selection changes.
9 | * @extends {CcEvent}
10 | */
11 | export class CcLogsDateRangeSelectionChangeEvent extends CcEvent {
12 | static TYPE = 'cc-logs-date-range-selection-change';
13 |
14 | /**
15 | * @param {LogsDateRangeSelectionChangeEventData} detail
16 | */
17 | constructor(detail) {
18 | super(CcLogsDateRangeSelectionChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-logs-date-range-selector/cc-logs-date-range-selector.types.d.ts:
--------------------------------------------------------------------------------
1 | import { DateRange } from '../../lib/date/date-range.types.js';
2 |
3 | export type LogsDateRangeSelection =
4 | | LogsDateRangeSelectionLive
5 | | LogsDateRangeSelectionPreset
6 | | LogsDateRangeSelectionCustom;
7 |
8 | export interface LogsDateRangeSelectionLive {
9 | type: 'live';
10 | }
11 |
12 | export interface LogsDateRangeSelectionPreset {
13 | type: 'preset';
14 | preset: LogsDateRangePresetType;
15 | }
16 |
17 | export interface LogsDateRangeSelectionCustom {
18 | type: 'custom';
19 | since: string;
20 | until: string;
21 | }
22 |
23 | export type LogsDateRangePresetType = 'lastHour' | 'last4Hours' | 'last7Days' | 'today' | 'yesterday';
24 |
25 | export type LogsDateRangeSelectOption = 'live' | 'custom' | LogsDateRangePresetType;
26 |
27 | export interface LogsDateRangeSelectionChangeEventData {
28 | selection: LogsDateRangeSelection;
29 | range: DateRange;
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/cc-logs-date-range-selector/date-range-selection.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('./cc-logs-date-range-selector.types.js').LogsDateRangeSelection} LogsDateRangeSelection
3 | * @typedef {import('../../lib/date/date-range.types.js').DateRange} DateRange
4 | */
5 |
6 | import { getRangeToNow, lastXDays, today, yesterday } from '../../lib/date/date-range-utils.js';
7 |
8 | /**
9 | * Returns the date range corresponding to the given selection.
10 | *
11 | * Note that a `live` selection gives à 10 minutes window until now.
12 | *
13 | * @param {LogsDateRangeSelection} dateRangeSelection
14 | * @return {DateRange}
15 | */
16 | export function dateRangeSelectionToDateRange(dateRangeSelection) {
17 | switch (dateRangeSelection.type) {
18 | case 'custom':
19 | return {
20 | since: dateRangeSelection.since,
21 | until: dateRangeSelection.until,
22 | };
23 | case 'live':
24 | return {
25 | since: getRangeToNow(1000 * 60 * 10).since,
26 | };
27 | case 'preset':
28 | switch (dateRangeSelection.preset) {
29 | case 'lastHour':
30 | return getRangeToNow(1000 * 60 * 60);
31 | case 'last4Hours':
32 | return getRangeToNow(1000 * 60 * 60 * 4);
33 | case 'last7Days':
34 | return lastXDays(7);
35 | case 'today':
36 | return today();
37 | case 'yesterday':
38 | return yesterday();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/cc-logs-instances/cc-logs-instances.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when logs instances selection changes.
5 | * @extends {CcEvent>}
6 | */
7 | export class CcLogsInstancesSelectionChangeEvent extends CcEvent {
8 | static TYPE = 'cc-logs-instances-selection-change';
9 |
10 | /**
11 | * @param {Array} detail
12 | */
13 | constructor(detail) {
14 | super(CcLogsInstancesSelectionChangeEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-logs-instances/cc-logs-instances.types.d.ts:
--------------------------------------------------------------------------------
1 | export type LogsInstancesState = LogsInstancesStateLoading | LogsInstancesStateError | LogsInstancesStateLoaded;
2 |
3 | export interface LogsInstancesStateLoading {
4 | state: 'loading';
5 | }
6 |
7 | export interface LogsInstancesStateError {
8 | state: 'error';
9 | }
10 |
11 | export interface LogsInstancesStateLoaded {
12 | state: 'loaded';
13 | mode: LogsMode;
14 | instances: Array;
15 | selection: Array;
16 | }
17 |
18 | export type LogsMode = 'live' | 'cold';
19 |
20 | export type DeploymentState = 'QUEUED' | 'WORK_IN_PROGRESS' | 'SUCCEEDED' | 'CANCELLED' | 'FAILED';
21 |
22 | export interface Deployment {
23 | id: string;
24 | state: DeploymentState;
25 | creationDate: Date;
26 | commitId: string;
27 | endDate?: Date;
28 | }
29 |
30 | export type InstanceState =
31 | | 'BOOTING'
32 | | 'STARTING'
33 | | 'DEPLOYING'
34 | | 'BUILDING'
35 | | 'READY'
36 | | 'UP'
37 | | 'STOPPING'
38 | | 'DELETED'
39 | | 'MIGRATION_IN_PROGRESS'
40 | | 'TASK_IN_PROGRESS';
41 | export type InstanceKind = 'BUILD' | 'RUN';
42 |
43 | export interface Instance {
44 | ghost: false;
45 | id: string;
46 | name: string;
47 | index: number;
48 | deployment: Deployment;
49 | state: InstanceState;
50 | creationDate: Date;
51 | deletionDate?: Date;
52 | kind: InstanceKind;
53 | }
54 |
55 | export interface GhostInstance {
56 | ghost: true;
57 | id: string;
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/cc-logs-loading-progress/cc-logs-loading-progress-state-builder.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('./cc-logs-loading-progress.types.js').LogsLoadingProgressState} LogsLoadingProgressState
3 | * @typedef {import('../../lib/logs/logs-stream.types.js').LogsStreamState} LogsProgressState
4 | */
5 |
6 | /**
7 | * @param {LogsProgressState} progressState
8 | * @return {LogsLoadingProgressState|null}
9 | */
10 | export function buildLogsLoadingProgressState(progressState) {
11 | if (progressState.type === 'idle') {
12 | return null;
13 | }
14 | if (progressState.type === 'connecting') {
15 | return null;
16 | }
17 | if (progressState.type === 'error') {
18 | return null;
19 | }
20 | if (progressState.type === 'waitingForFirstLog') {
21 | return null;
22 | }
23 |
24 | if (progressState.type === 'running') {
25 | return {
26 | type: 'running',
27 | ...progressState.progress,
28 | overflowing: progressState.overflowing,
29 | };
30 | }
31 |
32 | if (progressState.type === 'paused' && progressState.reason === 'user') {
33 | return {
34 | type: 'paused',
35 | ...progressState.progress,
36 | overflowing: progressState.overflowing,
37 | };
38 | }
39 |
40 | if (progressState.type === 'paused' && progressState.reason === 'overflow') {
41 | return {
42 | type: 'overflowLimitReached',
43 | ...progressState.progress,
44 | };
45 | }
46 |
47 | return {
48 | type: 'completed',
49 | ...progressState.progress,
50 | overflowing: progressState.overflowing,
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/cc-logs-loading-progress/cc-logs-loading-progress.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when pause of the logs stream is requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcLogsLoadingPauseEvent extends CcEvent {
8 | static TYPE = 'cc-logs-loading-pause';
9 |
10 | constructor() {
11 | super(CcLogsLoadingPauseEvent.TYPE);
12 | }
13 | }
14 |
15 | /**
16 | * Dispatched when resume of the logs stream is requested.
17 | * @extends {CcEvent}
18 | */
19 | export class CcLogsLoadingResumeEvent extends CcEvent {
20 | static TYPE = 'cc-logs-loading-resume';
21 |
22 | constructor() {
23 | super(CcLogsLoadingResumeEvent.TYPE);
24 | }
25 | }
26 |
27 | /**
28 | * Dispatched when the logs stream overflow is accepted.
29 | * @extends {CcEvent}
30 | */
31 | export class CcLogsLoadingOverflowAcceptEvent extends CcEvent {
32 | static TYPE = 'cc-logs-loading-overflow-accept';
33 |
34 | constructor() {
35 | super(CcLogsLoadingOverflowAcceptEvent.TYPE);
36 | }
37 | }
38 |
39 | /**
40 | * Dispatched when the logs stream overflow is discarded.
41 | * @extends {CcEvent}
42 | */
43 | export class CcLogsLoadingOverflowDiscardEvent extends CcEvent {
44 | static TYPE = 'cc-logs-loading-overflow-discard';
45 |
46 | constructor() {
47 | super(CcLogsLoadingOverflowDiscardEvent.TYPE);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/components/cc-logs-loading-progress/cc-logs-loading-progress.types.d.ts:
--------------------------------------------------------------------------------
1 | export type LogsLoadingProgressState =
2 | | LogsLoadingProgressStateIdle
3 | | LogsLoadingProgressStateRunning
4 | | LogsLoadingProgressStatePaused
5 | | LogsLoadingProgressStateOverflowLimitReached
6 | | LogsLoadingProgressStateCompleted;
7 |
8 | export interface LogsLoadingProgressStateIdle {
9 | type: 'idle';
10 | }
11 |
12 | export interface LogsLoadingProgressStateRunning {
13 | type: 'running';
14 | value: number;
15 | percent?: number;
16 | overflowing: boolean;
17 | }
18 |
19 | export interface LogsLoadingProgressStatePaused {
20 | type: 'paused';
21 | value: number;
22 | percent?: number;
23 | overflowing: boolean;
24 | }
25 |
26 | export interface LogsLoadingProgressStateOverflowLimitReached {
27 | type: 'overflowLimitReached';
28 | value: number;
29 | percent?: number;
30 | }
31 |
32 | export interface LogsLoadingProgressStateCompleted {
33 | type: 'completed';
34 | value: number;
35 | overflowing: boolean;
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/cc-logs-message-filter/cc-logs-message-filter.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-logs-message-filter.types.js').LogsMessageFilterValue} LogsMessageFilterValue
5 | */
6 |
7 | /**
8 | * Dispatched when the logs message filter changes.
9 | * @extends {CcEvent}
10 | */
11 | export class CcLogsMessageFilterChangeEvent extends CcEvent {
12 | static TYPE = 'cc-logs-message-filter-change';
13 |
14 | /**
15 | * @param {LogsMessageFilterValue} detail
16 | */
17 | constructor(detail) {
18 | super(CcLogsMessageFilterChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-logs-message-filter/cc-logs-message-filter.types.d.ts:
--------------------------------------------------------------------------------
1 | import { LogMessageFilterMode } from '../cc-logs/cc-logs.types.js';
2 |
3 | export interface LogsMessageFilterValue {
4 | value: string;
5 | mode: LogMessageFilterMode;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/cc-logs/animation-runner.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Synchronizes an animation with `requestAnimationFrame`.
3 | */
4 | export class AnimationRunner {
5 | /**
6 | * Starts the animation.
7 | *
8 | * The callback will be executed at each frame tick.
9 | * The callback must return whether the lastTickTimestamp should be updated.
10 | *
11 | * @param {(nowTimestamp: number, startTimestamp: number, lastTickTimestamp: number) => boolean} animationCallback
12 | */
13 | start(animationCallback) {
14 | /** @type {(nowTimestamp: number) => void} */
15 | this._animation = (nowTimestamp) => {
16 | const hasTicked = animationCallback(nowTimestamp, this._startTimestamp, this._lastTimestamp);
17 | if (hasTicked) {
18 | this._lastTimestamp = nowTimestamp;
19 | }
20 | if (this._animation != null) {
21 | requestAnimationFrame(this._animation);
22 | }
23 | };
24 |
25 | this._startTimestamp = performance.now();
26 | this._lastTimestamp = this._startTimestamp;
27 |
28 | this._animation(this._startTimestamp);
29 | }
30 |
31 | /**
32 | * @return {boolean} Whether the animation is stopped
33 | */
34 | isStopped() {
35 | return this._animation == null;
36 | }
37 |
38 | /**
39 | * Stops the animation.
40 | */
41 | stop() {
42 | this._animation = null;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/cc-logs/cc-logs.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when the logs follow state changed after a user interaction.
5 | * @extends {CcEvent}
6 | */
7 | export class CcLogsFollowChangeEvent extends CcEvent {
8 | static TYPE = 'cc-logs-follow-change';
9 |
10 | /**
11 | * @param {boolean} detail
12 | */
13 | constructor(detail) {
14 | super(CcLogsFollowChangeEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/cc-logs/cc-logs.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface Log {
2 | id: string;
3 | date: Date;
4 | message: string;
5 | metadata: Array;
6 | }
7 |
8 | export interface Metadata {
9 | name: string;
10 | value: string;
11 | }
12 |
13 | export type MetadataRenderer = MetadataRenderingProvider | MetadataRendering;
14 |
15 | export type MetadataRenderingProvider = (metadata: Metadata) => MetadataRendering;
16 |
17 | export interface MetadataRendering {
18 | hidden?: boolean;
19 | intent?: MetadataIntent;
20 | showName?: boolean;
21 | size?: 'auto' | number;
22 | strong?: boolean;
23 | text?: string;
24 | }
25 |
26 | export type MetadataIntent = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
27 |
28 | export interface MetadataFilter {
29 | metadata: string;
30 | value: string;
31 | }
32 |
33 | export type LogMessageFilterMode = 'loose' | 'strict' | 'regex';
34 |
35 | export interface LogFilter {
36 | message: LogMessageFilter;
37 | metadata: Array;
38 | }
39 |
40 | export interface LogMessageFilter {
41 | type: string;
42 | value: string;
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/cc-logs/date-display.types.d.ts:
--------------------------------------------------------------------------------
1 | export type DateDisplay = 'none' | 'datetime-iso' | 'time-iso' | 'datetime-short' | 'time-short';
2 |
--------------------------------------------------------------------------------
/src/components/cc-logsmap/cc-logsmap.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('../common.types.js').MapModeType} MapModeType
5 | */
6 |
7 | /**
8 | * Dispatched when the logsmap display mode changes.
9 | * @extends {CcEvent}
10 | */
11 | export class CcLogsmapModeChangeEvent extends CcEvent {
12 | static TYPE = 'cc-logsmap-mode-change';
13 |
14 | /**
15 | * @param {MapModeType} detail
16 | */
17 | constructor(detail) {
18 | super(CcLogsmapModeChangeEvent.TYPE, detail);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-logsmap/cc-logsmap.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface PointsOptions {
2 | spreadDuration?: boolean | number; // Spread points appearance over a time window (in ms)
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/cc-map-marker-dot/cc-map-marker-dot.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-map-marker-dot.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🛠 Maps/',
7 | component: 'cc-map-marker-dot',
8 | };
9 |
10 | const conf = {
11 | component: 'cc-map-marker-dot',
12 | displayMode: 'flex-wrap',
13 | // language=CSS
14 | css: `
15 | cc-map-marker-dot {
16 | --cc-map-marker-dot-size: 12px;
17 | }
18 | `,
19 | };
20 |
21 | export const defaultStory = makeStory(conf, {
22 | items: [
23 | { count: 1 },
24 | { count: 2 },
25 | { count: 3 },
26 | { count: 5 },
27 | { count: 10 },
28 | { count: 15 },
29 | { count: 25 },
30 | { count: 50 },
31 | { count: 75 },
32 | { count: 100 },
33 | { count: 150 },
34 | { count: 500 },
35 | { count: 1000 },
36 | { count: 2000 },
37 | { count: 10000 },
38 | { count: 100000 },
39 | { count: 1000000 },
40 | { count: 10000000 },
41 | { count: 100000000 },
42 | ],
43 | });
44 |
45 | export const size = makeStory(conf, {
46 | items: [
47 | { count: 10, style: '--cc-map-marker-dot-size: 6px' },
48 | { count: 10, style: '--cc-map-marker-dot-size: 8px' },
49 | { count: 10, style: '--cc-map-marker-dot-size: 10px' },
50 | { count: 10, style: '--cc-map-marker-dot-size: 12px' },
51 | { count: 10, style: '--cc-map-marker-dot-size: 14px' },
52 | { count: 10, style: '--cc-map-marker-dot-size: 16px' },
53 | { count: 10, style: '--cc-map-marker-dot-size: 18px' },
54 | { count: 10, style: '--cc-map-marker-dot-size: 20px' },
55 | ],
56 | });
57 |
--------------------------------------------------------------------------------
/src/components/cc-map-marker-server/cc-map-marker-server.stories.js:
--------------------------------------------------------------------------------
1 | import { makeStory } from '../../stories/lib/make-story.js';
2 | import './cc-map-marker-server.js';
3 |
4 | export default {
5 | tags: ['autodocs'],
6 | title: '🛠 Maps/',
7 | component: 'cc-map-marker-server',
8 | };
9 |
10 | const conf = {
11 | component: 'cc-map-marker-server',
12 | displayMode: 'flex-wrap',
13 | };
14 |
15 | export const defaultStory = makeStory(conf, {
16 | items: [{ state: 'default' }, { state: 'hovered' }, { state: 'selected' }],
17 | });
18 |
19 | export const stateWithDefault = makeStory(conf, {
20 | items: [{ state: 'default' }],
21 | });
22 |
23 | export const stateWithHovered = makeStory(conf, {
24 | items: [{ state: 'hovered' }],
25 | });
26 |
27 | export const stateWithSelected = makeStory(conf, {
28 | items: [{ state: 'selected' }],
29 | });
30 |
--------------------------------------------------------------------------------
/src/components/cc-map-marker-server/cc-map-marker-server.types.d.ts:
--------------------------------------------------------------------------------
1 | export type MarkerStateType = 'default' | 'hovered' | 'selected';
2 |
--------------------------------------------------------------------------------
/src/components/cc-map/cc-map.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('../common.types.js').Point} Point
5 | */
6 |
7 | /**
8 | * Dispatched when a map marker has been clicked.
9 | * @extends {CcEvent}
10 | */
11 | export class CcMapMarkerClickEvent extends CcEvent {
12 | static TYPE = 'cc-map-marker-click';
13 |
14 | /**
15 | * @param {Point} detail
16 | */
17 | constructor(detail) {
18 | super(CcMapMarkerClickEvent.TYPE, detail);
19 | }
20 | }
21 |
22 | /**
23 | * Dispatched when a map marker has been entered by the mouse pointer.
24 | * @extends {CcEvent}
25 | */
26 | export class CcMapMarkerEnterEvent extends CcEvent {
27 | static TYPE = 'cc-map-marker-enter';
28 |
29 | /**
30 | * @param {Point} detail
31 | */
32 | constructor(detail) {
33 | super(CcMapMarkerEnterEvent.TYPE, detail);
34 | }
35 | }
36 |
37 | /**
38 | * Dispatched when a map marker has been left by the mouse pointer.
39 | * @extends {CcEvent}
40 | */
41 | export class CcMapMarkerLeaveEvent extends CcEvent {
42 | static TYPE = 'cc-map-marker-leave';
43 |
44 | /**
45 | * @param {Point} detail
46 | */
47 | constructor(detail) {
48 | super(CcMapMarkerLeaveEvent.TYPE, detail);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/cc-map/cc-map.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Marker, PointExpression } from 'src/lib/leaflet/leaflet-esm.js';
2 | import { Point } from '../common.types.js';
3 |
4 | export interface CachedPoint {
5 | point: Point;
6 | marker: Marker & {
7 | tag?: string;
8 | tooltip?: string | { tag: string };
9 | };
10 | iconElement: MapIconElement;
11 | }
12 |
13 | export interface MapIconElement extends HTMLElement {
14 | size: PointExpression;
15 | anchor: PointExpression;
16 | tooltip: PointExpression;
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/cc-matomo-info/cc-matomo-info.types.d.ts:
--------------------------------------------------------------------------------
1 | export type MatomoInfoState = MatomoInfoStateLoaded | MatomoInfoStateLoading | MatomoInfoStateError;
2 |
3 | export interface MatomoInfoStateLoaded {
4 | type: 'loaded';
5 | matomoUrl: string;
6 | mysqlUrl: string;
7 | phpUrl: string;
8 | redisUrl: string;
9 | }
10 |
11 | export interface MatomoInfoStateLoading {
12 | type: 'loading';
13 | }
14 |
15 | export interface MatomoInfoStateError {
16 | type: 'error';
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/cc-notice/cc-notice.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when a notice has been dismissed.
5 | * @extends {CcEvent}
6 | */
7 | export class CcNoticeDismissEvent extends CcEvent {
8 | static TYPE = 'cc-notice-dismiss';
9 |
10 | constructor() {
11 | super(CcNoticeDismissEvent.TYPE);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/cc-notice/cc-notice.types.d.ts:
--------------------------------------------------------------------------------
1 | export type NoticeIntent = 'info' | 'danger' | 'success' | 'warning';
2 |
--------------------------------------------------------------------------------
/src/components/cc-oauth-consumer-form/cc-oauth-consumer-form.types.d.ts:
--------------------------------------------------------------------------------
1 | import { FormDataMap } from '../../lib/form/form.types.js';
2 | import { OauthConsumer, OauthConsumerRights } from '../cc-oauth-consumer-info/cc-oauth-consumer-info.types.js';
3 |
4 | export type OauthConsumerFormState =
5 | | OauthConsumerFormStateIdleCreate
6 | | OauthConsumerFormStateCreating
7 | | OauthConsumerFormStateIdleUpdate
8 | | OauthConsumerFormStateUpdating
9 | | OauthConsumerFormStateDeleting
10 | | OauthConsumerFormStateLoading
11 | | OauthConsumerFormStateError;
12 |
13 | export interface OauthConsumerFormStateIdleCreate {
14 | type: 'idle-create';
15 | }
16 |
17 | export interface OauthConsumerFormStateCreating {
18 | type: 'creating';
19 | }
20 |
21 | export interface OauthConsumerFormStateIdleUpdate {
22 | type: 'idle-update';
23 | values: OauthConsumerWithoutKeyAndSecret;
24 | }
25 |
26 | export interface OauthConsumerFormStateUpdating {
27 | type: 'updating';
28 | values: OauthConsumerWithoutKeyAndSecret;
29 | }
30 |
31 | export interface OauthConsumerFormStateDeleting {
32 | type: 'deleting';
33 | values: OauthConsumerWithoutKeyAndSecret;
34 | }
35 |
36 | export interface OauthConsumerFormStateLoading {
37 | type: 'loading';
38 | }
39 |
40 | export interface OauthConsumerFormStateError {
41 | type: 'error';
42 | }
43 |
44 | export interface OauthConsumerFormData extends FormDataMap {
45 | name: string;
46 | description: string;
47 | url: string;
48 | picture: string;
49 | baseUrl: string;
50 | rights: Array;
51 | }
52 |
53 | export type OauthConsumerWithoutKeyAndSecret = Omit;
54 |
--------------------------------------------------------------------------------
/src/components/cc-order-summary/cc-order-summary.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when a product creation has be requested.
5 | * @extends {CcEvent}
6 | */
7 | export class CcProductCreateEvent extends CcEvent {
8 | static TYPE = 'cc-product-create';
9 |
10 | constructor() {
11 | super(CcProductCreateEvent.TYPE);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/cc-order-summary/cc-order-summary.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface OrderSummary {
2 | name: string;
3 | tags?: Array;
4 | logo?: LogoInfos;
5 | configuration?: Array;
6 | submitStatus?: 'disabled' | 'waiting';
7 | }
8 |
9 | export interface LogoInfos {
10 | url: string;
11 | alt: string;
12 | }
13 |
14 | export interface ConfigurationItem {
15 | label: string;
16 | value: string;
17 | a11yLive?: boolean;
18 | skeleton?: boolean;
19 | skeletonValueOnly?: boolean;
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-orga-member-list/cc-orga-member-list.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-orga-member-list.types.js').InviteMember} InviteMember
5 | * @typedef {import('../cc-orga-member-card/cc-orga-member-card.types.js').OrgaMember} OrgaMember
6 | */
7 |
8 | /**
9 | * Dispatched when an organisation member invitation is requested.
10 | * @extends {CcEvent}
11 | */
12 | export class CcOrgaMemberInviteEvent extends CcEvent {
13 | static TYPE = 'cc-orga-member-invite';
14 |
15 | /**
16 | * @param {InviteMember} detail
17 | */
18 | constructor(detail) {
19 | super(CcOrgaMemberInviteEvent.TYPE, detail);
20 | }
21 | }
22 |
23 | /**
24 | * Dispatched when a member has left the organisation.
25 | * @extends {CcEvent}
26 | */
27 | export class CcOrgaMemberLeftEvent extends CcEvent {
28 | static TYPE = 'cc-orga-member-left';
29 |
30 | /**
31 | * @param {OrgaMember} detail
32 | */
33 | constructor(detail) {
34 | super(CcOrgaMemberLeftEvent.TYPE, detail);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/cc-orga-member-list/cc-orga-member-list.types.d.ts:
--------------------------------------------------------------------------------
1 | import { OrgaMemberCardState, OrgaMemberRole } from '../cc-orga-member-card/cc-orga-member-card.types.js';
2 |
3 | export type OrgaMemberListState = OrgaMemberListStateLoading | OrgaMemberListStateLoaded | OrgaMemberListStateError;
4 |
5 | interface OrgaMemberListStateLoading {
6 | type: 'loading';
7 | }
8 |
9 | interface OrgaMemberListStateLoaded {
10 | type: 'loaded';
11 | memberList: OrgaMemberCardState[];
12 | identityFilter: string;
13 | mfaDisabledOnlyFilter: boolean;
14 | dangerZoneState: 'idle' | 'leaving' | 'error';
15 | }
16 |
17 | interface OrgaMemberListStateError {
18 | type: 'error';
19 | }
20 |
21 | export interface InviteMember {
22 | email: string;
23 | role: OrgaMemberRole;
24 | }
25 |
26 | interface ListAuthorisations {
27 | invite: boolean;
28 | edit: boolean;
29 | delete: boolean;
30 | }
31 |
32 | export interface InviteMemberFormState {
33 | type: 'idle' | 'inviting';
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/cc-overview/cc-overview.types.d.ts:
--------------------------------------------------------------------------------
1 | export type OverviewModeType = 'app' | 'orga';
2 |
--------------------------------------------------------------------------------
/src/components/cc-plan-item/cc-plan-item.types.d.ts:
--------------------------------------------------------------------------------
1 | import { BadgeIntent } from '../cc-badge/cc-badge.types.js';
2 | import { IconModel } from '../common.types.js';
3 |
4 | export interface PlanBadge {
5 | content: string;
6 | intent?: BadgeIntent;
7 | }
8 |
9 | export interface PlanDetails {
10 | icon: IconModel;
11 | value: string;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/cc-plan-picker/cc-plan-picker.types.d.ts:
--------------------------------------------------------------------------------
1 | import { PlanBadge, PlanDetails } from '../cc-plan-item/cc-plan-item.types.js';
2 |
3 | export interface PlanItem {
4 | id: string;
5 | badge?: PlanBadge;
6 | name: string;
7 | details?: PlanDetails[];
8 | disabled?: boolean;
9 | selected?: boolean;
10 | relatedPlans?: Array>;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/cc-popover/cc-popover.types.d.ts:
--------------------------------------------------------------------------------
1 | export type PopoverPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
2 |
--------------------------------------------------------------------------------
/src/components/cc-pricing-estimation/cc-pricing-estimation.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ConsumptionPlan, Plan, PricingSection } from '../common.types.js';
2 |
3 | export type PricingEstimationState =
4 | | PricingEstimationStateLoaded
5 | | PricingEstimationStateLoading
6 | | PricingEstimationStateError;
7 |
8 | export interface PricingEstimationStateError {
9 | type: 'error';
10 | }
11 |
12 | export interface PricingEstimationStateLoading {
13 | type: 'loading';
14 | }
15 |
16 | export interface PricingEstimationStateLoaded {
17 | type: 'loaded';
18 | runtimePrices: Array;
19 | countablePrices: Array;
20 | }
21 |
22 | export interface FormattedRuntimePrice {
23 | priceId: string;
24 | price: number;
25 | }
26 |
27 | export interface RuntimePlanWithQuantity extends Plan {
28 | quantity: number;
29 | }
30 |
31 | export interface CountablePlanWithQuantity extends ConsumptionPlan {
32 | quantity: number;
33 | sections: PricingSection[];
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/cc-pricing-header/cc-pricing-header.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Zone } from '../common.types.js';
2 |
3 | export interface PricingHeaderStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | export interface PricingHeaderStateError {
8 | type: 'error';
9 | }
10 |
11 | export interface PricingHeaderStateLoaded {
12 | type: 'loaded';
13 | zones: Zone[];
14 | }
15 |
16 | export type PricingHeaderState = PricingHeaderStateLoading | PricingHeaderStateError | PricingHeaderStateLoaded;
17 |
--------------------------------------------------------------------------------
/src/components/cc-pricing-page/cc-pricing-page.types.d.ts:
--------------------------------------------------------------------------------
1 | import {
2 | CountablePlanWithQuantity,
3 | RuntimePlanWithQuantity,
4 | } from '../cc-pricing-estimation/cc-pricing-estimation.types.js';
5 |
6 | export interface SelectedPlansById {
7 | [planId: string]: RuntimePlanWithQuantity | CountablePlanWithQuantity;
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/cc-pricing-product-consumption/cc-pricing-product-consumption.types.d.ts:
--------------------------------------------------------------------------------
1 | import { PricingSection, SectionType } from '../common.types.js';
2 |
3 | interface PricingProductConsumptionStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | interface PricingProductConsumptionStateError {
8 | type: 'error';
9 | }
10 |
11 | interface PricingProductConsumptionStateLoaded {
12 | type: 'loaded';
13 | name: string;
14 | sections: PricingSection[];
15 | }
16 |
17 | export type PricingProductConsumptionState =
18 | | PricingProductConsumptionStateLoading
19 | | PricingProductConsumptionStateError
20 | | PricingProductConsumptionStateLoaded;
21 |
22 | export type SectionStates = Partial<
23 | Record<
24 | SectionType,
25 | {
26 | isClosed: boolean;
27 | quantity: number;
28 | unitValue: string;
29 | }
30 | >
31 | >;
32 |
--------------------------------------------------------------------------------
/src/components/cc-pricing-product/cc-pricing-product.types.d.ts:
--------------------------------------------------------------------------------
1 | import { FormattedFeature, Plan } from '../common.types.js';
2 |
3 | interface PricingProductStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | interface PricingProductStateError {
8 | type: 'error';
9 | }
10 |
11 | interface PricingProductStateLoaded {
12 | type: 'loaded';
13 | productFeatures: FormattedFeature[];
14 | name: string;
15 | plans: Plan[];
16 | }
17 |
18 | export type PricingProductState = PricingProductStateLoading | PricingProductStateError | PricingProductStateLoaded;
19 |
--------------------------------------------------------------------------------
/src/components/cc-product-card/cc-product-card.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface Keyword {
2 | value: string;
3 | hidden: boolean;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/cc-product-card/generate-random-keywords.js:
--------------------------------------------------------------------------------
1 | import { randomString } from '../../lib/utils.js';
2 |
3 | /**
4 | * @typedef {import('./cc-product-card.types.js').Keyword} Keyword
5 | */
6 |
7 | /**
8 | * Returns a list of random keywords.
9 | *
10 | * @param {number} number
11 | * @returns {Array}
12 | */
13 | export function generateRandomKeywords(number) {
14 | const keywords = [{ value: 'hidden', hidden: true }];
15 |
16 | for (let i = 0; i < number; i++) {
17 | const numberOfChars = Math.floor(Math.random() * 7 + 3);
18 | keywords.push({ value: randomString(numberOfChars), hidden: false });
19 | }
20 |
21 | return keywords;
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/cc-product-list/cc-product-list.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Keyword } from '../cc-product-card/cc-product-card.types.js';
2 |
3 | export interface Product {
4 | description: string;
5 | iconUrl: string;
6 | keywords?: Keyword[];
7 | name: string;
8 | url: string;
9 | }
10 |
11 | export interface ProductsCategory {
12 | categoryName: string;
13 | icon?: string;
14 | products: Product[];
15 | }
16 |
17 | export interface CategoryFilter {
18 | categoryName: string;
19 | toggled: boolean;
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-select/cc-select.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface Option {
2 | label: string;
3 | value: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/cc-ssh-key-list/cc-ssh-key-list.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-ssh-key-list.types.js').NewKey} NewKey
5 | * @typedef {import('./cc-ssh-key-list.types.js').GithubSshKey} GithubSshKey
6 | */
7 |
8 | /**
9 | * Dispatched when an ssh key creation is requested.
10 | * @extends {CcEvent}
11 | */
12 | export class CcSshKeyCreateEvent extends CcEvent {
13 | static TYPE = 'cc-ssh-key-create';
14 |
15 | /**
16 | * @param {NewKey} detail
17 | */
18 | constructor(detail) {
19 | super(CcSshKeyCreateEvent.TYPE, detail);
20 | }
21 | }
22 |
23 | /**
24 | * Dispatched when an ssh key deletion is requested.
25 | * @extends {CcEvent<{name: string}>}
26 | */
27 | export class CcSshKeyDeleteEvent extends CcEvent {
28 | static TYPE = 'cc-ssh-key-delete';
29 |
30 | /**
31 | * @param {{name: string}} detail
32 | */
33 | constructor(detail) {
34 | super(CcSshKeyDeleteEvent.TYPE, detail);
35 | }
36 | }
37 |
38 | /**
39 | * Dispatched when a GitHub ssh key import is requested.
40 | * @extends {CcEvent}
41 | */
42 | export class CcSshKeyImportEvent extends CcEvent {
43 | static TYPE = 'cc-ssh-key-import';
44 |
45 | /**
46 | * @param {GithubSshKey} detail
47 | */
48 | constructor(detail) {
49 | super(CcSshKeyImportEvent.TYPE, detail);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/components/cc-ssh-key-list/cc-ssh-key-list.types.d.ts:
--------------------------------------------------------------------------------
1 | //#region creation form
2 | export interface NewKey {
3 | name: string;
4 | publicKey: string;
5 | }
6 |
7 | export interface CreateSshKeyFormState {
8 | type: 'idle' | 'creating';
9 | }
10 |
11 | //#endregion
12 |
13 | //#region key lists
14 | export type SshKeyListState =
15 | | SshKeyListStateLoading
16 | | SshKeyListStateLoadedAndUnlinked
17 | | SshKeyListStateLoadedAndLinked
18 | | SshKeyListStateError;
19 |
20 | // when exchange with API is occurring = loading SSH keys
21 | // - is the initial state
22 | interface SshKeyListStateLoading {
23 | type: 'loading';
24 | }
25 |
26 | // when ready to receive user inputs (personal keys only)
27 | interface SshKeyListStateLoadedAndUnlinked {
28 | type: 'loaded';
29 | isGithubLinked: false;
30 | personalKeys: SshKeyState[];
31 | }
32 |
33 | // when ready to receive user inputs (personal keys & GitHub keys)
34 | interface SshKeyListStateLoadedAndLinked {
35 | type: 'loaded';
36 | isGithubLinked: true;
37 | personalKeys: SshKeyState[];
38 | githubKeys: GithubSshKeyState[];
39 | }
40 |
41 | // when an error has occurred
42 | interface SshKeyListStateError {
43 | type: 'error';
44 | }
45 | //#endregion
46 |
47 | //#region common
48 |
49 | // SshKey
50 | export interface SshKey {
51 | name: string;
52 | fingerprint: string;
53 | }
54 | interface SshKeyState extends SshKey {
55 | type: 'idle' | 'deleting';
56 | }
57 |
58 | export interface GithubSshKey extends SshKey {
59 | key: string;
60 | }
61 | interface GithubSshKeyState extends GithubSshKey {
62 | type: 'idle' | 'importing';
63 | }
64 | //#endregion
65 |
--------------------------------------------------------------------------------
/src/components/cc-tcp-redirection-form/cc-tcp-redirection-form.types.d.ts:
--------------------------------------------------------------------------------
1 | import {
2 | TcpRedirectionStateLoaded,
3 | TcpRedirectionStateWaiting,
4 | } from '../cc-tcp-redirection/cc-tcp-redirection.types.js';
5 |
6 | export type TcpRedirectionFormContextType = 'user' | 'admin';
7 |
8 | export type TcpRedirectionFormState =
9 | | TcpRedirectionFormStateLoading
10 | | TcpRedirectionFormStateLoaded
11 | | TcpRedirectionFormStateError;
12 |
13 | export interface TcpRedirectionFormStateLoading {
14 | type: 'loading';
15 | }
16 |
17 | export interface TcpRedirectionFormStateLoaded {
18 | type: 'loaded';
19 | redirections: Array;
20 | }
21 |
22 | export interface TcpRedirectionFormStateError {
23 | type: 'error';
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/cc-tcp-redirection/cc-tcp-redirection.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-tcp-redirection.types.js').CreateTcpRedirection} CreateTcpRedirection
5 | * @typedef {import('./cc-tcp-redirection.types.js').DeleteTcpRedirection} DeleteTcpRedirection
6 | */
7 |
8 | /**
9 | * Dispatched when a tcp redirection creation is requested.
10 | * @extends {CcEvent}
11 | */
12 | export class CcTcpRedirectionCreateEvent extends CcEvent {
13 | static TYPE = 'cc-tcp-redirection-create';
14 |
15 | /**
16 | * @param {CreateTcpRedirection} detail
17 | */
18 | constructor(detail) {
19 | super(CcTcpRedirectionCreateEvent.TYPE, detail);
20 | }
21 | }
22 |
23 | /**
24 | * Dispatched when a tcp redirection deletion is requested.
25 | * @extends {CcEvent}
26 | */
27 | export class CcTcpRedirectionDeleteEvent extends CcEvent {
28 | static TYPE = 'cc-tcp-redirection-delete';
29 |
30 | /**
31 | * @param {DeleteTcpRedirection} detail
32 | */
33 | constructor(detail) {
34 | super(CcTcpRedirectionDeleteEvent.TYPE, detail);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/cc-tcp-redirection/cc-tcp-redirection.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface TcpRedirection {
2 | namespace: string;
3 | isPrivate: boolean;
4 | sourcePort?: number | null;
5 | }
6 |
7 | export type TcpRedirectionState = TcpRedirectionStateLoading | TcpRedirectionStateLoaded | TcpRedirectionStateWaiting;
8 |
9 | export interface TcpRedirectionStateLoading {
10 | type: 'loading';
11 | }
12 |
13 | export interface TcpRedirectionStateLoaded extends TcpRedirection {
14 | type: 'loaded';
15 | }
16 |
17 | export interface TcpRedirectionStateWaiting extends TcpRedirection {
18 | type: 'waiting';
19 | }
20 |
21 | export interface CreateTcpRedirection {
22 | namespace: string;
23 | }
24 |
25 | export interface DeleteTcpRedirection {
26 | namespace: string;
27 | sourcePort: number;
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/cc-tile-deployments/cc-tile-deployments.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TileDeploymentsState = TileDeploymentsStateLoading | TileDeploymentsStateLoaded | TileDeploymentsStateError;
2 |
3 | interface TileDeploymentsStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | interface TileDeploymentsStateLoaded {
8 | type: 'loaded';
9 | deploymentsInfo: Array;
10 | }
11 |
12 | interface TileDeploymentsStateError {
13 | type: 'error';
14 | }
15 |
16 | export interface DeploymentTileInfo {
17 | state: string;
18 | action: string;
19 | date: string;
20 | logsUrl: string;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/cc-tile-instances/cc-tile-instances.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TileInstancesState = TileInstancesStateLoading | TileInstancesStateLoaded | TileInstancesStateError;
2 |
3 | export interface TileInstancesStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | export interface TileInstancesStateLoaded {
8 | type: 'loaded';
9 | running: Array;
10 | deploying: Array;
11 | }
12 |
13 | export interface TileInstancesStateError {
14 | type: 'error';
15 | }
16 |
17 | export interface InstanceState {
18 | flavorName: string;
19 | count: number;
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-tile-metrics/cc-tile-metrics.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TileMetricsMetricsState =
2 | | TileMetricsMetricsStateLoading
3 | | TileMetricsMetricsStateError
4 | | TileMetricsMetricsStateLoaded
5 | | TileMetricsMetricsStateEmpty;
6 |
7 | export interface TileMetricsMetricsStateLoaded {
8 | type: 'loaded';
9 | metricsData: MetricsData;
10 | }
11 |
12 | export interface TileMetricsMetricsStateLoading {
13 | type: 'loading';
14 | }
15 |
16 | export interface TileMetricsMetricsStateError {
17 | type: 'error';
18 | }
19 |
20 | export interface TileMetricsMetricsStateEmpty {
21 | type: 'empty';
22 | }
23 |
24 | export interface Metric {
25 | // Timestamp in ms
26 | timestamp: number;
27 | // Value is a percentage (e.g: 14.02)
28 | value: number;
29 | }
30 |
31 | export interface MetricsData {
32 | cpuMetrics: Metric[];
33 | memMetrics: Metric[];
34 | }
35 |
36 | export type TileMetricsGrafanaLinkState =
37 | | TileMetricsGrafanaLinkStateLoaded
38 | | TileMetricsGrafanaLinkStateLoading
39 | | TileMetricsGrafanaLinkStateHidden;
40 |
41 | export interface TileMetricsGrafanaLinkStateLoaded {
42 | type: 'loaded';
43 | link: string;
44 | }
45 |
46 | export interface TileMetricsGrafanaLinkStateLoading {
47 | type: 'loading';
48 | }
49 |
50 | export interface TileMetricsGrafanaLinkStateHidden {
51 | type: 'hidden';
52 | }
53 |
54 | // this is what we retrieve directly from the API
55 | export interface RawMetric {
56 | data: { timestamp: number; value: string }[];
57 | name: 'mem' | 'cpu';
58 | resource: string;
59 | unit: string;
60 | }
61 |
--------------------------------------------------------------------------------
/src/components/cc-tile-requests/cc-tile-requests.types.d.ts:
--------------------------------------------------------------------------------
1 | export type RequestsData = [
2 | number, // Start timestamp in milliseconds. Expected to be rounded to the hour of its respective TZ.
3 | number, // End timestamp in milliseconds. Expected to be rounded to the hour of its respective TZ.
4 | number, // Number of request during this time window.
5 | ];
6 |
7 | export type TileRequestsState = TileRequestsStateLoaded | TileRequestsStateLoading | TileRequestsStateError;
8 |
9 | export interface TileRequestsStateLoaded {
10 | type: 'loaded';
11 | data: Array;
12 | }
13 |
14 | export interface TileRequestsStateLoading {
15 | type: 'loading';
16 | }
17 |
18 | export interface TileRequestsStateError {
19 | type: 'error';
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/cc-tile-scalability/cc-tile-scalability.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Scalability } from '../common.types.js';
2 |
3 | export type TileScalabilityState = TileScalabilityStateLoaded | TileScalabilityStateLoading | TileScalabilityStateError;
4 |
5 | export interface TileScalabilityStateLoaded extends Scalability {
6 | type: 'loaded';
7 | }
8 |
9 | export interface TileScalabilityStateLoading {
10 | type: 'loading';
11 | }
12 |
13 | export interface TileScalabilityStateError {
14 | type: 'error';
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/cc-toast/cc-toast.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * Dispatched when a toast is dismissed.
5 | * @extends {CcEvent}
6 | */
7 | export class CcToastDismissEvent extends CcEvent {
8 | static TYPE = 'cc-toast-dismiss';
9 |
10 | constructor() {
11 | super(CcToastDismissEvent.TYPE);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/cc-toaster/cc-toaster.types.d.ts:
--------------------------------------------------------------------------------
1 | import { NotificationIntent } from '../common.types.js';
2 |
3 | export type ToastPosition = 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right';
4 |
5 | export type ToastAnimation = 'fade' | 'slide' | 'fade-and-slide';
6 |
7 | export interface Notification {
8 | message: string;
9 | title?: string;
10 | intent: NotificationIntent;
11 | options?: ToastOptions;
12 | }
13 |
14 | export interface ToastOptions {
15 | timeout?: number;
16 | closeable?: boolean;
17 | showProgress?: boolean;
18 | }
19 |
20 | export interface Toast extends Notification {
21 | key: string;
22 | dismissing?: boolean;
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/cc-toggle/cc-toggle.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface Choice {
2 | label: string;
3 | image?: string; // Optional URL of an image
4 | value: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/cc-token-api-creation-form/cc-token-api-creation-form.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-token-api-creation-form.types.js').NewToken} NewToken
5 | */
6 |
7 | /**
8 | * Dispatched when a token creation is requested.
9 | * @extends {CcEvent}
10 | */
11 | export class CcTokenCreateEvent extends CcEvent {
12 | static TYPE = 'cc-token-create';
13 |
14 | /** @param {NewToken} detail */
15 | constructor(detail) {
16 | super(CcTokenCreateEvent.TYPE, detail);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/cc-token-api-list/cc-token-api-list.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TokenApiListState = TokenApiListStateLoading | TokenApiListStateError | TokenApiListStateLoaded;
2 |
3 | export interface TokenApiListStateLoading {
4 | type: 'loading';
5 | }
6 |
7 | export interface TokenApiListStateError {
8 | type: 'error';
9 | }
10 |
11 | export interface TokenApiListStateLoaded {
12 | type: 'loaded';
13 | apiTokens: ApiTokenState[];
14 | }
15 |
16 | export type ApiTokenState = ApiTokenStateIdle | ApiTokenStateRevoking;
17 |
18 | export interface ApiTokenStateIdle extends ApiToken {
19 | type: 'idle';
20 | }
21 |
22 | export interface ApiTokenStateRevoking extends ApiToken {
23 | type: 'revoking';
24 | }
25 |
26 | export interface ApiToken {
27 | id: string;
28 | creationDate: Date;
29 | expirationDate: Date;
30 | name: string;
31 | description?: string;
32 | isExpired: boolean;
33 | }
34 |
35 | export interface RawApiToken {
36 | apiTokenId: string;
37 | userId: string;
38 | creationDate: string; // ISO
39 | expirationDate: string; // ISO
40 | ip: string;
41 | name: string;
42 | description?: string;
43 | state: 'ACTIVE' | 'EXPIRED';
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/cc-token-api-update-form/cc-token-api-update-form.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../../lib/events.js';
2 |
3 | /**
4 | * @typedef {import('./cc-token-api-update-form.types.js').CcTokenChangePayload} CcTokenChangePayload
5 | */
6 |
7 | /**
8 | * Dispatched when the update token form is submitted
9 | * @extends {CcEvent}
10 | */
11 | export class CcTokenChangeEvent extends CcEvent {
12 | static TYPE = 'cc-token-change';
13 |
14 | /** @param {CcTokenChangePayload} detail */
15 | constructor(detail) {
16 | super(CcTokenChangeEvent.TYPE, detail);
17 | }
18 | }
19 |
20 | /**
21 | * Dispatched when the API token has been updated successfully
22 | * @extends {CcEvent}
23 | */
24 | export class CcTokenWasUpdatedEvent extends CcEvent {
25 | static TYPE = 'cc-token-was-updated';
26 |
27 | /** @param {string} detail */
28 | constructor(detail) {
29 | super(CcTokenWasUpdatedEvent.TYPE, detail);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/cc-token-api-update-form/cc-token-api-update-form.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TokenApiUpdateFormState =
2 | | TokenApiUpdateFormStateLoading
3 | | TokenApiUpdateFormStateError
4 | | TokenApiUpdateFormStateLoaded
5 | | TokenApiUpdateFormStateUpdating;
6 |
7 | export interface TokenApiUpdateFormStateLoading {
8 | type: 'loading';
9 | }
10 |
11 | export interface TokenApiUpdateFormStateError {
12 | type: 'error';
13 | }
14 |
15 | type FormValues = {
16 | name: string;
17 | description?: string;
18 | };
19 |
20 | export interface TokenApiUpdateFormStateLoaded {
21 | type: 'loaded';
22 | values: FormValues;
23 | }
24 |
25 | export interface TokenApiUpdateFormStateUpdating {
26 | type: 'updating';
27 | values: FormValues;
28 | }
29 |
30 | export type CcTokenChangePayload = Required;
31 |
--------------------------------------------------------------------------------
/src/components/cc-token-oauth-list/cc-token-oauth-list.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TokenOauthListState =
2 | | TokenOauthListStateLoaded
3 | | TokenOauthListStateLoading
4 | | TokenOauthListStateError
5 | | TokenOauthListStateRevokingAll;
6 |
7 | export interface TokenOauthListStateLoaded {
8 | type: 'loaded';
9 | oauthTokens: Array;
10 | }
11 |
12 | export interface TokenOauthListStateRevokingAll {
13 | type: 'revoking-all';
14 | oauthTokens: Array;
15 | }
16 |
17 | export interface TokenOauthListStateLoading {
18 | type: 'loading';
19 | }
20 |
21 | export interface TokenOauthListStateError {
22 | type: 'error';
23 | }
24 |
25 | export type OauthTokenState = OauthTokenStateIdle | OauthTokenStateRevoking;
26 |
27 | export interface OauthTokenStateIdle extends OauthToken {
28 | type: 'idle';
29 | }
30 |
31 | export interface OauthTokenStateRevoking extends OauthToken {
32 | type: 'revoking';
33 | }
34 |
35 | export interface OauthToken {
36 | id: string;
37 | consumerName: string;
38 | creationDate: Date;
39 | expirationDate: Date;
40 | lastUsedDate: Date;
41 | imageUrl: string;
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/cc-warning-payment/cc-warning-payment.types.d.ts:
--------------------------------------------------------------------------------
1 | export type PaymentWarningModeType = 'home' | 'overview' | 'billing';
2 |
3 | export interface PaymentMethodError {
4 | type: number;
5 | orgaName?: string;
6 | orgaBillingLink?: string;
7 | }
8 |
--------------------------------------------------------------------------------
/src/components/cc-zone-card/cc-zone-card.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface ZoneImage {
2 | url: string | URL;
3 | alt: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/cc-zone-input/cc-zone-input.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ZoneModeType, ZoneStateLoaded } from '../cc-zone/cc-zone.types.js';
2 | import { Point, Zone } from '../common.types.js';
3 |
4 | export type ZoneInputState = ZoneInputStateLoaded | ZoneInputStateLoading | ZoneInputStateError;
5 |
6 | export interface ZoneInputStateLoaded {
7 | type: 'loaded';
8 | zones: Zone[];
9 | }
10 |
11 | export interface ZoneInputStateLoading {
12 | type: 'loading';
13 | }
14 |
15 | export interface ZoneInputStateError {
16 | type: 'error';
17 | }
18 |
19 | // FIXME: the `Point` type has a different type for `marker` & `tooltip` properties
20 | // maybe we could add this as an alternative within the original `Point` interface?
21 | export interface ZoneInputPoint extends Omit {
22 | marker: { tag: 'cc-map-marker-server'; state: ZonePointMarkerState; keyboard: false };
23 | tooltip: { tag: 'cc-zone'; state: ZoneStateLoaded; mode: ZoneModeType };
24 | }
25 |
26 | export type ZonePointMarkerState = 'selected' | 'hovered' | 'default';
27 |
--------------------------------------------------------------------------------
/src/components/cc-zone-picker/cc-zone-picker.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ZoneImage } from '../cc-zone-card/cc-zone-card.types.js';
2 |
3 | export interface ZoneItem {
4 | code: string;
5 | country: string;
6 | countryCode: string;
7 | name: string;
8 | flagUrl: string;
9 | images: Array;
10 | disabled?: boolean;
11 | selected?: boolean;
12 | }
13 |
14 | export type ZonesSections = Array | [SingleZoneSection];
15 |
16 | export interface ZoneSection {
17 | title: string;
18 | zones: Array;
19 | }
20 |
21 | export interface SingleZoneSection {
22 | zones: Array;
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/cc-zone/cc-zone.types.d.ts:
--------------------------------------------------------------------------------
1 | import { Zone } from '../common.types.js';
2 |
3 | export type ZoneState = ZoneStateLoaded | ZoneStateLoading;
4 |
5 | export interface ZoneStateLoaded extends Zone {
6 | type: 'loaded';
7 | }
8 |
9 | export interface ZoneStateLoading {
10 | type: 'loading';
11 | }
12 |
13 | export type ZoneModeType = 'default' | 'small' | 'small-infra';
14 |
--------------------------------------------------------------------------------
/src/lib/animate.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @param {ShadowRoot} shadowRoot
4 | * @param {string} selector
5 | * @param {Array | PropertyIndexedKeyframes} keyframes
6 | * @param {number | KeyframeAnimationOptions} options
7 | */
8 | export function animate(shadowRoot, selector, keyframes, options) {
9 | Array.from(shadowRoot.querySelectorAll(selector)).forEach((element) => element.animate(keyframes, options));
10 | }
11 |
12 | export const QUICK_SHRINK = {
13 | keyframes: [{ transform: 'scale(1)' }, { transform: 'scale(0.9)' }, { transform: 'scale(1)' }],
14 | options: {
15 | duration: 200,
16 | easing: 'ease-in-out',
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/src/lib/ansi/ansi-palette-analyser.js:
--------------------------------------------------------------------------------
1 | import { getContrastRatio, hexToRgb, isDark } from '../color.js';
2 |
3 | /**
4 | * @typedef {import('./ansi.types.js').AnsiPalette} AnsiPalette
5 | * @typedef {keyof AnsiPalette} ColorsType
6 | */
7 |
8 | /** @type {Array} */
9 | const COLORS = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan'];
10 |
11 | /**
12 | * @param {AnsiPalette} palette
13 | */
14 | export function analyzePalette(palette) {
15 | const background = hexToRgb(palette.background);
16 | /** @type {Array} */
17 | const colorsToTest = getColorsToTest(isDark(background));
18 |
19 | const colorsCount = colorsToTest.length;
20 | let ratioSum = 0;
21 | let compliantCount = 0;
22 |
23 | /** @type {Partial>} */
24 | const contrasts = {};
25 |
26 | colorsToTest.forEach((colorName) => {
27 | const ratio = getContrastRatio(background, hexToRgb(palette[colorName]));
28 | const compliant = ratio >= 4.5;
29 | if (compliant) {
30 | compliantCount++;
31 | }
32 | ratioSum += ratio;
33 | contrasts[colorName] = { ratio, compliant };
34 | });
35 |
36 | return {
37 | totalColors: colorsCount,
38 | compliantColors: compliantCount,
39 | contrastAvg: ratioSum / colorsCount,
40 | contrasts,
41 | };
42 | }
43 |
44 | /**
45 | * @param {boolean} isDarkPalette
46 | * @return {Array}
47 | */
48 | function getColorsToTest(isDarkPalette) {
49 | const result = [...COLORS, isDarkPalette ? 'white' : 'black'];
50 |
51 | // @ts-ignore
52 | return [...result, ...result.map((c) => `bright-${c}`)];
53 | }
54 |
--------------------------------------------------------------------------------
/src/lib/ansi/ansi-palette-style.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('./ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /**
6 | * @param {AnsiPalette} palette - The palette
7 | * @return {string} - The CSS style corresponding to the given palette.
8 | */
9 | export function ansiPaletteStyle(palette) {
10 | return [
11 | ...Object.entries(palette).map(([colorName, color]) => `--cc-color-ansi-${colorName}: ${color}`),
12 | 'color: var(--cc-color-ansi-foreground)',
13 | 'background-color: var(--cc-color-ansi-background);',
14 | ].join(';');
15 | }
16 |
--------------------------------------------------------------------------------
/src/lib/ansi/ansi.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface AnsiPalette {
2 | foreground: string;
3 | background: string;
4 | 'background-hover': string;
5 | 'background-selected': string;
6 | black: string;
7 | red: string;
8 | green: string;
9 | yellow: string;
10 | blue: string;
11 | magenta: string;
12 | cyan: string;
13 | white: string;
14 | 'bright-black': string;
15 | 'bright-red': string;
16 | 'bright-green': string;
17 | 'bright-yellow': string;
18 | 'bright-blue': string;
19 | 'bright-magenta': string;
20 | 'bright-cyan': string;
21 | 'bright-white': string;
22 | }
23 |
24 | export interface AnsiPart {
25 | styles: Array;
26 | text: string;
27 | }
28 |
29 | export type ColorName = keyof AnsiPalette;
30 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/default.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#000000',
8 | background: '#FFFFFF',
9 | 'background-hover': '#F5F5F5',
10 | 'background-selected': '#EBEBEB',
11 | black: '#000000',
12 | red: '#990000',
13 | green: '#0C7814',
14 | yellow: '#6D6B12',
15 | blue: '#0000B2',
16 | magenta: '#B200B2',
17 | cyan: '#28757B',
18 | white: '#BFBFBF',
19 | 'bright-black': '#666666',
20 | 'bright-red': '#D60000',
21 | 'bright-green': '#00D900',
22 | 'bright-yellow': '#E5E500',
23 | 'bright-blue': '#0000FF',
24 | 'bright-magenta': '#E500E5',
25 | 'bright-cyan': '#00E5E5',
26 | 'bright-white': '#E5E5E5',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/everblush.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#DADADA',
8 | background: '#141B1E',
9 | 'background-hover': '#1E2528',
10 | 'background-selected': '#282F32',
11 | black: '#232A2D',
12 | red: '#E57474',
13 | green: '#8CCF7E',
14 | yellow: '#E5C76B',
15 | blue: '#67B0E8',
16 | magenta: '#C47FD5',
17 | cyan: '#6CBFBF',
18 | white: '#B3B9B8',
19 | 'bright-black': '#2D3437',
20 | 'bright-red': '#EF7E7E',
21 | 'bright-green': '#96D988',
22 | 'bright-yellow': '#F4D67A',
23 | 'bright-blue': '#71BAF2',
24 | 'bright-magenta': '#CE89DF',
25 | 'bright-cyan': '#67CBE7',
26 | 'bright-white': '#BDC3C2',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/hyoob.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#FFFFFF',
8 | background: '#000000',
9 | 'background-hover': '#1E1E1E',
10 | 'background-selected': '#2B2B2B',
11 | black: '#000000',
12 | red: '#FF4040',
13 | green: '#90AF7D',
14 | yellow: '#FFFF66',
15 | blue: '#9999FF',
16 | magenta: '#FF4BB9',
17 | cyan: '#3AEEE0',
18 | white: '#FFFFFF',
19 | 'bright-black': '#BBBBBB',
20 | 'bright-red': '#FF4040',
21 | 'bright-green': '#90AF7D',
22 | 'bright-yellow': '#FFFF66',
23 | 'bright-blue': '#9999FF',
24 | 'bright-magenta': '#FF4BB9',
25 | 'bright-cyan': '#3AEEE0',
26 | 'bright-white': '#FFFFFF',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/night-owl.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#D6DEEB',
8 | background: '#011627',
9 | 'background-hover': '#0B2031',
10 | 'background-selected': '#152A3B',
11 | black: '#011627',
12 | red: '#EF5350',
13 | green: '#22DA6E',
14 | yellow: '#ADDB67',
15 | blue: '#82AAFF',
16 | magenta: '#C792EA',
17 | cyan: '#21C7A8',
18 | white: '#FFFFFF',
19 | 'bright-black': '#575656',
20 | 'bright-red': '#EF5350',
21 | 'bright-green': '#22DA6E',
22 | 'bright-yellow': '#FFEB95',
23 | 'bright-blue': '#82AAFF',
24 | 'bright-magenta': '#C792EA',
25 | 'bright-cyan': '#7FDBCA',
26 | 'bright-white': '#FFFFFF',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/one-light.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#2A2B32',
8 | background: '#F8F8F8',
9 | 'background-hover': '#EEEEEE',
10 | 'background-selected': '#E4E4E4',
11 | black: '#000000',
12 | red: '#D13B38',
13 | green: '#3B813D',
14 | yellow: '#855504',
15 | blue: '#315EEE',
16 | magenta: '#930092',
17 | cyan: '#0E6FAD',
18 | white: '#8E8F96',
19 | 'bright-black': '#2A2B32',
20 | 'bright-red': '#D13B38',
21 | 'bright-green': '#3B813D',
22 | 'bright-yellow': '#855504',
23 | 'bright-blue': '#315EEE',
24 | 'bright-magenta': '#930092',
25 | 'bright-cyan': '#0E6FAD',
26 | 'bright-white': '#FFFEFE',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/ansi/palettes/tokyo-night-light.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../ansi.types.js').AnsiPalette} AnsiPalette
3 | */
4 |
5 | /** @type {AnsiPalette} */
6 | export default {
7 | foreground: '#565A6E',
8 | background: '#D5D6DB',
9 | 'background-hover': '#CBCCD1',
10 | 'background-selected': '#C1C2C7',
11 | black: '#0F0F14',
12 | red: '#8C4351',
13 | green: '#485E30',
14 | yellow: '#855215',
15 | blue: '#34548A',
16 | magenta: '#5A4A78',
17 | cyan: '#0F4B6E',
18 | white: '#343B58',
19 | 'bright-black': '#9699A3',
20 | 'bright-red': '#8C4351',
21 | 'bright-green': '#485E30',
22 | 'bright-yellow': '#855215',
23 | 'bright-blue': '#34548A',
24 | 'bright-magenta': '#5A4A78',
25 | 'bright-cyan': '#0F4B6E',
26 | 'bright-white': '#343B58',
27 | };
28 |
--------------------------------------------------------------------------------
/src/lib/color.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface RgbColor {
2 | r: number;
3 | g: number;
4 | b: number;
5 | }
6 |
7 | export interface HslColor {
8 | h: number;
9 | s: number;
10 | l: number;
11 | }
12 |
--------------------------------------------------------------------------------
/src/lib/css-custom-properties.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Get an object literally with CSS custom properties and their values
3 | * @param {HTMLElement} element
4 | * @returns {any}
5 | */
6 | export function getCssCustomProperties(element) {
7 | const styles = getComputedStyle(element);
8 | const entries = Object.values(styles)
9 | .filter((name) => name.startsWith('--'))
10 | .map((name) => [name, styles.getPropertyValue(name)]);
11 | return Object.fromEntries(entries);
12 | }
13 |
--------------------------------------------------------------------------------
/src/lib/date/date-range.types.d.ts:
--------------------------------------------------------------------------------
1 | export type DateRange = {
2 | since: string;
3 | until?: string;
4 | };
5 |
6 | export type RawDateRange = {
7 | since: Date;
8 | until?: Date;
9 | };
10 |
--------------------------------------------------------------------------------
/src/lib/date/date.types.d.ts:
--------------------------------------------------------------------------------
1 | export type Timezone = 'local' | 'UTC';
2 |
3 | export type DateFormat = 'datetime-iso' | 'datetime-short';
4 |
5 | export interface DateFormattedParts {
6 | date: string;
7 | separator: 'T' | ' ';
8 | time: string;
9 | millisecond?: string;
10 | timezone?: string;
11 | }
12 |
13 | export type DateFormattedPart = keyof DateFormattedParts;
14 |
15 | export interface DateParts {
16 | year: string;
17 | month: string;
18 | day: string;
19 | hour: string;
20 | minute: string;
21 | second: string;
22 | millisecond?: string;
23 | timezone?: string;
24 | }
25 |
26 | export type DatePart = keyof DateParts;
27 |
28 | export type DateField = 'Y' | 'M' | 'D' | 'H' | 'm' | 's' | 'S';
29 |
--------------------------------------------------------------------------------
/src/lib/dom.js:
--------------------------------------------------------------------------------
1 | const timeoutCache = new WeakMap();
2 |
3 | /**
4 | * @param {Element} parent
5 | * @param {Element} child
6 | */
7 | export function scrollChildIntoParent(parent, child) {
8 | const oldTimeoutId = timeoutCache.get(parent);
9 | clearTimeout(oldTimeoutId);
10 |
11 | const newTimeoutId = setTimeout(() => {
12 | if (child == null) {
13 | return;
14 | }
15 | doScrollChildIntoParent(parent, child);
16 | }, 200);
17 |
18 | timeoutCache.set(parent, newTimeoutId);
19 | }
20 |
21 | /**
22 | * @param {Element} parent
23 | * @param {Element} child
24 | */
25 | function doScrollChildIntoParent(parent, child) {
26 | // In our situation, we don't need to handle borders and paddings
27 | const parentRect = parent.getBoundingClientRect();
28 | const childRect = child.getBoundingClientRect();
29 |
30 | if (childRect.top < parentRect.top) {
31 | const top = childRect.top - parentRect.top;
32 | parent.scrollBy({ top, behavior: 'smooth' });
33 | } else if (childRect.bottom > parentRect.bottom && childRect.top > parentRect.top) {
34 | const top = childRect.bottom - parentRect.bottom;
35 | parent.scrollBy({ top, behavior: 'smooth' });
36 | }
37 | }
38 |
39 | /**
40 | * @param {HTMLElement} element
41 | * @param {string} clazz
42 | * @return {boolean}
43 | */
44 | export function hasClass(element, clazz) {
45 | return element.classList?.contains(clazz) ?? false;
46 | }
47 |
--------------------------------------------------------------------------------
/src/lib/events.types.d.ts:
--------------------------------------------------------------------------------
1 | export type EventWithTarget<
2 | T extends EventTarget = HTMLElement | SVGElement,
3 | U extends EventTarget = null | HTMLElement | SVGElement,
4 | > = GenericEventWithTarget;
5 |
6 | export type GenericEventWithTarget<
7 | E extends Event,
8 | T extends EventTarget = HTMLElement | SVGElement,
9 | U extends EventTarget = null | HTMLElement | SVGElement,
10 | > = E & {
11 | target: T;
12 | currentTarget: U;
13 | };
14 |
--------------------------------------------------------------------------------
/src/lib/fake-strings.js:
--------------------------------------------------------------------------------
1 | // It's more representative of a real sentence to use this than to try to generate something with spaces.
2 | const FAKE_STRING_BASE =
3 | '??? ??????????? ???? ?????? ??? ????????????? ????????? ?? ??????? ?? ????? ????????????? ?? ?????? ??? ?? ??????? ?? ????????? ?? ?????????? ?? ??????????? ????? ?????????? ?? ???? ???????????? ???? ????? ????????????????';
4 |
5 | /**
6 | * Creates a fake string of `charCount` characters
7 | *
8 | * @param {number} charCount
9 | * @return {string}
10 | */
11 | export function fakeString(charCount) {
12 | return FAKE_STRING_BASE.substring(0, charCount);
13 | }
14 |
--------------------------------------------------------------------------------
/src/lib/focus-helper.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {Element|ShadowRoot|Document} element The root element on which the querySelector is made (can be `null`)
3 | * @param {string} selector The query selector
4 | * @param {() => void} [orElse] The optional function to call when the result of the query selector is `null`
5 | */
6 | export function focusBySelector(element, selector, orElse = null) {
7 | /** @type {Element & { focus?: () => void}} */
8 | const elementToFocus = element?.querySelector(selector);
9 | if (typeof elementToFocus?.focus === 'function') {
10 | elementToFocus.focus();
11 | } else {
12 | orElse?.();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/lib/form/form-error-focus-controller.js:
--------------------------------------------------------------------------------
1 | import { focusFirstFormControlWithError } from './form-utils.js';
2 |
3 | /**
4 | * @typedef {import('lit').LitElement} LitElement
5 | * @typedef {import('lit/directives/ref.js').Ref} HTMLFormElementRef
6 | */
7 |
8 | /**
9 | * This reactive controller handles the focus after a form submission.
10 | * When there is an error, it waits for the next render and then focus the first form control with error.
11 | */
12 | export class FormErrorFocusController {
13 | /**
14 | *
15 | * @param {LitElement} host
16 | * @param {HTMLFormElementRef} formRef
17 | * @param {() => Object} getErrors
18 | */
19 | constructor(host, formRef, getErrors) {
20 | this._host = host;
21 | this._host.addController(this);
22 | this._formRef = formRef;
23 | this._getErrors = getErrors;
24 | }
25 |
26 | hostUpdated() {
27 | const errors = this._getErrors();
28 | if (errors != null && Object.values(errors).some((value) => value != null)) {
29 | this._host.updateComplete.then(() => {
30 | focusFirstFormControlWithError(this._formRef.value);
31 | });
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/lib/form/form.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from '../events.js';
2 |
3 | /**
4 | * @typedef {import('./form.types.js').FormValidity} FormValidity
5 | * @typedef {import('./form.types.js').FormDataMap} FormSubmittedData
6 | * @typedef {import('./validation.types.js').ErrorMessage} ErrorMessage
7 | */
8 |
9 | /**
10 | * Dispatched when a form is submitted with invalid state.
11 | * @extends {CcEvent}
12 | */
13 | export class CcFormInvalidEvent extends CcEvent {
14 | static TYPE = 'cc-form-invalid';
15 |
16 | /**
17 | * @param {FormValidity} detail
18 | */
19 | constructor(detail) {
20 | super(CcFormInvalidEvent.TYPE, detail);
21 | }
22 | }
23 |
24 | /**
25 | * Dispatched when a form is submitted with valid state.
26 | * @extends {CcEvent}
27 | */
28 | export class CcFormValidEvent extends CcEvent {
29 | static TYPE = 'cc-form-valid';
30 |
31 | /**
32 | * @param {FormSubmittedData} detail
33 | */
34 | constructor(detail) {
35 | super(CcFormValidEvent.TYPE, detail);
36 | }
37 | }
38 |
39 | /**
40 | * Dispatched when the `errorMessage` property of a form control element changes.
41 | * @extends {CcEvent}
42 | */
43 | export class CcErrorMessageChangeEvent extends CcEvent {
44 | static TYPE = 'cc-error-message-change';
45 |
46 | /**
47 | * @param {ErrorMessage|null} detail
48 | */
49 | constructor(detail) {
50 | super(CcErrorMessageChangeEvent.TYPE, detail);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/lib/form/form.types.d.ts:
--------------------------------------------------------------------------------
1 | import { EventWithTarget } from '../events.types.js';
2 | import { Validity } from './validation.types.js';
3 |
4 | export type FormControlData = null | File | string | FormData;
5 |
6 | export type FormDataMap = { [key: string]: FormControlData | Array };
7 |
8 | export interface FormControlElementLike {
9 | get willValidate(): boolean;
10 | checkValidity: () => boolean;
11 | get validationMessage(): string;
12 | }
13 |
14 | export type OnValidCallback = (formData: FormDataMap, formElement: HTMLFormElement) => void;
15 | export type OnInvalidCallback = (formValidity: FormValidity, formElement: HTMLFormElement) => void;
16 |
17 | export interface SubmitHandlerCallbacks {
18 | onValid?: OnValidCallback;
19 | onInvalid?: OnInvalidCallback;
20 | }
21 |
22 | export type HTMLFormElementEvent = EventWithTarget;
23 |
24 | export type FormValidity = Array;
25 |
26 | interface FormControlValidity {
27 | name: string;
28 | validity: Validity;
29 | }
30 |
--------------------------------------------------------------------------------
/src/lib/form/validation.types.d.ts:
--------------------------------------------------------------------------------
1 | export type Validity = ValidValidity | InvalidValidity;
2 |
3 | export interface ValidValidity {
4 | valid: true;
5 | }
6 |
7 | export interface InvalidValidity {
8 | valid: false;
9 | code: string;
10 | }
11 |
12 | export interface Validator {
13 | validate(value: any, formData?: Object): Validity;
14 | }
15 |
16 | export type ErrorMessage = null | string | Node;
17 |
18 | export type ErrorMessageMap = { [code: string]: ErrorMessage | (() => ErrorMessage) };
19 |
--------------------------------------------------------------------------------
/src/lib/i18n/i18n-display.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Get the translated name of a country using its code with a fallback
3 | *
4 | * @param {string} lang - BCP 47 language tag
5 | * @param {string} code - ISO 3166 Country code
6 | * @param {string} name - Country name (fallback)
7 | * @returns {string}
8 | */
9 | export function getCountryName(lang, code, name) {
10 | // try/catch with fallback on english name because the support is not great for now
11 | // https://caniuse.com/mdn-javascript_builtins_intl_displaynames_of
12 | try {
13 | // This API was not really designed for this but...
14 | return new Intl.DisplayNames([lang], { type: 'region' }).of(code.toUpperCase());
15 | } catch {
16 | return name;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/lib/i18n/i18n-string.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Prepares a plural() function for a given lang
3 | *
4 | * @param {string} lang - BCP 47 language tag
5 | * @returns {(number: number, one: string, other?: string) => string}
6 | */
7 | export function preparePlural(lang) {
8 | const pr = new Intl.PluralRules(lang);
9 |
10 | /**
11 | * Based on https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules
12 | *
13 | * @param {number} number - The number to get a plural rule for.
14 | * @param {string} one - The singular form of the string.
15 | * @param {string} [other] - The plural form of the string (optional with automatic "s" suffix).
16 | * @returns {string}
17 | */
18 | return function plural(number, one, other = one + 's') {
19 | const rules = { zero: one, one, two: other, few: other, many: other, other };
20 | return rules[pr.select(number)];
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/lib/i18n/i18n.types.d.ts:
--------------------------------------------------------------------------------
1 | export type TranslationsMap = { [lang: string]: Translations };
2 |
3 | export type Translations = { [key: string]: Translation };
4 |
5 | export type Translation = string | TranslateFunction;
6 |
7 | export type TranslateFunction = (data: any) => Translated;
8 |
9 | export type Translated = string | Node;
10 |
11 | export type DateInput = number | string | Date;
12 |
13 | export type DateFormatter = (dateInput: DateInput) => string;
14 |
15 | export type DateUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
16 |
17 | export type RelativeTimeFormatFunction = (value: number, unit: DateUnit) => string;
18 |
19 | export type NumberFormatter = (number: number) => string;
20 |
--------------------------------------------------------------------------------
/src/lib/immer.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 |
3 | // immer uses a non-standard global property from Node.js "process"
4 | window.process = {
5 | env: {
6 | NODE_ENV: 'production',
7 | },
8 | };
9 |
10 | export { produce } from 'immer/dist/immer.esm.js';
11 | // TODO: object freeze
12 |
--------------------------------------------------------------------------------
/src/lib/leaflet/leaflet-esm.js:
--------------------------------------------------------------------------------
1 | // @ts-no-check
2 | /*
3 |
4 | We want to use the ESM version of Leaflet so we can treeshake what we don't use.
5 | When we tried that, we discovered that some parts of the code we need were removed by the treeshaking process.
6 |
7 | We did a lot of experiments and we discovered that some modules inside Leaflet have side effects.
8 |
9 | Take a look at `node_modules/leaflet/src/layer/Tooltip.js` for example.
10 | You will notice that this module exports the `Tooltip` class and the `tooltip` function.
11 | But below that, there are a few calls that have side effects.
12 | Calling `SomeClass.include()` actually patch `SomeClass` to add new methods.
13 | This is described in `node_modules/leaflet/src/core/Class.js`.
14 | The class `Class` has other methods like this one that will patch the original class.
15 |
16 | In our use case, it seems like we're missing:
17 |
18 | * zoom controls
19 | * tooltips
20 | * the `getRenderer` function but we're not sure why
21 |
22 | This is why we import them explicitly here.
23 | This is also why we have special rules in `rollup/rollup-common.js` at `treeshakeOptions` for those files.
24 |
25 | */
26 |
27 | import 'leaflet/src/control/index.js';
28 | import 'leaflet/src/layer/Tooltip.js';
29 | import 'leaflet/src/layer/vector/Renderer.getRenderer.js';
30 |
31 | export * from 'leaflet/src/Leaflet.js';
32 | export { HeatLayer } from './leaflet-heat.js';
33 |
--------------------------------------------------------------------------------
/src/lib/leaflet/tsconfig-empty.json:
--------------------------------------------------------------------------------
1 | // prevents esbuild from bundling types instead of the actual package
2 | // because of the `paths` option within the regular `tsconfig.json` file
3 | {}
4 |
--------------------------------------------------------------------------------
/src/lib/notifications.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from './events.js';
2 |
3 | /**
4 | * @typedef {import('../components/common.types.js').Notification} Notification
5 | */
6 |
7 | /**
8 | * Dispatched when a notification message is raised.
9 | * @extends {CcEvent}
10 | */
11 | export class CcNotifyEvent extends CcEvent {
12 | static TYPE = 'cc-notify';
13 |
14 | /**
15 | * @param {Notification} detail
16 | */
17 | constructor(detail) {
18 | super(CcNotifyEvent.TYPE, detail);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/lib/notifications.js:
--------------------------------------------------------------------------------
1 | import { CcNotifyEvent } from './notifications.events.js';
2 |
3 | /**
4 | * @typedef {import('../components/common.types.js').Notification} Notification
5 | */
6 |
7 | /**
8 | * @param {Notification} notification
9 | * @param {Window|Node} target
10 | */
11 | export function notify(notification, target = window) {
12 | target.dispatchEvent(new CcNotifyEvent(notification));
13 | }
14 |
15 | /**
16 | * @param {string|Node} message
17 | * @param {string} [title]
18 | */
19 | export function notifyError(message, title) {
20 | notify({
21 | message,
22 | title,
23 | intent: 'danger',
24 | });
25 | }
26 |
27 | /**
28 | * @param {string|Node} message
29 | * @param {string} [title]
30 | */
31 | export function notifySuccess(message, title) {
32 | notify({
33 | message,
34 | title,
35 | intent: 'success',
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/src/lib/pricing.types.d.ts:
--------------------------------------------------------------------------------
1 | import { PricingSection } from 'src/components/common.types.js';
2 |
3 | export type PricingSimulatorState = Partial<{
4 | [key in PricingSection['type']]: Omit & { quantity: number };
5 | }>;
6 |
--------------------------------------------------------------------------------
/src/lib/regex-parse.js:
--------------------------------------------------------------------------------
1 | const VALID_FLAGS = 'dgimsuy';
2 | const REGEX_WITH_TRAILING_SLASH = /\/(?.+)\/(?[a-z]*)/i;
3 |
4 | /**
5 | * @param {string} input
6 | * @return {RegExp}
7 | */
8 | export function parseRegex(input) {
9 | if (input.startsWith('/')) {
10 | const m = input.match(REGEX_WITH_TRAILING_SLASH);
11 |
12 | if (m == null) {
13 | throw new Error('invalid regular expression format');
14 | }
15 |
16 | const { expression, flags } = m.groups;
17 |
18 | const validFlags = Array.from(new Set(flags))
19 | .filter((flag) => VALID_FLAGS.includes(flag))
20 | .join('');
21 |
22 | return new RegExp(expression, validFlags);
23 | } else {
24 | return new RegExp(input);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/lib/remote-assets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string|null} countryCode
3 | * @return {string|null}
4 | */
5 | export function getFlagUrl(countryCode) {
6 | return countryCode != null ? `https://assets.clever-cloud.com/flags/${countryCode.toLowerCase()}.svg` : null;
7 | }
8 |
9 | /**
10 | * @param {string|null} providerSlug
11 | * @return {string|null}
12 | */
13 | export function getInfraProviderLogoUrl(providerSlug) {
14 | return providerSlug != null ? `https://assets.clever-cloud.com/infra/${providerSlug}.svg` : null;
15 | }
16 |
--------------------------------------------------------------------------------
/src/lib/send-to-api.events.js:
--------------------------------------------------------------------------------
1 | import { CcEvent } from './events.js';
2 |
3 | /**
4 | * Dispatched when an API request failed.
5 | * @extends {CcEvent}
6 | */
7 | export class CcApiErrorEvent extends CcEvent {
8 | static TYPE = 'cc-api-error';
9 |
10 | /**
11 | * @param {any} detail
12 | */
13 | constructor(detail) {
14 | super(CcApiErrorEvent.TYPE, detail);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/lib/send-to-api.types.d.ts:
--------------------------------------------------------------------------------
1 | export interface ApiConfig {
2 | API_HOST: string;
3 | API_OAUTH_TOKEN: string;
4 | API_OAUTH_TOKEN_SECRET: string;
5 | OAUTH_CONSUMER_KEY: string;
6 | OAUTH_CONSUMER_SECRET: string;
7 | }
8 |
9 | export interface Warp10ApiConfig {
10 | WARP_10_HOST: string;
11 | API_OAUTH_TOKEN: string;
12 | API_OAUTH_TOKEN_SECRET: string;
13 | OAUTH_CONSUMER_KEY: string;
14 | OAUTH_CONSUMER_SECRET: string;
15 | }
16 |
17 | export interface AuthBridgeConfig {
18 | AUTH_BRIDGE_HOST: string;
19 | API_OAUTH_TOKEN: string;
20 | API_OAUTH_TOKEN_SECRET: string;
21 | OAUTH_CONSUMER_KEY: string;
22 | OAUTH_CONSUMER_SECRET: string;
23 | }
24 |
--------------------------------------------------------------------------------
/src/lib/smart/smart-symbols.js:
--------------------------------------------------------------------------------
1 | export const COMPONENTS = Symbol('COMPONENTS');
2 | export const CURRENT_CONTEXT = Symbol('CURRENT_CONTEXT');
3 | export const LAST_CONTEXT = Symbol('LAST_CONTEXT');
4 | export const META = Symbol('META');
5 |
--------------------------------------------------------------------------------
/src/lib/tokens.types.d.ts:
--------------------------------------------------------------------------------
1 | export type ExpirationWarningThresholds = Array<{
2 | /** Number of days representing the maximum lifetime for which the given threshold is applicable */
3 | maxApplicableTokenLifetimeInDays: number;
4 | /** Number of days below which the token is considered close to expiration (must be lower than maxApplicableTokenLifetimeInDays) */
5 | warningThresholdInDays: number;
6 | }>;
7 |
--------------------------------------------------------------------------------
/src/lib/zone.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {import('../components/common.types.js').Zone} Zone
3 | */
4 |
5 | const CLEVER_CLOUD_ZONE = 'infra:clever-cloud';
6 | export const PRIVATE_ZONE = 'scope:private';
7 |
8 | /**
9 | * Sort zones as follows:
10 | * 1. Clever Cloud zones "infra:clever-cloud"
11 | * 2. Private zones "scope:private"
12 | * 3. Alphanum sort on city
13 | *
14 | * @template {Zone} T
15 | * @param {T[]} rawZones
16 | * @returns {T[]}
17 | */
18 | export function sortZones(rawZones) {
19 | if (rawZones == null) {
20 | return null;
21 | }
22 | return [...rawZones].sort((a, b) => {
23 | if (a == null || b == null) {
24 | return 0;
25 | }
26 | const aIsCleverCloud = a.tags.includes(CLEVER_CLOUD_ZONE);
27 | const bIsCleverCloud = b.tags.includes(CLEVER_CLOUD_ZONE);
28 | if (aIsCleverCloud !== bIsCleverCloud) {
29 | return aIsCleverCloud ? -1 : 1;
30 | }
31 | const aIsPrivate = a.tags.includes(PRIVATE_ZONE);
32 | const bIsPrivate = b.tags.includes(PRIVATE_ZONE);
33 | if (aIsCleverCloud && bIsCleverCloud) {
34 | if (aIsPrivate !== bIsPrivate) {
35 | return aIsPrivate ? 1 : -1;
36 | }
37 | if (aIsPrivate && bIsPrivate) {
38 | return (a.displayName ?? '').localeCompare(b.displayName ?? '');
39 | }
40 | }
41 | if (aIsPrivate !== bIsPrivate) {
42 | return aIsPrivate ? -1 : 1;
43 | }
44 | return a.city.localeCompare(b.city);
45 | });
46 | }
47 |
--------------------------------------------------------------------------------
/src/stories/assets/center.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverCloud/clever-components/d26069222d113921ee49ad1fa31e0bfdeedaea02/src/stories/assets/console.png
--------------------------------------------------------------------------------
/src/stories/assets/italic.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/justify.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/left.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/oracle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/ovh.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/right.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/scaleway.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/underline.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/stories/assets/warning.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/stories/fixtures/fake-map-data.js:
--------------------------------------------------------------------------------
1 | import fakePointsDataBig from './country-city-points-big-orga.js';
2 | import fakePointsDataMedium from './country-city-points-medium-orga.js';
3 | import fakePointsDataNormal from './country-city-points-normal-orga.js';
4 |
5 | const FAKE_POINTS_DATA = [
6 | fakePointsDataNormal,
7 | fakePointsDataMedium,
8 | fakePointsDataBig,
9 | ];
10 |
11 | let lastSampleIndex;
12 | let fakeDataIndex = 0;
13 |
14 | export function getFakePointsData (sampleIndex) {
15 | if (sampleIndex !== lastSampleIndex) {
16 | fakeDataIndex = 0;
17 | lastSampleIndex = sampleIndex;
18 | }
19 | const data = Promise.resolve(FAKE_POINTS_DATA[sampleIndex][fakeDataIndex]);
20 | fakeDataIndex = (fakeDataIndex + 1) % FAKE_POINTS_DATA[sampleIndex].length;
21 | return data;
22 | }
23 |
--------------------------------------------------------------------------------
/src/stories/lib/autodocs-template.jsx:
--------------------------------------------------------------------------------
1 | // we disable this rule because this file is only meant to be processed by Storybook. It is not part of our npm / CDN bundle.
2 | // eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars
3 | import { Controls, Description, Subtitle, Title } from '@storybook/blocks';
4 | // eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars
5 | import React from 'react';
6 |
7 | export function AutodocsTemplate() {
8 | return (
9 | <>
10 |
11 |
12 |
13 |
14 | >
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/src/stories/lib/dom.js:
--------------------------------------------------------------------------------
1 | export function createContainer(elements) {
2 | const frag = document.createDocumentFragment();
3 | elements.forEach((el) => {
4 | if (typeof el === 'string') {
5 | const title = document.createElement('div');
6 | title.classList.add('title');
7 | title.innerHTML = el;
8 | frag.appendChild(title);
9 | } else {
10 | frag.appendChild(el);
11 | }
12 | });
13 | return frag;
14 | }
15 |
--------------------------------------------------------------------------------
/src/stories/lib/i18n-control.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_GLOBALS } from '@storybook/core-events';
2 | import { addons } from '@storybook/preview-api';
3 | import { addTranslations, getLanguage, setLanguage } from '../../lib/i18n/i18n.js';
4 | import * as en from '../../translations/translations.en.js';
5 | import * as fr from '../../translations/translations.fr.js';
6 |
7 | const availableLanguages = [
8 | { value: 'en', title: 'English' },
9 | { value: 'fr', title: 'Français' },
10 | { value: 'missing', title: '🤬 Missing' },
11 | ];
12 |
13 | // Init languages
14 | addTranslations(en.lang, en.translations);
15 | addTranslations(fr.lang, fr.translations);
16 |
17 | const INIT_LANG = window.localStorage.getItem('I18N_LANG') ?? 'en';
18 |
19 | // Default to English
20 | setLanguage(INIT_LANG);
21 |
22 | const ALL_LANGS = availableLanguages.map((o) => o.value);
23 |
24 | window.addEventListener('keypress', ({ key, altKey, ctrlKey, metaKey, shiftKey }) => {
25 | if (key === 'i' && !altKey && !ctrlKey && !metaKey && !shiftKey) {
26 | const langIdx = ALL_LANGS.indexOf(getLanguage());
27 | const nextIdx = (langIdx + 1) % ALL_LANGS.length;
28 | const nextLang = ALL_LANGS[nextIdx];
29 | addons.getChannel().emit(UPDATE_GLOBALS, { globals: { locale: nextLang } });
30 | }
31 | });
32 |
--------------------------------------------------------------------------------
/src/stories/lib/markdown-docs.jsx:
--------------------------------------------------------------------------------
1 | // we disable this rule because this file is only meant to be processed by Storybook. It is not part of our npm / CDN bundle.
2 | // eslint-disable-next-line import/no-extraneous-dependencies, no-unused-vars
3 | import React from 'react';
4 | // several docs rely on `cc-notice`
5 | import '../../components/cc-notice/cc-notice.js';
6 |
7 | export function MarkdownDocs({ html }) {
8 | const htmlContent = { __html: html };
9 |
10 | return ;
11 | }
12 |
--------------------------------------------------------------------------------
/src/stories/lib/markdown-indexer.js:
--------------------------------------------------------------------------------
1 | import { readFile } from 'fs/promises';
2 | import { getMetaDataFromMd } from './markdown-to-csf.js';
3 |
4 | /** @type {import('storybook/internal/types').Indexer} */
5 | export const markdownIndexer = {
6 | test: /.md$/,
7 | createIndex: async (fileName, { makeTitle }) => {
8 | const markdownContent = await readFile(fileName, { encoding: 'utf-8' });
9 |
10 | const { title, subtitle } = getMetaDataFromMd(markdownContent);
11 |
12 | /** @type {import('storybook/internal/types').IndexInput} */
13 | const indexInput = {
14 | type: 'docs',
15 | importPath: fileName,
16 | // we tell storybook to import a story named "docs" so that it is considered as
17 | // a "docs only" story. This solution is unofficial / undocumented.
18 | exportName: 'docs',
19 | title: makeTitle(title),
20 | name: subtitle,
21 | /**
22 | * This makes storybook think an auto generated doc will be associated to this story.
23 | * Usually this tag is to be added within the default export of a CSF file.
24 | * The default export would then be processed by `csfIndexers` and added to the
25 | * index input, here.
26 | * Since CSF files for markdown files are actually generated on the fly (virtual files),
27 | * we hard code the tag here and we don't need to set `tags: ['autodocs']` within the virtual file.
28 | * We override the autogenerated docs page with our own doc generated from our markdown file
29 | * (see `/src/stories/lib/markdown-to-csf.js`).
30 | */
31 | tags: ['autodocs'],
32 | };
33 |
34 | return [indexInput];
35 | },
36 | };
37 |
--------------------------------------------------------------------------------
/src/stories/lib/sequence.js:
--------------------------------------------------------------------------------
1 | function wait(delay) {
2 | return new Promise((resolve) => {
3 | setTimeout(resolve, delay);
4 | });
5 | }
6 |
7 | export function sequence(callback) {
8 | setTimeout(() => callback(wait), 50);
9 | }
10 |
--------------------------------------------------------------------------------
/src/stories/lib/timers.js:
--------------------------------------------------------------------------------
1 | export function setTimeoutDom(fn, delay, domNode) {
2 | const id = setTimeout(() => {
3 | if (domNode.parentNode == null) {
4 | clearTimeout(id);
5 | } else {
6 | fn();
7 | }
8 | }, delay);
9 | return id;
10 | }
11 |
12 | export function setIntervalDom(fn, delay, domNode) {
13 | const id = setInterval(() => {
14 | if (domNode.parentNode == null) {
15 | clearInterval(id);
16 | } else {
17 | fn();
18 | }
19 | }, delay);
20 | return id;
21 | }
22 |
--------------------------------------------------------------------------------
/src/styles/accessibility.js:
--------------------------------------------------------------------------------
1 | import { css } from 'lit';
2 |
3 | // language=CSS
4 | export const accessibilityStyles = css`
5 | .visually-hidden {
6 | clip: rect(0 0 0 0);
7 | clip-path: inset(50%);
8 | height: 1px;
9 | overflow: hidden;
10 | position: absolute;
11 | white-space: nowrap;
12 | width: 1px;
13 | }
14 | `;
15 |
--------------------------------------------------------------------------------
/src/styles/cli-commands.js:
--------------------------------------------------------------------------------
1 | import { css } from 'lit';
2 |
3 | // language=CSS
4 | export const cliCommandsStyles = css`
5 | cc-block-details a {
6 | color: var(--cc-color-text-primary-highlight, blue);
7 | }
8 | cc-block-details p {
9 | margin: 0;
10 | }
11 | cc-block-details dt {
12 | font-weight: bold;
13 | margin: 1em 0 0.5em 0;
14 | }
15 | cc-block-details dd {
16 | margin: 0;
17 | }
18 | cc-block-details dl {
19 | margin: 0;
20 | }
21 | cc-block-details code {
22 | padding: 0.5em 1em;
23 | display: block;
24 | border: 1px solid #dcdcdc;
25 | background-color: var(--cc-color-bg-neutral);
26 | border-radius: var(--cc-border-radius-default, 0.25em);
27 | font-family: var(--cc-ff-monospace);
28 | }
29 | `;
30 |
--------------------------------------------------------------------------------
/src/styles/skeleton.js:
--------------------------------------------------------------------------------
1 | import { css } from 'lit';
2 |
3 | // language=CSS
4 | export const skeletonStyles = css`
5 | @keyframes skeleton-pulse {
6 | from {
7 | opacity: 0.85;
8 | }
9 |
10 | to {
11 | opacity: 0.45;
12 | }
13 | }
14 |
15 | .skeleton {
16 | animation-direction: alternate;
17 | animation-duration: 500ms;
18 | animation-iteration-count: infinite;
19 | animation-name: skeleton-pulse;
20 | animation-play-state: var(--cc-skeleton-state, running);
21 | color: transparent;
22 | cursor: progress;
23 | -moz-user-select: none;
24 | -webkit-user-select: none;
25 | -ms-user-select: none;
26 | user-select: none;
27 | }
28 | `;
29 |
--------------------------------------------------------------------------------
/src/styles/undefined-components.css:
--------------------------------------------------------------------------------
1 | /* This is a work in progress */
2 |
3 | cc-block:not(:defined) {
4 | border-radius: 0.25em;
5 | border: 1px solid #bcc2d1;
6 | display: grid;
7 | grid-gap: 1em;
8 | padding: 1em;
9 | }
10 |
11 | cc-block:not(:defined) > [slot='title'] {
12 | color: #3a3871;
13 | font-size: 1.2em;
14 | font-weight: 700;
15 | margin-bottom: 0.5em;
16 | }
17 |
18 | cc-block[icon]:not(:defined) > [slot='title'] {
19 | padding-left: 2.5em;
20 | }
21 |
22 | cc-input-text:not(:defined) {
23 | background: #eee;
24 | border-radius: 0.25em;
25 | display: inline-block;
26 | height: 2em;
27 | min-width: 18em;
28 | vertical-align: top;
29 | }
30 |
31 | cc-tcp-redirection-form:not(:defined) {
32 | background: #eee;
33 | border-radius: 0.25em;
34 | display: block;
35 | height: calc(3.8em - 2px);
36 | }
37 |
38 | cc-toggle:not(:defined) {
39 | background: #eee;
40 | border-radius: 0.15em;
41 | display: inline-block;
42 | height: 2em;
43 | min-width: 10em;
44 | vertical-align: top;
45 | }
46 |
47 | cc-toggle:not(:defined)::after {
48 | content: '\00a0';
49 | }
50 |
--------------------------------------------------------------------------------
/src/styles/waiting.js:
--------------------------------------------------------------------------------
1 | import { css } from 'lit';
2 |
3 | // language=CSS
4 | export const waitingStyles = css`
5 | @keyframes waiting {
6 | from {
7 | opacity: 0.85;
8 | }
9 |
10 | to {
11 | opacity: 1;
12 | }
13 | }
14 |
15 | .cc-waiting {
16 | animation-direction: alternate;
17 | animation-duration: 500ms;
18 | animation-iteration-count: infinite;
19 | animation-name: waiting;
20 | }
21 | `;
22 |
--------------------------------------------------------------------------------
/src/templates/cc-addon-encryption-at-rest-option/cc-addon-encryption-at-rest-option.js:
--------------------------------------------------------------------------------
1 | import { html } from 'lit';
2 | import { iconRemixShieldKeyholeFill as iconEncryptionAtRest } from '../../assets/cc-remix.icons.js';
3 | import '../../components/cc-icon/cc-icon.js';
4 | import { i18n } from '../../translations/translation.js';
5 |
6 | /**
7 | * @typedef {import('../../components/common.types.js').EncryptionAddonOption} EncryptionAddonOption
8 | * @typedef {import('../../components/common.types.js').AddonOptionWithMetadata} AddonOptionWithMetadata
9 | */
10 |
11 | /** @type {(option: EncryptionAddonOption) => AddonOptionWithMetadata & EncryptionAddonOption} */
12 | export const ccAddonEncryptionAtRestOption = ({ enabled }) => {
13 | const description = html`
14 | ${i18n('cc-addon-encryption-at-rest-option.description')}
15 | `;
16 |
17 | return {
18 | title: i18n('cc-addon-encryption-at-rest-option.title'),
19 | icon: iconEncryptionAtRest,
20 | description,
21 | enabled,
22 | name: 'encryption',
23 | };
24 | };
25 |
--------------------------------------------------------------------------------
/src/templates/cc-link/cc-link.md:
--------------------------------------------------------------------------------
1 | # `ccLink()` template and `linkStyles` CSS styles
2 |
3 | We want all the HTML links included in our components to look the same and have the same behaviour.
4 | Instead of creating a link component, we provide a helper function and some shared styles that any component can import and reuse.
5 |
6 | ## Features
7 |
8 | * Automatic attributes: `target="_blank"` and `rel="nopener noreferrer"` when target origin is different from current origin.
9 | * Default style with 6 color contrast ratio over a white background.
10 | * Hover style with pointer cursor (default) and slightly darker color (primary).
11 | * Focus styles with focus ring (and white background).
12 | * Works well with `.skeleton`.
13 |
14 | ## How to use it?
15 |
16 | In your component, import the template and styles like this:
17 |
18 | ```js
19 | import { ccLink, linkStyles } from 'src/templates/cc-link.js';
20 | ```
21 |
22 | When you need a link, use the `ccLink(url, content, skeleton)` function like this:
23 |
24 | ```html
25 |
26 | ${ccLink(null, 'My awesome link', true)}
27 |
28 | ```
29 |
30 | You also need to add the CSS styles in your LitElement `static get styles()` like this:
31 |
32 | ```js
33 | static get styles () {
34 | return [
35 | linkStyles,
36 | css`
37 | /* CSS for component goes here */
38 | `
39 | ]
40 | }
41 | ```
42 |
--------------------------------------------------------------------------------
/src/templates/cc-link/cc-link.stories.js:
--------------------------------------------------------------------------------
1 | import { render } from 'lit';
2 | import { makeStory } from '../../stories/lib/make-story.js';
3 | import { skeletonStyles } from '../../styles/skeleton.js';
4 | import { ccLink, linkStyles } from './cc-link.js';
5 | import docStoryModule from './cc-link.md';
6 |
7 | export default {
8 | title: '♻️ Templates/ccLink()',
9 | tags: ['autodocs'],
10 | parameters: {
11 | docs: docStoryModule.parameters.docs,
12 | },
13 | };
14 |
15 | const conf = {
16 | css: [linkStyles, skeletonStyles].join(''),
17 | };
18 |
19 | export const defaultStory = makeStory(conf, {
20 | dom: (container) => render(ccLink('https://example.com', 'This is an outside link using the link styles'), container),
21 | });
22 |
23 | export const innerLink = makeStory(conf, {
24 | dom: (container) => render(ccLink('/other-page', 'This is an inside link using the link styles'), container),
25 | });
26 |
27 | export const skeleton = makeStory(conf, {
28 | dom: (container) => render(ccLink('https://example.com', 'This is a link using the link styles', true), container),
29 | });
30 |
--------------------------------------------------------------------------------
/src/translations/translation.js:
--------------------------------------------------------------------------------
1 | import { i18n as i18nRaw } from '../lib/i18n/i18n.js';
2 |
3 | /**
4 | * @typedef {import('./translation.types.js').I18nFunction} I18nFunction
5 | */
6 |
7 | /** @type {I18nFunction} */
8 | export function i18n(key, data) {
9 | // @ts-ignore
10 | return i18nRaw(key, data);
11 | }
12 |
--------------------------------------------------------------------------------
/src/translations/translation.types.d.ts:
--------------------------------------------------------------------------------
1 | import { translations as enTranslations } from './translations.en.js';
2 | import { translations as frTranslations } from './translations.fr.js';
3 |
4 | type Translations = typeof frTranslations & typeof enTranslations;
5 | type TranslationKeys = keyof Translations;
6 | type ArrowFunction = (...args: any) => any;
7 |
8 | export type I18nFunction = (
9 | key: Key,
10 | // the rest of the arguments depends on the type of the TranslationPropertyValue which can be either a function or a string (see (i18n.types.d.ts).Translation)
11 | // if it's a string, we do not allow any arguments
12 | // if it's a function, we allow one argument with the same type as the one expected by the function
13 | ...args: TranslationPropertyValue extends ArrowFunction ? [Parameters[0]] : [undefined]
14 | ) => TranslationPropertyValue extends ArrowFunction ? ReturnType : TranslationPropertyValue;
15 |
--------------------------------------------------------------------------------
/tasks/cdn-entry-name.js:
--------------------------------------------------------------------------------
1 | import semver from 'semver';
2 |
3 | /**
4 | *
5 | * @param {CdnEnvironment} cdnEnvironment
6 | * @param {string} name
7 | * @return {string}
8 | */
9 | export function toCdnEntryName(cdnEnvironment, name) {
10 | if (name == null) {
11 | throw new Error('Invalid CDN entry name: It cannot be null.');
12 | }
13 |
14 | const result = name.trim();
15 |
16 | if (result.length === 0) {
17 | throw new Error('Invalid CDN entry name: It cannot be empty.');
18 | }
19 |
20 | if (cdnEnvironment.semver) {
21 | if (semver.valid(result) == null) {
22 | throw new Error(`Invalid CDN entry name '${result}': It must be a valid version.`);
23 | }
24 |
25 | return result;
26 | }
27 |
28 | return result.replaceAll('/', '-').replaceAll(' ', '-');
29 | }
30 |
--------------------------------------------------------------------------------
/test-mocha/cem/fixtures/cem-test-import/cc-test-imports-sub.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ToImport } from "../test-imports.types.js";
2 |
3 | export interface ToSubImport {
4 |
5 | }
6 |
7 | export interface ToSubImportBar {
8 |
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/test-mocha/cem/fixtures/common.types.d.ts:
--------------------------------------------------------------------------------
1 | interface Common {
2 | sub: SubCommon;
3 | }
4 |
5 | interface SubCommon {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/test-mocha/cem/fixtures/test-imports.types.d.ts:
--------------------------------------------------------------------------------
1 | import { ToSubImport, ToSubImportBar } from "./cem-test-import/cc-test-imports-sub.types.js";
2 |
3 | export interface ToImport {
4 |
5 | }
6 |
7 | export interface ImpExtendInterface {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/test/dom/dom.css:
--------------------------------------------------------------------------------
1 | .big {
2 | height: 5000px;
3 | }
4 |
5 | .container {
6 | height: 250px;
7 | overflow: auto;
8 | }
9 |
10 | .item {
11 | height: 100px;
12 | }
13 |
--------------------------------------------------------------------------------
/test/dom/dom.test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/test/helpers/mock-now.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} nowIsoString The fake now ISO string
3 | * @param {function} fn the function to execute
4 | */
5 | export function withMockedNow(nowIsoString, fn) {
6 | const realDate = window.Date;
7 | const fakeNow = new Date(nowIsoString).getTime();
8 | // @ts-ignore
9 | window.Date = class extends Date {
10 | static now() {
11 | return fakeNow;
12 | }
13 |
14 | // @ts-ignore
15 | constructor(...options) {
16 | if (options.length > 0) {
17 | // @ts-ignore
18 | super(...options);
19 | } else {
20 | super(fakeNow);
21 | }
22 | }
23 | };
24 | try {
25 | return fn();
26 | } finally {
27 | window.Date = realDate;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/helpers/test-stories.types.d.ts:
--------------------------------------------------------------------------------
1 | import type { AnnotatedStoryFn } from '@storybook/csf';
2 | import type { StoryObj, WebComponentsRenderer } from '@storybook/web-components';
3 |
4 | export type StoryParams = StoryObj['parameters'];
5 |
6 | export type AccessibilityTestOptions = {
7 | tests: {
8 | accessibility: {
9 | enable: boolean;
10 | ignoredRules: Array;
11 | };
12 | };
13 | };
14 |
15 | export type AnnotatedStoryFnClever = AnnotatedStoryFn & {
16 | parameters: StoryParams & AccessibilityTestOptions;
17 | };
18 |
19 | export type RawStoriesModule = {
20 | default: {
21 | component: keyof HTMLElementTagNameMap;
22 | };
23 | } & { [storyName: string]: AnnotatedStoryFnClever } & {};
24 |
25 | export type ArrayOfStoryFunctions = Array<{ storyName: string; storyFunction: AnnotatedStoryFnClever }>;
26 |
27 | export type ModuleEntryWithStoryFunction = [storyName: string, storyFunction: AnnotatedStoryFnClever];
28 |
--------------------------------------------------------------------------------
/test/i18n/i18n-string.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from '@bundled-es-modules/chai';
2 | import { preparePlural } from '../../src/lib/i18n/i18n-string.js';
3 |
4 | describe('preparePlural', () => {
5 | describe('english', () => {
6 | const plural = preparePlural('en');
7 |
8 | it('select correct rule', () => {
9 | expect(plural(0, 'mouse', 'mice')).to.equal('mice');
10 | expect(plural(1, 'mouse', 'mice')).to.equal('mouse');
11 | expect(plural(2, 'mouse', 'mice')).to.equal('mice');
12 | expect(plural(10, 'mouse', 'mice')).to.equal('mice');
13 | });
14 |
15 | it('automatic "s" suffix', () => {
16 | expect(plural(0, 'cat')).to.equal('cats');
17 | expect(plural(1, 'cat')).to.equal('cat');
18 | expect(plural(2, 'cat')).to.equal('cats');
19 | expect(plural(10, 'cat')).to.equal('cats');
20 | });
21 | });
22 |
23 | describe('french', () => {
24 | const plural = preparePlural('fr');
25 |
26 | it('select correct rule', () => {
27 | expect(plural(0, 'cheval', 'chevaux')).to.equal('cheval');
28 | expect(plural(1, 'cheval', 'chevaux')).to.equal('cheval');
29 | expect(plural(2, 'cheval', 'chevaux')).to.equal('chevaux');
30 | expect(plural(10, 'cheval', 'chevaux')).to.equal('chevaux');
31 | });
32 |
33 | it('automatic "s" suffix', () => {
34 | expect(plural(0, 'chat')).to.equal('chat');
35 | expect(plural(1, 'chat')).to.equal('chat');
36 | expect(plural(2, 'chat')).to.equal('chats');
37 | expect(plural(10, 'chat')).to.equal('chats');
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/smart/smart-manager.test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tsconfig.ci.json:
--------------------------------------------------------------------------------
1 | {
2 | // this file is used for typechecking in the CI context
3 | // as opposed to the `tsconfig.json` file used for typechecking within IDEs
4 | // Every file passing typechecking should be added in the `include` array below
5 | "include": [
6 | ".storybook/**/*.js",
7 | "src/lib/**/*.js",
8 | "src/components/**/*.js",
9 | "src/controllers/*.js",
10 | "src/templates/*.js",
11 | "src/translations/**/*.js",
12 | "tasks/typechecking-stats.js",
13 | "src/lib/events-map.types.d.ts"
14 | ],
15 | "exclude": ["src/controllers/*.stories.js", "src/components/**/*.test.js", "src/components/**/*.stories.js"],
16 | "extends": "./tsconfig.json",
17 | "compilerOptions": {
18 | // FIXME:
19 | // This means our `d.ts` files are not checked in CI context
20 | // This needs to be set to `true` at least until we can upgrade TypeScript
21 | // see https://github.com/CleverCloud/clever-components/issues/972
22 | "skipLibCheck": true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/wds/cem-analyzer-plugin.js:
--------------------------------------------------------------------------------
1 | import { cli } from '@custom-elements-manifest/analyzer/cli.js';
2 |
3 | const path = '/dist/custom-elements.json';
4 |
5 | // This plugin generates and serves the CEM on demand.
6 | export const cemAnalyzerPlugin = {
7 | name: 'cem-analyzer-plugin',
8 | // we disable transform cache to enforce generation for every call
9 | transform(context) {
10 | if (context.path === path) {
11 | return {
12 | transformCache: false,
13 | };
14 | }
15 | },
16 | async serve(context) {
17 | if (context.path === path) {
18 | const cemJson = await cli({
19 | argv: ['analyze'],
20 | noWrite: true,
21 | });
22 |
23 | return JSON.stringify(cemJson);
24 | }
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/wds/esbuild-bundle-plugin.js:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 |
3 | // /!\ This is an experimental plugin for now
4 | // We created this because some of our deps have way to many separated ES module files (Leaflet, chart.js...)
5 | export function esbuildBundlePlugin({ pathsToBundle }) {
6 | return {
7 | async transform(context) {
8 | if (pathsToBundle.includes(context.request.url)) {
9 | const bundle = esbuild.buildSync({
10 | entryPoints: [context.request.url.slice(1)],
11 | bundle: true,
12 | format: 'esm',
13 | minify: true,
14 | write: false,
15 | // prevents esbuild from bundling types instead of the actual package
16 | // because of the `paths` option within the regular `tsconfig.json` file
17 | tsconfig: 'src/lib/leaflet/tsconfig-empty.json',
18 | });
19 |
20 | const code = bundle.outputFiles[0].text;
21 |
22 | return code;
23 | }
24 | },
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/wds/test-stories-plugin.js:
--------------------------------------------------------------------------------
1 | export const testStoriesPlugin = {
2 | name: 'test-story',
3 | async transformImport({ source, context }) {
4 | // if `.stories.js` is imported by WTR itself, then we change it to import the test file
5 | if (context.request.url.startsWith('/?wtr-session-id=') && source.includes('.stories.js?wtr-session')) {
6 | return source.replace('.stories.js', '.stories.test.js');
7 | }
8 | },
9 | async serve(context) {
10 | // test files are generated on the fly and they import story modules
11 | if (context.path.endsWith('.stories.test.js')) {
12 | const testFileContent = `
13 | import { testStories } from '/test/helpers/test-stories.js';
14 | import * as storiesModule from '${context.path.replace('.stories.test.js', '.stories.js')}';
15 |
16 | testStories(storiesModule);
17 | `;
18 | return testFileContent;
19 | }
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/wds/wds-common.js:
--------------------------------------------------------------------------------
1 | import rollupCommonjs from '@rollup/plugin-commonjs';
2 | import { fromRollup } from '@web/dev-server-rollup';
3 | import { esbuildBundlePlugin } from './esbuild-bundle-plugin.js';
4 |
5 | const commonjs = fromRollup(rollupCommonjs);
6 |
7 | function commonJsIdentifiers(ids) {
8 | return ids.map((id) => `**/node_modules/${id}/**/*`);
9 | }
10 |
11 | // regroup ES module files into one bundle
12 | export const esbuildBundlePluginWithConfig = esbuildBundlePlugin({
13 | pathsToBundle: ['/src/lib/leaflet-esm.js', '/node_modules/chart.js/dist/chart.esm.js'],
14 | });
15 |
16 | // convert CommonJS modules to ES6 to be included in the rollup bundle
17 | export const commonjsPluginWithConfig = commonjs({
18 | // the commonjs plugin is slow, list the required packages explicitly:
19 | include: commonJsIdentifiers([
20 | 'statuses',
21 | // used by clever-client
22 | 'oauth-1.0a',
23 | 'component-emitter',
24 | ]),
25 | });
26 |
--------------------------------------------------------------------------------