* Integration page initial implementation * replace placeholder integrations * fix linting and tests * fix locales * update locale * Change logos, add link to SCIM page * refactor to standalone components, add integration filtering pipe * refactor modules and imports. Remove hyperlink text from integration card template * refactor i18n usage to be more generic * Add storybooks * fix tests * minify svgs, include spec files in TS config, fix stories * Update apps/web/src/locales/en/messages.json Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> * fix imports, add static dir for stories * Add darkmode svgs for integrations * hide nav link for non enterprise orgs * add router guard * change rxjs selector * Remove tailwind class causing style issues --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>pull/12261/head
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
<app-header> </app-header> |
||||
|
||||
<bit-tab-group [(selectedIndex)]="tabIndex"> |
||||
<bit-tab [label]="'singleSignOn' | i18n"> |
||||
<section class="tw-mb-9"> |
||||
<h2 bitTypography="h2">{{ "singleSignOn" | i18n }}</h2> |
||||
<p bitTypography="body1"> |
||||
{{ "ssoDescStart" | i18n }} |
||||
<a bitLink routerLink="../settings/sso" class="tw-lowercase">{{ "singleSignOn" | i18n }}</a> |
||||
{{ "ssoDescEnd" | i18n }} |
||||
</p> |
||||
<app-integration-grid |
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.SSO" |
||||
></app-integration-grid> |
||||
</section> |
||||
</bit-tab> |
||||
|
||||
<bit-tab [label]="'userProvisioning' | i18n"> |
||||
<section class="tw-mb-9"> |
||||
<h2 bitTypography="h2"> |
||||
{{ "scimIntegration" | i18n }} |
||||
</h2> |
||||
<p bitTypography="body1"> |
||||
{{ "scimIntegrationDescStart" | i18n }} |
||||
<a bitLink routerLink="../settings/scim">{{ "scimIntegration" | i18n }}</a> |
||||
{{ "scimIntegrationDescEnd" | i18n }} |
||||
</p> |
||||
<app-integration-grid |
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.SCIM" |
||||
></app-integration-grid> |
||||
</section> |
||||
<section class="tw-mb-9"> |
||||
<h2 bitTypography="h2"> |
||||
{{ "bwdc" | i18n }} |
||||
</h2> |
||||
<p bitTypography="body1">{{ "bwdcDesc" | i18n }}</p> |
||||
<app-integration-grid |
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.BWDC" |
||||
></app-integration-grid> |
||||
</section> |
||||
</bit-tab> |
||||
|
||||
<bit-tab [label]="'eventManagement' | i18n"> |
||||
<section class="tw-mb-9"> |
||||
<h2 bitTypography="h2"> |
||||
{{ "eventManagement" | i18n }} |
||||
</h2> |
||||
<p bitTypography="body1">{{ "eventManagementDesc" | i18n }}</p> |
||||
<app-integration-grid |
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.EVENT" |
||||
></app-integration-grid> |
||||
</section> |
||||
</bit-tab> |
||||
|
||||
<bit-tab [label]="'deviceManagement' | i18n"> |
||||
<section class="tw-mb-9"> |
||||
<h2 bitTypography="h2"> |
||||
{{ "deviceManagement" | i18n }} |
||||
</h2> |
||||
<p bitTypography="body1">{{ "deviceManagementDesc" | i18n }}</p> |
||||
<app-integration-grid |
||||
[integrations]="integrationsList | filterIntegrations: IntegrationType.DEVICE" |
||||
></app-integration-grid> |
||||
</section> |
||||
</bit-tab> |
||||
</bit-tab-group> |
||||
@ -0,0 +1,207 @@
@@ -0,0 +1,207 @@
|
||||
import { Component } from "@angular/core"; |
||||
|
||||
import { IntegrationType } from "@bitwarden/common/enums"; |
||||
|
||||
import { HeaderModule } from "../../../layouts/header/header.module"; |
||||
import { FilterIntegrationsPipe, IntegrationGridComponent, Integration } from "../../../shared/"; |
||||
import { SharedModule } from "../../../shared/shared.module"; |
||||
import { SharedOrganizationModule } from "../shared"; |
||||
|
||||
@Component({ |
||||
selector: "ac-integrations", |
||||
templateUrl: "./integrations.component.html", |
||||
standalone: true, |
||||
imports: [ |
||||
SharedModule, |
||||
SharedOrganizationModule, |
||||
IntegrationGridComponent, |
||||
HeaderModule, |
||||
FilterIntegrationsPipe, |
||||
], |
||||
}) |
||||
export class AdminConsoleIntegrationsComponent { |
||||
integrationsList: Integration[] = []; |
||||
tabIndex: number; |
||||
|
||||
constructor() { |
||||
this.integrationsList = [ |
||||
{ |
||||
name: "AD FS", |
||||
linkURL: "https://bitwarden.com/help/saml-adfs/", |
||||
image: "../../../../../../../images/integrations/azure-active-directory.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Auth0", |
||||
linkURL: "https://bitwarden.com/help/saml-auth0/", |
||||
image: "../../../../../../../images/integrations/logo-auth0-badge-color.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "AWS", |
||||
linkURL: "https://bitwarden.com/help/saml-aws/", |
||||
image: "../../../../../../../images/integrations/aws-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/aws-darkmode.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Microsoft Entra ID", |
||||
linkURL: "https://bitwarden.com/help/saml-azure/", |
||||
image: "../../../../../../../images/integrations/logo-microsoft-entra-id-color.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Duo", |
||||
linkURL: "https://bitwarden.com/help/saml-duo/", |
||||
image: "../../../../../../../images/integrations/logo-duo-color.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Google", |
||||
linkURL: "https://bitwarden.com/help/saml-google/", |
||||
image: "../../../../../../../images/integrations/logo-google-badge-color.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "JumpCloud", |
||||
linkURL: "https://bitwarden.com/help/saml-jumpcloud/", |
||||
image: "../../../../../../../images/integrations/logo-jumpcloud-badge-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/jumpcloud-darkmode.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "KeyCloak", |
||||
linkURL: "https://bitwarden.com/help/saml-keycloak/", |
||||
image: "../../../../../../../images/integrations/logo-keycloak-icon.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Okta", |
||||
linkURL: "https://bitwarden.com/help/saml-okta/", |
||||
image: "../../../../../../../images/integrations/logo-okta-symbol-black.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/okta-darkmode.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "OneLogin", |
||||
linkURL: "https://bitwarden.com/help/saml-onelogin/", |
||||
image: "../../../../../../../images/integrations/logo-onelogin-badge-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/onelogin-darkmode.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "PingFederate", |
||||
linkURL: "https://bitwarden.com/help/saml-pingfederate/", |
||||
image: "../../../../../../../images/integrations/logo-ping-identity-badge-color.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Microsoft Entra ID", |
||||
linkURL: "https://bitwarden.com/help/microsoft-entra-id-scim-integration/", |
||||
image: "../../../../../../../images/integrations/logo-microsoft-entra-id-color.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
{ |
||||
name: "Okta", |
||||
linkURL: "https://bitwarden.com/help/okta-scim-integration/", |
||||
image: "../../../../../../../images/integrations/logo-okta-symbol-black.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/okta-darkmode.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
{ |
||||
name: "OneLogin", |
||||
linkURL: "https://bitwarden.com/help/onelogin-scim-integration/", |
||||
image: "../../../../../../../images/integrations/logo-onelogin-badge-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/onelogin-darkmode.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
{ |
||||
name: "JumpCloud", |
||||
linkURL: "https://bitwarden.com/help/jumpcloud-scim-integration/", |
||||
image: "../../../../../../../images/integrations/logo-jumpcloud-badge-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/jumpcloud-darkmode.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
{ |
||||
name: "Ping Identity", |
||||
linkURL: "https://bitwarden.com/help/ping-identity-scim-integration/", |
||||
image: "../../../../../../../images/integrations/logo-ping-identity-badge-color.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
{ |
||||
name: "Active Directory", |
||||
linkURL: "https://bitwarden.com/help/ldap-directory/", |
||||
image: "../../../../../../../images/integrations/azure-active-directory.svg", |
||||
type: IntegrationType.BWDC, |
||||
}, |
||||
{ |
||||
name: "Microsoft Entra ID", |
||||
linkURL: "https://bitwarden.com/help/microsoft-entra-id/", |
||||
image: "../../../../../../../images/integrations/logo-microsoft-entra-id-color.svg", |
||||
type: IntegrationType.BWDC, |
||||
}, |
||||
{ |
||||
name: "Google Workspace", |
||||
linkURL: "https://bitwarden.com/help/workspace-directory/", |
||||
image: "../../../../../../../images/integrations/logo-google-badge-color.svg", |
||||
type: IntegrationType.BWDC, |
||||
}, |
||||
{ |
||||
name: "Okta", |
||||
linkURL: "https://bitwarden.com/help/okta-directory/", |
||||
image: "../../../../../../../images/integrations/logo-okta-symbol-black.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/okta-darkmode.svg", |
||||
type: IntegrationType.BWDC, |
||||
}, |
||||
{ |
||||
name: "OneLogin", |
||||
linkURL: "https://bitwarden.com/help/onelogin-directory/", |
||||
image: "../../../../../../../images/integrations/logo-onelogin-badge-color.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/onelogin-darkmode.svg", |
||||
type: IntegrationType.BWDC, |
||||
}, |
||||
{ |
||||
name: "Splunk", |
||||
linkURL: "https://bitwarden.com/help/splunk-siem/", |
||||
image: "../../../../../../../images/integrations/logo-splunk-black.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/splunk-darkmode.svg", |
||||
type: IntegrationType.EVENT, |
||||
}, |
||||
{ |
||||
name: "Microsoft Sentinel", |
||||
linkURL: "https://bitwarden.com/help/microsoft-sentinel-siem/", |
||||
image: "../../../../../../../images/integrations/logo-microsoft-sentinel-color.svg", |
||||
type: IntegrationType.EVENT, |
||||
}, |
||||
{ |
||||
name: "Rapid7", |
||||
linkURL: "https://bitwarden.com/help/rapid7-siem/", |
||||
image: "../../../../../../../images/integrations/logo-rapid7-black.svg", |
||||
imageDarkMode: "../../../../../../../images/integrations/rapid7-darkmode.svg", |
||||
type: IntegrationType.EVENT, |
||||
}, |
||||
{ |
||||
name: "Elastic", |
||||
linkURL: "https://bitwarden.com/help/elastic-siem/", |
||||
image: "../../../../../../../images/integrations/logo-elastic-badge-color.svg", |
||||
type: IntegrationType.EVENT, |
||||
}, |
||||
{ |
||||
name: "Panther", |
||||
linkURL: "https://bitwarden.com/help/panther-siem/", |
||||
image: "../../../../../../../images/integrations/logo-panther-round-color.svg", |
||||
type: IntegrationType.EVENT, |
||||
}, |
||||
{ |
||||
name: "Microsoft Intune", |
||||
linkURL: "https://bitwarden.com/help/deploy-browser-extensions-with-intune/", |
||||
image: "../../../../../../../images/integrations/logo-microsoft-intune-color.svg", |
||||
type: IntegrationType.DEVICE, |
||||
}, |
||||
]; |
||||
} |
||||
|
||||
get IntegrationType(): typeof IntegrationType { |
||||
return IntegrationType; |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
export * from "./integrations/integration-card/integration-card.component"; |
||||
export * from "./integrations/integration-grid/integration-grid.component"; |
||||
export * from "./integrations/integrations.pipe"; |
||||
export * from "./integrations/models"; |
||||
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; |
||||
import { of } from "rxjs"; |
||||
|
||||
import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens"; |
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; |
||||
import { ThemeTypes } from "@bitwarden/common/platform/enums"; |
||||
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; |
||||
import { I18nMockService } from "@bitwarden/components"; |
||||
|
||||
import { SharedModule } from "../../../shared.module"; |
||||
|
||||
import { IntegrationCardComponent } from "./integration-card.component"; |
||||
|
||||
class MockThemeService implements Partial<ThemeStateService> {} |
||||
|
||||
export default { |
||||
title: "Web/Integration Layout/Integration Card", |
||||
component: IntegrationCardComponent, |
||||
decorators: [ |
||||
moduleMetadata({ |
||||
imports: [SharedModule], |
||||
providers: [ |
||||
{ |
||||
provide: I18nService, |
||||
useFactory: () => { |
||||
return new I18nMockService({}); |
||||
}, |
||||
}, |
||||
{ |
||||
provide: ThemeStateService, |
||||
useClass: MockThemeService, |
||||
}, |
||||
{ |
||||
provide: SYSTEM_THEME_OBSERVABLE, |
||||
useValue: of(ThemeTypes.Light), |
||||
}, |
||||
], |
||||
}), |
||||
], |
||||
args: { |
||||
integrations: [], |
||||
}, |
||||
} as Meta; |
||||
|
||||
type Story = StoryObj<IntegrationCardComponent>; |
||||
|
||||
export const Default: Story = { |
||||
render: (args) => ({ |
||||
props: args, |
||||
template: /*html*/ ` |
||||
<app-integration-card |
||||
[name]="name" |
||||
[image]="image" |
||||
[linkURL]="linkURL" |
||||
></app-integration-card> |
||||
`,
|
||||
}), |
||||
args: { |
||||
name: "Bitwarden", |
||||
image: "/integrations/bitwarden-vertical-blue.svg", |
||||
linkURL: "https://bitwarden.com", |
||||
}, |
||||
}; |
||||
@ -1,15 +1,18 @@
@@ -1,15 +1,18 @@
|
||||
<ul |
||||
class="tw-inline-grid tw-grid-cols-3 tw-gap-6 tw-m-0 tw-p-0 tw-w-full tw-auto-cols-auto tw-list-none lg:tw-grid-cols-4 lg:tw-gap-10 lg:tw-w-auto" |
||||
> |
||||
<li *ngFor="let integration of integrations"> |
||||
<sm-integration-card |
||||
<li |
||||
*ngFor="let integration of integrations" |
||||
[title]="tooltipI18nKey | i18n: integration.name" |
||||
[attr.aria-label]="ariaI18nKey | i18n: integration.name" |
||||
> |
||||
<app-integration-card |
||||
[name]="integration.name" |
||||
[linkText]="integration.linkText" |
||||
[linkURL]="integration.linkURL" |
||||
[image]="integration.image" |
||||
[imageDarkMode]="integration.imageDarkMode" |
||||
[externalURL]="integration.type === IntegrationType.SDK" |
||||
[newBadgeExpiration]="integration.newBadgeExpiration" |
||||
></sm-integration-card> |
||||
></app-integration-card> |
||||
</li> |
||||
</ul> |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
import { Component, Input } from "@angular/core"; |
||||
|
||||
import { IntegrationType } from "@bitwarden/common/enums"; |
||||
|
||||
import { SharedModule } from "../../../shared.module"; |
||||
import { IntegrationCardComponent } from "../integration-card/integration-card.component"; |
||||
import { Integration } from "../models"; |
||||
|
||||
@Component({ |
||||
selector: "app-integration-grid", |
||||
templateUrl: "./integration-grid.component.html", |
||||
standalone: true, |
||||
imports: [IntegrationCardComponent, SharedModule], |
||||
}) |
||||
export class IntegrationGridComponent { |
||||
@Input() integrations: Integration[]; |
||||
|
||||
@Input() ariaI18nKey: string = "integrationCardAriaLabel"; |
||||
@Input() tooltipI18nKey: string = "integrationCardTooltip"; |
||||
|
||||
protected IntegrationType = IntegrationType; |
||||
} |
||||
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; |
||||
import { of } from "rxjs"; |
||||
|
||||
import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens"; |
||||
import { IntegrationType } from "@bitwarden/common/enums"; |
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; |
||||
import { ThemeTypes } from "@bitwarden/common/platform/enums"; |
||||
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; |
||||
import { I18nMockService } from "@bitwarden/components"; |
||||
|
||||
import { SharedModule } from "../../../shared.module"; |
||||
import { IntegrationCardComponent } from "../integration-card/integration-card.component"; |
||||
import { IntegrationGridComponent } from "../integration-grid/integration-grid.component"; |
||||
|
||||
class MockThemeService implements Partial<ThemeStateService> {} |
||||
|
||||
export default { |
||||
title: "Web/Integration Layout/Integration Grid", |
||||
component: IntegrationGridComponent, |
||||
decorators: [ |
||||
moduleMetadata({ |
||||
imports: [IntegrationCardComponent, SharedModule], |
||||
providers: [ |
||||
{ |
||||
provide: I18nService, |
||||
useFactory: () => { |
||||
return new I18nMockService({ |
||||
integrationCardAriaLabel: "Go to integration", |
||||
integrationCardTooltip: "Go to integration", |
||||
}); |
||||
}, |
||||
}, |
||||
{ |
||||
provide: ThemeStateService, |
||||
useClass: MockThemeService, |
||||
}, |
||||
{ |
||||
provide: SYSTEM_THEME_OBSERVABLE, |
||||
useValue: of(ThemeTypes.Dark), |
||||
}, |
||||
], |
||||
}), |
||||
], |
||||
} as Meta; |
||||
|
||||
type Story = StoryObj<IntegrationGridComponent>; |
||||
|
||||
export const Default: Story = { |
||||
render: (args) => ({ |
||||
props: args, |
||||
template: /*html*/ ` |
||||
<app-integration-grid [integrations]="integrations"></app-integration-grid> |
||||
`,
|
||||
}), |
||||
args: { |
||||
integrations: [ |
||||
{ |
||||
name: "Card 1", |
||||
linkURL: "https://bitwarden.com", |
||||
image: "/integrations/bitwarden-vertical-blue.svg", |
||||
type: IntegrationType.SSO, |
||||
}, |
||||
{ |
||||
name: "Card 2", |
||||
linkURL: "https://bitwarden.com", |
||||
image: "/integrations/bitwarden-vertical-blue.svg", |
||||
type: IntegrationType.SDK, |
||||
}, |
||||
{ |
||||
name: "Card 3", |
||||
linkURL: "https://bitwarden.com", |
||||
image: "/integrations/bitwarden-vertical-blue.svg", |
||||
type: IntegrationType.SCIM, |
||||
}, |
||||
], |
||||
}, |
||||
}; |
||||
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
import { Pipe, PipeTransform } from "@angular/core"; |
||||
|
||||
import { IntegrationType } from "@bitwarden/common/enums"; |
||||
|
||||
import { Integration } from "../../../shared/components/integrations/models"; |
||||
|
||||
@Pipe({ |
||||
name: "filterIntegrations", |
||||
standalone: true, |
||||
}) |
||||
export class FilterIntegrationsPipe implements PipeTransform { |
||||
transform(integrations: Integration[], type: IntegrationType): Integration[] { |
||||
return integrations.filter((integration) => integration.type === type); |
||||
} |
||||
} |
||||
@ -1,2 +1,3 @@
@@ -1,2 +1,3 @@
|
||||
export * from "./shared.module"; |
||||
export * from "./loose-components.module"; |
||||
export * from "./components/index"; |
||||
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 455 B |
|
After Width: | Height: | Size: 836 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 809 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 931 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 473 B |
|
After Width: | Height: | Size: 996 B |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 718 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
import { Component, Input } from "@angular/core"; |
||||
|
||||
import { IntegrationType } from "@bitwarden/common/enums"; |
||||
|
||||
import { Integration } from "../models/integration"; |
||||
|
||||
@Component({ |
||||
selector: "sm-integration-grid", |
||||
templateUrl: "./integration-grid.component.html", |
||||
}) |
||||
export class IntegrationGridComponent { |
||||
@Input() integrations: Integration[]; |
||||
|
||||
protected IntegrationType = IntegrationType; |
||||
} |
||||
@ -1,15 +1,22 @@
@@ -1,15 +1,22 @@
|
||||
import { NgModule } from "@angular/core"; |
||||
|
||||
import { |
||||
IntegrationCardComponent, |
||||
IntegrationGridComponent, |
||||
} from "@bitwarden/web-vault/app/shared"; |
||||
|
||||
import { SecretsManagerSharedModule } from "../shared/sm-shared.module"; |
||||
|
||||
import { IntegrationCardComponent } from "./integration-card/integration-card.component"; |
||||
import { IntegrationGridComponent } from "./integration-grid/integration-grid.component"; |
||||
import { IntegrationsRoutingModule } from "./integrations-routing.module"; |
||||
import { IntegrationsComponent } from "./integrations.component"; |
||||
|
||||
@NgModule({ |
||||
imports: [SecretsManagerSharedModule, IntegrationsRoutingModule], |
||||
declarations: [IntegrationsComponent, IntegrationGridComponent, IntegrationCardComponent], |
||||
providers: [], |
||||
imports: [ |
||||
SecretsManagerSharedModule, |
||||
IntegrationsRoutingModule, |
||||
IntegrationCardComponent, |
||||
IntegrationGridComponent, |
||||
], |
||||
declarations: [IntegrationsComponent], |
||||
}) |
||||
export class IntegrationsModule {} |
||||
|
||||