1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-12 14:56:58 +01:00

[PM-12273] Admin Console Integration Page (#11883)

* 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>
This commit is contained in:
Brandon Treston 2024-12-05 10:09:40 -05:00 committed by GitHub
parent 6dc68b174b
commit c11f429ddb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 764 additions and 110 deletions

View File

@ -57,6 +57,7 @@ const config: StorybookConfig = {
return config;
},
docs: {},
staticDirs: ["../apps/web/src/images"],
};
export default config;

View File

@ -59,8 +59,14 @@ describe("Is Enterprise Org Guard", () => {
{
path: "organizations/:organizationId/enterpriseOrgsOnly",
component: IsEnterpriseOrganizationComponent,
canActivate: [isEnterpriseOrgGuard()],
canActivate: [isEnterpriseOrgGuard(true)],
},
{
path: "organizations/:organizationId/enterpriseOrgsOnlyNoError",
component: IsEnterpriseOrganizationComponent,
canActivate: [isEnterpriseOrgGuard(false)],
},
{
path: "organizations/:organizationId/billing/subscription",
component: OrganizationUpgradeScreenComponent,
@ -115,6 +121,24 @@ describe("Is Enterprise Org Guard", () => {
);
});
it.each([
ProductTierType.Free,
ProductTierType.Families,
ProductTierType.Teams,
ProductTierType.TeamsStarter,
])("does not proceed with the navigation for productTierType '%s'", async (productTierType) => {
const org = orgFactory({
type: OrganizationUserType.User,
productTierType: productTierType,
});
organizationService.get.calledWith(org.id).mockResolvedValue(org);
await routerHarness.navigateByUrl(`organizations/${org.id}/enterpriseOrgsOnlyNoError`);
expect(dialogService.openSimpleDialog).not.toHaveBeenCalled();
expect(
routerHarness.routeNativeElement?.querySelector("h1")?.textContent?.trim() ?? "",
).not.toBe("This component can only be accessed by a enterprise organization!");
});
it("proceeds with navigation if the organization in question is a enterprise organization", async () => {
const org = orgFactory({ productTierType: ProductTierType.Enterprise });
organizationService.get.calledWith(org.id).mockResolvedValue(org);

View File

@ -17,7 +17,7 @@ import { DialogService } from "@bitwarden/components";
* if they have access to upgrade the organization. If the organization is
* enterprise routing proceeds."
*/
export function isEnterpriseOrgGuard(): CanActivateFn {
export function isEnterpriseOrgGuard(showError: boolean = true): CanActivateFn {
return async (route: ActivatedRouteSnapshot, _state: RouterStateSnapshot) => {
const router = inject(Router);
const organizationService = inject(OrganizationService);
@ -29,7 +29,7 @@ export function isEnterpriseOrgGuard(): CanActivateFn {
return router.createUrlTree(["/"]);
}
if (org.productTierType != ProductTierType.Enterprise) {
if (org.productTierType != ProductTierType.Enterprise && showError) {
// Users without billing permission can't access billing
if (!org.canEditSubscription) {
await dialogService.openSimpleDialog({

View File

@ -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>

View File

@ -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;
}
}

View File

@ -60,6 +60,12 @@
<bit-nav-item [text]="'billingHistory' | i18n" route="billing/history"></bit-nav-item>
</ng-container>
</bit-nav-group>
<bit-nav-item
icon="bwi-providers"
[text]="'integrations' | i18n"
route="integrations"
*ngIf="integrationPageEnabled$ | async"
></bit-nav-item>
<bit-nav-group
icon="bwi-cog"
[text]="'settings' | i18n"

View File

@ -18,6 +18,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
import { PolicyType, ProviderStatusType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { ProductTierType } from "@bitwarden/common/billing/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -47,12 +48,15 @@ export class OrganizationLayoutComponent implements OnInit {
protected orgFilter = (org: Organization) => canAccessOrgAdmin(org);
protected integrationPageEnabled$: Observable<boolean>;
organization$: Observable<Organization>;
canAccessExport$: Observable<boolean>;
showPaymentAndHistory$: Observable<boolean>;
hideNewOrgButton$: Observable<boolean>;
organizationIsUnmanaged$: Observable<boolean>;
isAccessIntelligenceFeatureEnabled = false;
enterpriseOrganization$: Observable<boolean>;
constructor(
private route: ActivatedRoute,
@ -104,6 +108,16 @@ export class OrganizationLayoutComponent implements OnInit {
provider.providerStatus !== ProviderStatusType.Billable,
),
);
this.integrationPageEnabled$ = combineLatest(
this.organization$,
this.configService.getFeatureFlag$(FeatureFlag.PM14505AdminConsoleIntegrationPage),
).pipe(
map(
([org, featureFlagEnabled]) =>
org.productTierType === ProductTierType.Enterprise && featureFlagEnabled,
),
);
}
canShowVaultTab(organization: Organization): boolean {

View File

@ -2,6 +2,7 @@ import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { authGuard } from "@bitwarden/angular/auth/guards";
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
import {
canAccessOrgAdmin,
canAccessGroupsTab,
@ -11,6 +12,7 @@ import {
canAccessSettingsTab,
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { organizationPermissionsGuard } from "../../admin-console/organizations/guards/org-permissions.guard";
import { organizationRedirectGuard } from "../../admin-console/organizations/guards/org-redirect.guard";
@ -18,6 +20,8 @@ import { OrganizationLayoutComponent } from "../../admin-console/organizations/l
import { deepLinkGuard } from "../../auth/guards/deep-link.guard";
import { VaultModule } from "../../vault/org-vault/vault.module";
import { isEnterpriseOrgGuard } from "./guards/is-enterprise-org.guard";
import { AdminConsoleIntegrationsComponent } from "./integrations/integrations.component";
import { GroupsComponent } from "./manage/groups.component";
const routes: Routes = [
@ -36,6 +40,17 @@ const routes: Routes = [
path: "vault",
loadChildren: () => VaultModule,
},
{
path: "integrations",
canActivate: [
canAccessFeature(FeatureFlag.PM14505AdminConsoleIntegrationPage),
isEnterpriseOrgGuard(false),
],
component: AdminConsoleIntegrationsComponent,
data: {
titleId: "integrations",
},
},
{
path: "settings",
loadChildren: () =>

View File

@ -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";

View File

@ -1,8 +1,11 @@
<div
class="tw-block tw-h-full tw-overflow-hidden tw-rounded tw-border tw-border-solid tw-border-secondary-600 tw-relative tw-transition-all xl:tw-w-64 hover:tw-scale-105 focus-within:tw-outline-none focus-within:tw-ring focus-within:tw-ring-primary-700 focus-within:tw-ring-offset-2"
class="tw-block tw-h-full tw-overflow-hidden tw-rounded tw-border tw-border-solid tw-border-secondary-600 tw-relative tw-transition-all hover:tw-scale-105 focus-within:tw-outline-none focus-within:tw-ring focus-within:tw-ring-primary-700 focus-within:tw-ring-offset-2"
>
<div class="tw-flex tw-bg-secondary-100 tw-items-center tw-justify-end tw-pt-4 tw-pr-4">
<i class="bwi bwi-external-link"></i>
</div>
<div
class="tw-flex tw-h-36 tw-bg-secondary-100 tw-items-center tw-justify-center tw-py-2 tw-px-6 lg:tw-py-4 lg:tw-px-12"
class="tw-flex tw-h-32 tw-bg-secondary-100 tw-items-center tw-justify-center tw-pb-2 tw-px-6 lg:tw-pb-4 lg:tw-px-12"
>
<div class="tw-flex tw-items-center tw-justify-center tw-h-28 tw-w-28 lg:tw-w-40">
<img
@ -14,14 +17,13 @@
</div>
</div>
<div class="tw-p-5">
<h3 class="tw-mb-4 tw-text-lg tw-font-semibold">{{ name }}</h3>
<h3 class="tw-text-main tw-text-lg tw-font-semibold">{{ name }}</h3>
<a
class="tw-block tw-mb-0 tw-font-bold hover:tw-no-underline focus:tw-outline-none after:tw-content-[''] after:tw-block after:tw-absolute after:tw-w-full after:tw-h-full after:tw-left-0 after:tw-top-0"
[href]="linkURL"
rel="noopener noreferrer"
target="_blank"
>
{{ linkText }}
</a>
<span *ngIf="showNewBadge()" bitBadge class="tw-mt-3" variant="secondary">
{{ "new" | i18n }}

View File

@ -1,9 +1,13 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { mock } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs";
import { SYSTEM_THEME_OBSERVABLE } from "../../../../../../../libs/angular/src/services/injection-tokens";
import { ThemeType } from "../../../../../../../libs/common/src/platform/enums";
import { ThemeStateService } from "../../../../../../../libs/common/src/platform/theming/theme-state.service";
import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ThemeType } from "@bitwarden/common/platform/enums";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { SharedModule } from "@bitwarden/components/src/shared";
import { I18nPipe } from "@bitwarden/components/src/shared/i18n.pipe";
import { IntegrationCardComponent } from "./integration-card.component";
@ -19,7 +23,7 @@ describe("IntegrationCardComponent", () => {
systemTheme$.next(ThemeType.Light);
await TestBed.configureTestingModule({
declarations: [IntegrationCardComponent],
imports: [IntegrationCardComponent, SharedModule],
providers: [
{
provide: ThemeStateService,
@ -29,6 +33,14 @@ describe("IntegrationCardComponent", () => {
provide: SYSTEM_THEME_OBSERVABLE,
useValue: systemTheme$,
},
{
provide: I18nPipe,
useValue: mock<I18nPipe>(),
},
{
provide: I18nService,
useValue: mock<I18nService>(),
},
],
}).compileComponents();
});
@ -39,7 +51,6 @@ describe("IntegrationCardComponent", () => {
component.name = "Integration Name";
component.image = "test-image.png";
component.linkText = "Get started with integration";
component.linkURL = "https://example.com/";
fixture.detectChanges();
@ -53,10 +64,8 @@ describe("IntegrationCardComponent", () => {
it("renders card body", () => {
const name = fixture.nativeElement.querySelector("h3");
const link = fixture.nativeElement.querySelector("a");
expect(name.textContent).toBe("Integration Name");
expect(link.textContent.trim()).toBe("Get started with integration");
});
it("assigns external rel attribute", () => {

View File

@ -13,9 +13,13 @@ import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-t
import { ThemeType } from "@bitwarden/common/platform/enums";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { SharedModule } from "../../../shared.module";
@Component({
selector: "sm-integration-card",
selector: "app-integration-card",
templateUrl: "./integration-card.component.html",
standalone: true,
imports: [SharedModule],
})
export class IntegrationCardComponent implements AfterViewInit, OnDestroy {
private destroyed$: Subject<void> = new Subject();
@ -24,7 +28,6 @@ export class IntegrationCardComponent implements AfterViewInit, OnDestroy {
@Input() name: string;
@Input() image: string;
@Input() imageDarkMode?: string;
@Input() linkText: string;
@Input() linkURL: string;
/** Adds relevant `rel` attribute to external links */

View File

@ -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",
},
};

View File

@ -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>

View File

@ -3,12 +3,16 @@ import { By } from "@angular/platform-browser";
import { mock } from "jest-mock-extended";
import { of } from "rxjs";
import { SYSTEM_THEME_OBSERVABLE } from "../../../../../../../libs/angular/src/services/injection-tokens";
import { IntegrationType } from "../../../../../../../libs/common/src/enums";
import { ThemeType } from "../../../../../../../libs/common/src/platform/enums";
import { ThemeStateService } from "../../../../../../../libs/common/src/platform/theming/theme-state.service";
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 { SharedModule } from "@bitwarden/components/src/shared";
import { I18nPipe } from "@bitwarden/components/src/shared/i18n.pipe";
import { IntegrationCardComponent } from "../integration-card/integration-card.component";
import { Integration } from "../models/integration";
import { Integration } from "../models";
import { IntegrationGridComponent } from "./integration-grid.component";
@ -19,14 +23,12 @@ describe("IntegrationGridComponent", () => {
{
name: "Integration 1",
image: "test-image1.png",
linkText: "Get started with integration 1",
linkURL: "https://example.com/1",
type: IntegrationType.Integration,
},
{
name: "SDK 2",
image: "test-image2.png",
linkText: "View SDK 2",
linkURL: "https://example.com/2",
type: IntegrationType.SDK,
},
@ -34,7 +36,7 @@ describe("IntegrationGridComponent", () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [IntegrationGridComponent, IntegrationCardComponent],
imports: [IntegrationGridComponent, IntegrationCardComponent, SharedModule],
providers: [
{
provide: ThemeStateService,
@ -42,7 +44,15 @@ describe("IntegrationGridComponent", () => {
},
{
provide: SYSTEM_THEME_OBSERVABLE,
useValue: of(ThemeType.Light),
useValue: of(ThemeTypes.Light),
},
{
provide: I18nPipe,
useValue: mock<I18nPipe>(),
},
{
provide: I18nService,
useValue: mock<I18nService>({ t: (key, p1) => key + " " + p1 }),
},
],
});
@ -50,6 +60,8 @@ describe("IntegrationGridComponent", () => {
fixture = TestBed.createComponent(IntegrationGridComponent);
component = fixture.componentInstance;
component.integrations = integrations;
component.ariaI18nKey = "integrationCardAriaLabel";
component.tooltipI18nKey = "integrationCardTooltip";
fixture.detectChanges();
});
@ -68,7 +80,6 @@ describe("IntegrationGridComponent", () => {
expect(card.componentInstance.name).toBe("SDK 2");
expect(card.componentInstance.image).toBe("test-image2.png");
expect(card.componentInstance.linkText).toBe("View SDK 2");
expect(card.componentInstance.linkURL).toBe("https://example.com/2");
});
@ -78,4 +89,12 @@ describe("IntegrationGridComponent", () => {
expect(card[0].componentInstance.externalURL).toBe(false);
expect(card[1].componentInstance.externalURL).toBe(true);
});
it("has a tool tip and aria label attributes", () => {
const card: HTMLElement = fixture.debugElement.queryAll(By.css("li"))[0].nativeElement;
expect(card.title).toBe("integrationCardTooltip" + " " + integrations[0].name);
expect(card.getAttribute("aria-label")).toBe(
"integrationCardAriaLabel" + " " + integrations[0].name,
);
});
});

View File

@ -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;
}

View File

@ -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,
},
],
},
};

View File

@ -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);
}
}

View File

@ -9,7 +9,6 @@ export type Integration = {
*/
imageDarkMode?: string;
linkURL: string;
linkText: string;
type: IntegrationType;
/**
* Shows the "New" badge until the defined date.

View File

@ -1,2 +1,3 @@
export * from "./shared.module";
export * from "./loose-components.module";
export * from "./components/index";

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M169.086 251.309c0 7.383.798 13.37 2.195 17.76 1.596 4.39 3.592 9.179 6.386 14.368.997 1.596 1.397 3.193 1.397 4.589 0 1.996-1.198 3.992-3.792 5.987l-12.572 8.381c-1.796 1.198-3.592 1.796-5.188 1.796-1.996 0-3.991-.997-5.987-2.793a61.826 61.826 0 0 1-7.184-9.379c-1.995-3.393-3.991-7.184-6.186-11.774-15.565 18.359-35.121 27.538-58.669 27.538-16.762 0-30.132-4.789-39.91-14.368-9.779-9.578-14.767-22.35-14.767-38.314 0-16.962 5.986-30.731 18.159-41.108 12.173-10.377 28.337-15.565 48.89-15.565 6.785 0 13.77.598 21.153 1.596 7.384.998 14.967 2.594 22.949 4.39v-14.567c0-15.166-3.193-25.742-9.379-31.929-6.386-6.186-17.162-9.179-32.527-9.179-6.985 0-14.169.798-21.552 2.594-7.384 1.796-14.567 3.991-21.552 6.785-3.193 1.397-5.587 2.195-6.984 2.594-1.397.399-2.395.599-3.193.599-2.794 0-4.19-1.996-4.19-6.186v-9.778c0-3.193.398-5.588 1.396-6.985.998-1.397 2.794-2.794 5.588-4.19 6.984-3.592 15.365-6.586 25.143-8.98 9.779-2.595 20.155-3.792 31.13-3.792 23.748 0 41.109 5.388 52.284 16.164 10.975 10.776 16.563 27.139 16.563 49.09v64.656h.399Zm-81.019 30.332c6.585 0 13.37-1.198 20.554-3.592 7.184-2.395 13.57-6.785 18.958-12.772 3.193-3.791 5.587-7.982 6.785-12.771 1.197-4.789 1.995-10.576 1.995-17.361v-8.382c-5.787-1.396-11.973-2.594-18.359-3.392-6.386-.798-12.572-1.197-18.758-1.197-13.37 0-23.148 2.594-29.733 7.982-6.586 5.388-9.779 12.971-9.779 22.949 0 9.379 2.395 16.363 7.384 21.152 4.79 4.989 11.774 7.384 20.953 7.384Zm160.242 21.552c-3.592 0-5.987-.599-7.583-1.996-1.597-1.197-2.994-3.991-4.191-7.783L189.64 139.159c-1.197-3.991-1.796-6.585-1.796-7.982 0-3.193 1.596-4.989 4.789-4.989h19.556c3.792 0 6.386.599 7.783 1.996 1.597 1.197 2.794 3.991 3.991 7.783l33.525 132.104 31.131-132.104c.997-3.992 2.195-6.586 3.791-7.783 1.597-1.197 4.39-1.996 7.982-1.996h15.965c3.791 0 6.385.599 7.982 1.996 1.596 1.197 2.993 3.991 3.791 7.783l31.53 133.7 34.522-133.7c1.198-3.992 2.595-6.586 3.992-7.783 1.596-1.197 4.19-1.996 7.782-1.996h18.559c3.192 0 4.988 1.597 4.988 4.989 0 .998-.199 1.996-.399 3.193-.199 1.197-.598 2.794-1.397 4.989l-48.092 154.255c-1.197 3.991-2.594 6.585-4.191 7.783-1.596 1.197-4.19 1.995-7.583 1.995H350.68c-3.792 0-6.386-.599-7.982-1.995-1.597-1.397-2.994-3.992-3.792-7.983l-30.931-128.712-30.731 128.513c-.998 3.991-2.195 6.585-3.792 7.982-1.596 1.397-4.39 1.996-7.982 1.996h-17.161Zm256.426 5.387c-10.377 0-20.753-1.197-30.731-3.591-9.978-2.395-17.76-4.989-22.949-7.983-3.193-1.796-5.388-3.791-6.186-5.587a14.091 14.091 0 0 1-1.197-5.588v-10.177c0-4.191 1.596-6.186 4.59-6.186 1.197 0 2.394.2 3.591.599 1.198.399 2.994 1.197 4.989 1.995a108.617 108.617 0 0 0 21.951 6.985c7.982 1.596 15.765 2.394 23.747 2.394 12.572 0 22.35-2.195 29.135-6.585 6.785-4.39 10.377-10.776 10.377-18.958 0-5.587-1.796-10.177-5.388-13.968-3.592-3.792-10.377-7.184-20.155-10.377l-28.935-8.98c-14.568-4.59-25.344-11.375-31.929-20.355-6.585-8.78-9.978-18.558-9.978-28.935 0-8.381 1.796-15.765 5.388-22.15 3.592-6.386 8.381-11.974 14.368-16.364 5.987-4.59 12.772-7.982 20.754-10.377 7.982-2.394 16.363-3.392 25.143-3.392 4.391 0 8.98.2 13.371.798 4.589.599 8.78 1.397 12.971 2.195 3.991.998 7.782 1.996 11.374 3.193 3.592 1.197 6.386 2.395 8.381 3.592 2.794 1.597 4.79 3.193 5.987 4.989 1.197 1.596 1.796 3.791 1.796 6.585v9.379c0 4.191-1.596 6.386-4.59 6.386-1.596 0-4.19-.798-7.583-2.395-11.374-5.188-24.146-7.782-38.314-7.782-11.375 0-20.355 1.796-26.541 5.587-6.186 3.792-9.379 9.579-9.379 17.761 0 5.587 1.996 10.376 5.987 14.168 3.991 3.791 11.374 7.583 21.951 10.975l28.336 8.98c14.368 4.59 24.745 10.976 30.931 19.157 6.186 8.182 9.18 17.561 9.18 27.938 0 8.581-1.796 16.363-5.189 23.148-3.592 6.785-8.381 12.772-14.567 17.561-6.186 4.989-13.57 8.581-22.151 11.175-8.98 2.794-18.359 4.19-28.536 4.19Z" fill="#252F3E"/><path fill-rule="evenodd" clip-rule="evenodd" d="M542.451 405.564c-65.653 48.491-161.04 74.234-243.057 74.234-114.943 0-218.51-42.505-296.736-113.147-6.186-5.588-.599-13.171 6.785-8.781 84.61 49.09 188.977 78.824 296.936 78.824 72.837 0 152.858-15.166 226.493-46.296 10.976-4.989 20.355 7.183 9.579 15.166Z" fill="#F90"/><path fill-rule="evenodd" clip-rule="evenodd" d="M569.79 374.433c-8.382-10.776-55.476-5.188-76.828-2.594-6.386.798-7.384-4.789-1.597-8.98 37.516-26.341 99.178-18.758 106.362-9.978 7.184 8.98-1.995 70.642-37.117 100.176-5.388 4.59-10.576 2.195-8.181-3.791 7.982-19.756 25.742-64.257 17.361-74.833Z" fill="#F90"/></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)" fill="#fff"><path d="M169.086 251.309c0 7.383.798 13.37 2.195 17.76 1.596 4.39 3.592 9.179 6.386 14.368.997 1.596 1.397 3.193 1.397 4.589 0 1.996-1.198 3.992-3.792 5.987l-12.572 8.381c-1.796 1.198-3.592 1.796-5.188 1.796-1.996 0-3.991-.997-5.987-2.793a61.826 61.826 0 0 1-7.184-9.379c-1.995-3.393-3.991-7.184-6.186-11.774-15.565 18.359-35.121 27.538-58.669 27.538-16.762 0-30.132-4.789-39.91-14.368-9.779-9.578-14.767-22.35-14.767-38.314 0-16.962 5.986-30.731 18.159-41.108 12.173-10.377 28.337-15.565 48.89-15.565 6.785 0 13.77.598 21.153 1.596 7.384.998 14.967 2.594 22.949 4.39v-14.567c0-15.166-3.193-25.742-9.379-31.929-6.386-6.186-17.162-9.179-32.527-9.179-6.985 0-14.169.798-21.552 2.594-7.384 1.796-14.567 3.991-21.552 6.785-3.193 1.397-5.587 2.195-6.984 2.594-1.397.399-2.395.599-3.193.599-2.794 0-4.19-1.996-4.19-6.186v-9.778c0-3.193.398-5.588 1.396-6.985.998-1.397 2.794-2.794 5.588-4.19 6.984-3.592 15.365-6.586 25.143-8.98 9.779-2.595 20.155-3.792 31.13-3.792 23.748 0 41.109 5.388 52.284 16.164 10.975 10.776 16.563 27.139 16.563 49.09v64.656h.399Zm-81.019 30.332c6.585 0 13.37-1.198 20.554-3.592 7.184-2.395 13.57-6.785 18.958-12.772 3.193-3.791 5.587-7.982 6.785-12.771 1.197-4.789 1.995-10.576 1.995-17.361v-8.382c-5.787-1.396-11.973-2.594-18.359-3.392-6.386-.798-12.572-1.197-18.758-1.197-13.37 0-23.148 2.594-29.733 7.982-6.586 5.388-9.779 12.971-9.779 22.949 0 9.379 2.395 16.363 7.384 21.152 4.79 4.989 11.774 7.384 20.953 7.384Zm160.242 21.552c-3.592 0-5.987-.599-7.583-1.996-1.597-1.197-2.994-3.991-4.191-7.783L189.64 139.159c-1.197-3.991-1.796-6.585-1.796-7.982 0-3.193 1.596-4.989 4.789-4.989h19.556c3.792 0 6.386.599 7.783 1.996 1.597 1.197 2.794 3.991 3.991 7.783l33.525 132.104 31.131-132.104c.997-3.992 2.195-6.586 3.791-7.783 1.597-1.197 4.39-1.996 7.982-1.996h15.965c3.791 0 6.385.599 7.982 1.996 1.596 1.197 2.993 3.991 3.791 7.783l31.53 133.7 34.522-133.7c1.198-3.992 2.595-6.586 3.992-7.783 1.596-1.197 4.19-1.996 7.782-1.996h18.559c3.192 0 4.988 1.597 4.988 4.989 0 .998-.199 1.996-.399 3.193-.199 1.197-.598 2.794-1.397 4.989l-48.092 154.255c-1.197 3.991-2.594 6.585-4.191 7.783-1.596 1.197-4.19 1.995-7.583 1.995H350.68c-3.792 0-6.386-.599-7.982-1.995-1.597-1.397-2.994-3.992-3.792-7.983l-30.931-128.712-30.731 128.513c-.998 3.991-2.195 6.585-3.792 7.982-1.596 1.397-4.39 1.996-7.982 1.996h-17.161Zm256.426 5.387c-10.377 0-20.753-1.197-30.731-3.591-9.978-2.395-17.76-4.989-22.949-7.983-3.193-1.796-5.388-3.791-6.186-5.587a14.091 14.091 0 0 1-1.197-5.588v-10.177c0-4.191 1.596-6.186 4.59-6.186 1.197 0 2.394.2 3.591.599 1.198.399 2.994 1.197 4.989 1.995a108.617 108.617 0 0 0 21.951 6.985c7.982 1.596 15.765 2.394 23.747 2.394 12.572 0 22.35-2.195 29.135-6.585 6.785-4.39 10.377-10.776 10.377-18.958 0-5.587-1.796-10.177-5.388-13.968-3.592-3.792-10.377-7.184-20.155-10.377l-28.935-8.98c-14.568-4.59-25.344-11.375-31.929-20.355-6.585-8.78-9.978-18.558-9.978-28.935 0-8.381 1.796-15.765 5.388-22.15 3.592-6.386 8.381-11.974 14.368-16.364 5.987-4.59 12.772-7.982 20.754-10.377 7.982-2.394 16.363-3.392 25.143-3.392 4.391 0 8.98.2 13.371.798 4.589.599 8.78 1.397 12.971 2.195 3.991.998 7.782 1.996 11.374 3.193 3.592 1.197 6.386 2.395 8.381 3.592 2.794 1.597 4.79 3.193 5.987 4.989 1.197 1.596 1.796 3.791 1.796 6.585v9.379c0 4.191-1.596 6.386-4.59 6.386-1.596 0-4.19-.798-7.583-2.395-11.374-5.188-24.146-7.782-38.314-7.782-11.375 0-20.355 1.796-26.541 5.587-6.186 3.792-9.379 9.579-9.379 17.761 0 5.587 1.996 10.376 5.987 14.168 3.991 3.791 11.374 7.583 21.951 10.975l28.336 8.98c14.368 4.59 24.745 10.976 30.931 19.157 6.186 8.182 9.18 17.561 9.18 27.938 0 8.581-1.796 16.363-5.189 23.148-3.592 6.785-8.381 12.772-14.567 17.561-6.186 4.989-13.57 8.581-22.151 11.175-8.98 2.794-18.359 4.19-28.536 4.19Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M542.451 405.564c-65.653 48.491-161.04 74.234-243.057 74.234-114.943 0-218.51-42.505-296.736-113.147-6.186-5.588-.599-13.171 6.785-8.781 84.61 49.09 188.977 78.824 296.936 78.824 72.837 0 152.858-15.166 226.493-46.296 10.976-4.989 20.355 7.183 9.579 15.166Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M569.79 374.433c-8.382-10.776-55.476-5.188-76.828-2.594-6.386.798-7.384-4.789-1.597-8.98 37.516-26.341 99.178-18.758 106.362-9.978 7.184 8.98-1.995 70.642-37.117 100.176-5.388 4.59-10.576 2.195-8.181-3.791 7.982-19.756 25.742-64.257 17.361-74.833Z"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 374.5 377.3" width="2481" height="2500"><path d="M290 166.3c.4 0 .8.5 1.4 1.4.5.8 42.6 51.3 93.6 112.2 51 60.9 92.6 111 92.4 111.3-.1.3-40.7 33.6-90.2 73.9s-91.6 74.6-93.5 76.2c-3.3 2.7-3.5 2.8-4.7 1.6-.7-.7-42.9-35.2-93.8-76.7S102.8 390.5 103 390c.2-.5 42-50.4 93.1-111s92.9-110.7 93.1-111.5c.2-.8.5-1.2.8-1.2z" style="fill:#00bef2" transform="translate(-102.969 -166.294)"/><path d="M283.1 483.6c-5.8-2.1-12.8-8.1-15.7-13.7-3.6-6.9-3.3-17.7.7-26.3 3.1-6.4 3.1-6.6 1.1-8.1-1.1-.8-14.4-8.2-29.4-16.3-15-8.1-28.1-15.2-29-15.7-1.2-.7-3.2 0-6.8 2.3-11.7 7.4-23.9 6.6-33.5-2.3-6.9-6.4-8.9-10.9-8.9-20.1 0-8.9 1.8-13.5 7.5-19.2 7.7-7.7 18-10.3 27.9-7 5.4 1.8 5.5 1.8 8.9-.8 4-3 36.1-32.3 51.6-47l10.7-10.2-3.2-6.7c-6.5-13.5-3.2-28.5 8.2-37.5 6.2-4.9 10.8-6.4 19.7-6.4 20.8 0 35.3 21.8 27.5 41.3-2.1 5.4-2.1 5.5-.1 8.8 1.7 2.9 30.6 37.8 45.9 55.6 2.7 3.1 5.7 5.6 6.7 5.6s4.4-1 7.6-2.2c14.9-5.9 30.6.7 36.8 15.5 4 9.5.5 22.3-8 30-6 5.4-10.4 7.1-18.4 7.1-5.6 0-7.7-.6-13.6-3.8-4.4-2.4-7.8-3.6-9.2-3.2-2.4.6-39.3 25.9-47.5 32.5-5 4.1-5.4 5.6-2.8 11.7 2.5 6 2.2 15.4-.6 21.3-3.1 6.5-10.8 13-17.5 15-6.8 1.9-10.9 1.9-16.6-.2zm1.7-110.2v-57l-3.2-4.4c-1.8-2.4-3.5-4.4-3.8-4.4-1.3 0-65.9 58.7-65.9 59.9 0 .3 1 3.3 2.2 6.5 1.2 3.3 2.1 8 2 10.7-.1 2.7-.1 5.7-.1 6.7.1 2.3 21.7 16.1 54.1 34.8 8.9 5.2 12 6.5 13.1 5.6 1.3-1.1 1.6-12.2 1.6-58.4zm27.4 50.4c42.8-26.9 50.8-32.3 51.3-34.3.3-1.2.7-5.9.8-10.6l.3-8.4-21.8-25.9c-23.4-27.7-32-37.1-34-37.1-.7 0-4.2 2-7.8 4.4l-6.6 4.4.3 56.9c.3 51 .7 59.6 2.6 59.6.2.1 7-4 14.9-9z" style="fill:#fff;stroke:#fff;stroke-width:1.2357;stroke-linecap:round;stroke-linejoin:round" transform="translate(-102.969 -166.294)"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M81.081 446.322C36.122 445.244 0 408.378 0 363.092c0-45.969 37.215-83.231 83.108-83.231a82.864 82.864 0 0 1 30.168 5.654c13.049-27.358 40.921-46.254 73.21-46.254 2.012 0 3.991.071 5.955.214C201.8 190.778 244.589 154 295.946 154c39.955 0 74.715 22.259 92.594 55.064 9.533-4.084 20.033-6.344 31.055-6.344 43.66 0 79.054 35.446 79.054 79.171a83.331 83.331 0 0 1 18.243-2.03c45.893 0 83.108 37.262 83.108 83.231 0 45.286-36.122 82.152-81.081 83.23h-20.175c-9.803-29.491-36.978-53.573-72.546-65.317 12.21-12.458 19.748-29.531 19.748-48.364 0-38.118-30.849-69.02-68.919-69.02-38.07 0-68.919 30.902-68.919 69.02 0 18.833 7.538 35.906 19.748 48.364-11.83 3.901-22.757 9.159-32.417 15.534-6.619 4.369-12.653 9.262-17.974 14.607-8.425-7.034-18.116-12.862-28.695-17.184 9.169-10.388 14.744-24.035 14.744-38.991 0-32.511-26.32-58.87-58.784-58.87s-58.784 26.359-58.784 58.87c0 14.956 5.574 28.603 14.743 38.991-25.163 10.277-45.196 29.086-55.584 52.36H81.081Z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M459.852 485.376 398.925 300l159.424-114.547H361.201L300.275 0h197.162l60.989 185.438c35.314 107.518-1.112 229.866-98.867 299.907l.293.031Zm-318.939 0L300.336 600l159.516-114.624-159.423-114.547-159.516 114.547Zm-98.558-300C5.079 298.811 48.349 418.95 140.867 485.422v-.046L201.794 300 42.37 185.376l197.117.062L300.275 0H103.004l-60.65 185.376Z" fill="#EB5424"/></svg>

After

Width:  |  Height:  |  Size: 455 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M96.958 396.5H.195v-91.924H193.6c-2.521 51.193-44.824 91.924-96.641 91.924Z" fill="#7BCD54"/><path d="M96.957 202.977H.195V294.9H193.6c-2.521-51.192-44.824-91.923-96.641-91.923ZM503.356 202.977c-51.817 0-94.121 40.731-96.641 91.923h193.282c-2.52-51.192-44.823-91.923-96.641-91.923Z" fill="#63C43F"/><path d="M503.356 396.5c-51.817 0-94.121-40.731-96.641-91.924h193.282c-2.52 51.193-44.823 91.924-96.641 91.924Z" fill="#7BCD54"/><path d="M203.395 202.977v96.762c0 51.817 40.731 94.12 91.924 96.641V202.977h-91.924Z" fill="#63C43F"/><path d="M396.922 396.501h-91.926V202.977h91.926v193.524Z" fill="#7BCD54"/></g><defs><clipPath id="a"><path fill="#fff" transform="translate(0 203)" d="M0 0h600v193.5H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 836 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M600 313.996c0-50.02-31.192-93.978-78.107-110.903a169.795 169.795 0 0 0 3.044-32.084C524.937 77.789 448.859 2 355.538 2c-54.777 0-105.496 26.02-137.449 69.978-15.723-12.126-34.994-18.694-55.028-18.694-49.705 0-90.026 40.168-90.026 89.683 0 10.863 2.028 21.474 5.579 31.326C31.953 190.967 0 235.682 0 285.449c0 50.273 31.445 94.231 78.36 111.158-2.028 10.358-3.043 21.22-3.043 32.082 0 92.969 75.825 168.504 169.147 168.504 54.776 0 105.494-26.272 137.193-70.231 15.723 12.379 34.996 19.2 55.03 19.2 49.703 0 90.025-40.167 90.025-89.683 0-10.863-2.029-21.473-5.579-31.327C567.794 408.48 600 363.765 600 313.996Z" fill="#fff"/><path d="m237.006 258.654 130.334 59.815 131.342-116.08c2.012-9.632 2.767-19.009 2.767-29.148 0-81.61-65.922-148.014-146.941-148.014-48.56 0-93.599 24.078-121.025 64.376L211.594 203.91l25.412 54.745Z" fill="#FED10A"/><path d="M98.438 397.96c-2.026 9.685-2.786 19.623-2.786 29.817 0 82.32 66.605 149.093 148.403 149.093 49.13 0 94.968-24.467 122.573-65.244l21.778-114.43-29.123-56.07-131.689-60.401L98.438 397.96Z" fill="#24BBB1"/><path d="m100.032 171.886 91.466 21.737 20.096-104.288c-12.367-9.575-27.825-14.75-43.8-14.75-39.678 0-72.142 32.347-72.142 72.458 0 8.539 1.546 17.08 4.38 24.843Z" fill="#EF5098"/><path d="M88.903 193.623c-40.301 13.109-68.614 51.433-68.614 93.538 0 41.096 25.762 77.655 64.278 92.278l127.026-113.456-23.212-49.164-99.478-23.196Z" fill="#1BA9F5"/><path d="M391.297 509.966c12.337 9.341 27.191 14.643 42.549 14.643 38.772 0 70.494-31.559 70.494-70.69 0-8.584-1.51-16.917-4.28-24.49l-89.124-20.955-19.639 101.492Z" fill="#93C83E"/><path d="m408.86 385.531 99.395 22.943c40.524-13.111 68.557-51.434 68.557-93.791 0-40.844-25.74-77.655-64.224-92.026l-129.979 112.7 26.251 50.174Z" fill="#07C"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M593.251 306.75c0-19.75-1.75-38.5-4.75-56.75H306v112.75h161.75c-7.25 37-28.5 68.25-60 89.501v75h96.5c56.501-52.25 89.001-129.251 89.001-220.501Z" fill="#4285F4"/><path d="M306.001 600.001c81 0 148.75-27 198.25-72.751l-96.5-75c-27 18-61.25 29-101.75 29-78.251 0-144.501-52.75-168.251-124h-99.5v77.25c49.25 98 150.5 165.501 267.751 165.501Z" fill="#34A853"/><path d="M137.75 357.25c-6.25-18-9.5-37.25-9.5-57.25s3.5-39.25 9.5-57.25V165.5h-99.5C17.75 206 6 251.5 6 300s11.75 94 32.25 134.501l99.5-77.251Z" fill="#FBBC05"/><path d="M306.001 118.75c44.25 0 83.75 15.25 115 45l85.5-85.5C454.751 29.75 387.001 0 306.001 0 188.75 0 87.501 67.5 38.25 165.5l99.5 77.251c23.75-71.251 90-124.001 168.251-124.001Z" fill="#EA4335"/></svg>

After

Width:  |  Height:  |  Size: 809 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M81.081 446.322C36.122 445.244 0 408.378 0 363.092c0-45.969 37.215-83.231 83.108-83.231a82.864 82.864 0 0 1 30.168 5.654c13.049-27.358 40.921-46.254 73.21-46.254 2.012 0 3.991.071 5.955.214C201.8 190.778 244.589 154 295.946 154c39.955 0 74.715 22.259 92.594 55.064 9.533-4.084 20.033-6.344 31.055-6.344 43.66 0 79.054 35.446 79.054 79.171a83.331 83.331 0 0 1 18.243-2.03c45.893 0 83.108 37.262 83.108 83.231 0 45.286-36.122 82.152-81.081 83.23h-20.175c-9.803-29.491-36.978-53.573-72.546-65.317 12.21-12.458 19.748-29.531 19.748-48.364 0-38.118-30.849-69.02-68.919-69.02-38.07 0-68.919 30.902-68.919 69.02 0 18.833 7.538 35.906 19.748 48.364-11.83 3.901-22.757 9.159-32.417 15.534-6.619 4.369-12.653 9.262-17.974 14.607-8.425-7.034-18.116-12.862-28.695-17.184 9.169-10.388 14.744-24.035 14.744-38.991 0-32.511-26.32-58.87-58.784-58.87s-58.784 26.359-58.784 58.87c0 14.956 5.574 28.603 14.743 38.991-25.163 10.277-45.196 29.086-55.584 52.36H81.081Z" fill="#002B49"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,23 @@
<svg width="600" height="600" viewBox="0 0 600 600" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8150_20)">
<path d="M78.6386 163.123L156.203 29.0543L468.552 29L545.709 164.427L545.804 435.309L468.579 570.628L156.312 570.737L77.8516 435.309L78.6386 163.123Z" fill="#4D4D4D"/>
<path d="M77.8496 435.268H218.636L141.302 298.808L204.184 163.149L78.6367 163.122L0 299.909" fill="#EDEDED"/>
<path d="M261.325 435.269H364.21L455.209 302.451L365.798 164.428H244.742L171.832 297.803L261.325 435.269Z" fill="#E0E0E0"/>
<path d="M0 299.896L77.8632 435.309H218.636L142.157 300.358L0 299.896Z" fill="#ACACAC"/>
<path d="M173.34 299.923L261.326 435.323H364.212L453.786 299.977L173.34 299.923Z" fill="#9E9E9E"/>
<path d="M208.188 300.017L181.619 307.75L156.148 299.977L260.188 119.389L286.214 164.454" fill="#00B8E3"/>
<path d="M286.119 435.282L260.214 480.564L191.104 405.994L156.094 300.031V299.977H208.174" fill="#33C6E9"/>
<path d="M156.146 299.977H156.106V300.017L130.079 345.164L103.957 300.221L130.445 254.204L208.173 119.389H260.199" fill="#008AAA"/>
<path d="M442.443 435.269H600.002L599.907 164.414H442.43L442.443 435.269Z" fill="#D4D4D4"/>
<path d="M442.441 300.357V435.309H599.715V300.357H442.441Z" fill="#919191"/>
<path d="M260.226 480.606H208.172L130.078 345.165L156.105 300.031L260.226 480.606Z" fill="#00B8E3"/>
<path d="M468.4 299.977L364.334 480.578C354.767 466.499 338.375 435.309 338.375 435.309L416.442 299.963L468.4 299.977Z" fill="#008AAA"/>
<path d="M416.322 480.578L364.336 480.565L468.416 299.977L494.429 254.898L520.496 300.289M468.416 299.977H416.457L338.363 164.441L364.214 119.402L427.422 199.884L468.416 299.977Z" fill="#00B8E3"/>
<path d="M494.415 254.843V254.884L468.402 299.977L364.227 119.416L416.348 119.443L494.415 254.843Z" fill="#33C6E9"/>
</g>
<defs>
<clipPath id="clip0_8150_20">
<rect width="600" height="600" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M126.732 467.734c12.934 8.066 34.434 17.033 57.167 17.033 20.7 0 39.933-6 55.867-16.233 0 0 .033 0 .066-.034l60.167-37.6v135.767c-9.533 0-19.133-2.6-27.467-7.8l-145.8-91.133Z" fill="#225086"/><path d="m261.767 50.234-250 282c-19.3 21.8-14.267 54.733 10.766 70.367 0 0 92.534 57.833 104.2 65.133 12.934 8.067 34.434 17.033 57.167 17.033 20.7 0 39.933-6 55.867-16.233 0 0 .033 0 .066-.033l60.167-37.6-145.467-90.934 145.5-164.133v-142.5c-14.133 0-28.266 5.633-38.266 16.9Z" fill="#6DF"/><path d="m154.533 339.967 1.734 1.067L300 430.901h.033V175.867l-.033-.033-145.467 164.133Z" fill="#CBF8FF"/><path d="M577.468 402.6c25.034-15.633 30.067-48.567 10.767-70.367L424.202 147.2a103.399 103.399 0 0 0-43.767-9.7c-30.833 0-58.4 13.3-76.733 34.2l-3.634 4.1 145.467 164.133-145.5 90.934v135.766c9.567 0 19.1-2.6 27.433-7.8l250-156.266v.033Z" fill="#074793"/><path d="M300.033 33.334v142.5l3.634-4.1c18.333-20.9 45.9-34.2 76.733-34.2 15.733 0 30.533 3.567 43.767 9.7L338.2 50.267c-9.967-11.266-24.1-16.9-38.2-16.9l.033-.033Z" fill="#0294E4"/><path d="m445.502 339.967-145.467-164.1v255l145.467-90.9Z" fill="#96BCC2"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)" fill="#1976D2"><path d="M271.429 371.286V357h185.714v28.571l71.428-50-71.428-50v28.572H42.857V99.857H400V157h42.857V78.429c0-11.858-9.571-21.429-21.428-21.429h-400C9.57 57 0 66.571 0 78.429V335.57C0 347.429 9.571 357 21.429 357H200v14.286c0 23.714-19.143 42.857-42.857 42.857h-42.857V457h242.857v-42.857h-42.857c-23.715 0-42.857-19.143-42.857-42.857Z"/><path d="M578.572 185.571H280.715c-8-16.857-25.143-28.571-45-28.571-27.572 0-50 22.429-50 50s22.428 50 50 50c19.857 0 37-11.714 45-28.571h276.428v242.857H428.572v-85.715h-42.857v135.715c0 11.857 9.571 21.428 21.428 21.428h171.429c11.857 0 21.429-9.571 21.429-21.428V207c0-11.857-9.572-21.429-21.429-21.429ZM471.429 514.143v-14.286h42.857v14.286h-42.857Z"/></g><defs><clipPath id="a"><path fill="#fff" transform="translate(0 57)" d="M0 0h600v485.714H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 931 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M547.991 279.316c0 162.64-194.461 289.924-236.888 318.209-3.536 3.536-10.607 3.536-17.679 0C250.996 572.776 53 441.956 53 279.316V84.856c0-7.072 7.071-14.143 14.143-14.143C219.176 67.177 187.355 0 300.496 0c113.14 0 77.784 67.177 229.817 70.713 7.071 0 14.143 7.071 14.143 14.143l3.535 194.46Z" fill="#1B93EB"/><path d="M526.778 279.316c0 148.498-180.318 268.71-219.21 289.924-3.536 3.535-10.607 3.535-14.143 0-38.892-24.75-219.21-144.962-219.21-289.924V102.534c0-7.071 3.535-14.143 10.607-17.678C222.712 81.32 190.89 21.214 296.96 21.214c106.069 0 74.248 63.642 212.139 63.642 7.071 0 14.143 7.07 14.143 14.142l3.535 180.318Z" fill="url(#b)"/><path d="M300.495 212.139c49.499 0 91.927 38.892 98.998 88.391 0 7.071 10.607 14.143 17.679 14.143h49.499c10.607 0 17.678-7.072 17.678-17.679v-3.535c-10.607-102.534-102.534-176.783-205.068-166.176-88.391 10.607-155.569 77.784-166.176 166.176 0 10.607 7.072 17.678 14.143 17.678h53.035c7.071 0 14.142-7.071 17.678-14.143 10.607-49.499 53.035-84.855 102.534-84.855Z" fill="#C3F1FF"/><path d="M300.496 378.315c37.101 0 67.177-30.077 67.177-67.178s-30.076-67.177-67.177-67.177c-37.101 0-67.178 30.076-67.178 67.177 0 37.101 30.077 67.178 67.178 67.178Z" fill="#fff"/></g><defs><linearGradient id="b" x1="300.497" y1="552.622" x2="300.497" y2="2.121" gradientUnits="userSpaceOnUse"><stop stop-color="#1B93EB"/><stop offset=".21" stop-color="#2095EB"/><stop offset=".44" stop-color="#2E9CED"/><stop offset=".69" stop-color="#45A7EF"/><stop offset=".95" stop-color="#64B6F1"/><stop offset="1" stop-color="#6BB9F2"/></linearGradient><clipPath id="a"><path fill="#fff" transform="translate(53)" d="M0 0h494.991v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="m330.104 4.167-12.342 152c-5.837-.667-11.675-1-17.679-1-7.505 0-14.843.5-22.015 1.666l-7.004-73.666c-.167-2.334 1.668-4.334 4.002-4.334h12.509l-6.004-74.5C281.404 2 283.239 0 285.407 0h40.861c2.335 0 4.169 2 3.836 4.333v-.166Zm-103.07 7.5c-.667-2.167-3.002-3.5-5.17-2.667l-38.36 14c-2.168.833-3.169 3.333-2.168 5.333l31.188 68-11.841 4.334c-2.169.833-3.169 3.333-2.169 5.333l31.855 66.833a143.073 143.073 0 0 1 37.192-14.166l-40.36-147h-.167ZM132.97 54l88.227 124.333c-11.175 7.334-21.348 16-30.021 26l-52.869-52c-1.668-1.666-1.501-4.333.167-5.833l9.673-8-52.536-53.167c-1.668-1.666-1.5-4.333.334-5.833l31.188-26.167c1.834-1.5 4.336-1.166 5.67.667h.167Zm-74.05 72c-1.835-1.333-4.504-.667-5.67 1.333l-20.348 35.334c-1.168 2-.334 4.5 1.668 5.5l67.712 32L95.945 211c-1.168 2-.334 4.667 1.834 5.5l67.379 30.833c4.837-12.5 11.341-24.166 19.347-34.666L58.92 126ZM9.052 222c.334-2.333 2.669-3.667 4.837-3.167l147.6 38.5c-3.836 12.5-6.004 25.667-6.337 39.334l-73.884-6A3.85 3.85 0 0 1 77.766 286l2.168-12.333-74.55-7C3.047 266.5 1.546 264.333 1.88 262l7.005-40.167.166.167ZM3.55 321.667c-2.335.166-3.836 2.333-3.503 4.666L7.218 366.5c.333 2.333 2.668 3.667 4.836 3.167l72.383-18.834 2.168 12.334c.334 2.333 2.668 3.666 4.837 3.166l71.382-19.666c-4.17-12.334-6.838-25.5-7.506-39l-151.936 14h.167ZM27.23 427.333c-1.167-2-.333-4.5 1.668-5.5L166.66 356.5c5.171 12.333 12.175 23.833 20.514 34.167l-60.374 43c-1.835 1.333-4.503.833-5.67-1.167l-6.338-11L53.249 464c-1.835 1.333-4.503.667-5.67-1.333l-20.514-35.334h.166Zm166.947-28.666-107.24 108.5c-1.667 1.666-1.5 4.333.334 5.833l31.355 26.167c1.834 1.5 4.336 1.166 5.67-.667l43.363-61 9.673 8.167c1.835 1.5 4.503 1.166 5.838-.834l42.028-61c-11.341-7-21.848-15.5-30.854-25.166h-.167Zm-21.181 174.166c-2.168-.833-3.169-3.333-2.168-5.333l63.543-138.667c11.675 6 24.35 10.5 37.526 13l-18.68 71.667c-.5 2.167-3.002 3.5-5.17 2.667l-11.841-4.334L216.36 584c-.667 2.167-3.002 3.5-5.17 2.667l-38.36-14 .167.166Zm109.408-129.166-12.342 152c-.167 2.333 1.668 4.333 3.836 4.333h40.861c2.335 0 4.17-2 3.836-4.333l-6.004-74.5H325.1c2.335 0 4.17-2 4.003-4.334l-7.005-73.666c-7.171 1.166-14.509 1.666-22.015 1.666-6.004 0-11.841-.333-17.678-1.166Zm147.1-411.5c1-2.167 0-4.5-2.168-5.334l-38.36-14c-2.168-.833-4.503.5-5.17 2.667L363.96 87.667l-11.841-4.334c-2.168-.833-4.503.5-5.17 2.667l-18.68 71.667c13.343 2.666 25.851 7.166 37.526 13l63.71-138.5Zm83.723 60.5-107.239 108.5A145.541 145.541 0 0 0 375.134 176l42.029-61c1.334-1.833 4.003-2.333 5.837-.833l9.673 8.166 43.363-61c1.335-1.833 4.003-2.166 5.671-.666l31.354 26.166c1.835 1.5 1.835 4.167.334 5.834h-.167ZM571.268 178c2.168-1 2.835-3.5 1.667-5.5l-20.513-35.333c-1.168-2-3.836-2.5-5.671-1.334l-61.542 42.5-6.337-10.833c-1.168-2-3.836-2.667-5.671-1.167l-60.374 43c8.339 10.334 15.177 21.834 20.514 34.167l137.76-65.333.167-.167Zm21.681 55.333 7.005 40.167c.333 2.333-1.168 4.333-3.503 4.667l-151.936 14.166c-.667-13.666-3.336-26.666-7.505-39l71.382-19.666c2.168-.667 4.503.833 4.836 3.166l2.168 12.334 72.383-18.834c2.168-.5 4.503.834 4.836 3.167l.334-.167Zm-6.838 147.5c2.168.5 4.503-.833 4.837-3.166l7.004-40.167c.334-2.333-1.167-4.333-3.502-4.667l-74.551-7 2.169-12.333c.333-2.333-1.168-4.333-3.503-4.667l-73.883-6c-.334 13.667-2.502 26.834-6.338 39.334l147.6 38.5.167.166Zm-39.36 91.667c-1.167 2-3.836 2.5-5.671 1.333l-125.585-86.666c8.006-10.5 14.51-22.167 19.347-34.667l67.379 30.833c2.168 1 3.002 3.5 1.834 5.5l-6.337 10.834 67.712 32c2.002 1 2.836 3.5 1.668 5.5L546.751 472.5Zm-167.947-51.167 88.226 124.334c1.334 1.833 4.003 2.166 5.671.666l31.188-26.166c1.834-1.5 1.834-4.167.333-5.834l-52.536-53.166 9.674-8c1.834-1.5 1.834-4.167.166-5.834l-52.869-52c-8.839 10-18.846 18.834-30.02 26h.167Zm-.834 169.334c-2.168.833-4.503-.5-5.171-2.667l-40.36-147a143.04 143.04 0 0 0 37.192-14.167l31.855 66.834c1 2.166 0 4.666-2.168 5.333l-11.842 4.333 31.188 68c1.001 2.167 0 4.5-2.168 5.334l-38.36 14h-.166Z" fill="#191919"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><circle cx="300" cy="300" r="300" fill="#1C1F2A"/><path d="M229.85 204.478a8.955 8.955 0 0 0-8.955 8.955v53.731a8.955 8.955 0 0 0 8.955 8.955h43.283V405.97a8.955 8.955 0 0 0 8.956 8.955h53.731a8.955 8.955 0 0 0 8.955-8.955V213.433a8.955 8.955 0 0 0-8.955-8.955H229.85Z" fill="#fff"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 473 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="600" height="600" rx="300" fill="#192FFF"/><path d="m445.835 230.057-23.98 44.93a4.887 4.887 0 0 0-.543 3.076l8.728 66.101c.415 3.108-.927 6.215-3.485 7.996l-49.686 35.154a5.108 5.108 0 0 0-1.726 2.137l-24.395 57.199c-1.376 3.205-4.285 5.471-7.706 5.989l-42.076 6.215a12.657 12.657 0 0 1-3.837 0l-42.076-6.215c-3.421-.518-6.331-2.784-7.706-5.989l-24.395-57.199c-.351-.874-.959-1.586-1.726-2.137l-49.686-35.122a8.427 8.427 0 0 1-3.485-7.996l8.729-66.101a5.357 5.357 0 0 0-.544-3.075l-24.043-44.963a10.537 10.537 0 0 1-1.183-5.406l1.151-19.682c.223-3.625 2.302-6.83 5.531-8.448l13.684-6.863a12.336 12.336 0 0 1 12.15.615l30.726 19.455a4.928 4.928 0 0 0 4.092.55l76.799-23.695a13.132 13.132 0 0 1 7.737 0l76.799 23.695a4.93 4.93 0 0 0 4.093-.55l30.725-19.455a12.336 12.336 0 0 1 12.15-.615l13.652 6.863a10.15 10.15 0 0 1 5.532 8.448l1.151 19.682c.095 1.877-.288 3.755-1.184 5.406h.033Z" fill="#F7F9FC"/></svg>

After

Width:  |  Height:  |  Size: 996 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M554.306 249h-80.082c1.214 1.237 2.429 2.518 3.533 3.865 8.967 10.866 13.693 24.515 13.693 39.533 0 23.19-9.761 44.105-25.442 58.196h49.03l23.3-57.909h-29.153l4.859-22.461h57.909l-30.412 80.37h11.926c27.761.177 46.534-22.881 46.534-50.885 0-28.005-17.889-50.709-45.717-50.709" fill="#E85E26"/><path fill-rule="evenodd" clip-rule="evenodd" d="M67.887 249c22.397 0 35.208 12.19 35.208 28.798 0 18.112-11.906 33.262-30.79 36.221l15.753 36.575H62.72l-14.77-34.897H33.085l-7.687 34.897H0L22.31 249h45.577Zm-30.169 45.431h24.674c9.714 0 15.417-6.471 15.417-14.248 0-2.334-.69-4.378-1.993-5.996-1.993-2.467-5.4-3.943-9.939-3.943h-22.81l-5.349 24.187ZM99.385 350.594 158.395 249h29.997l22.241 101.594h-25.338l-3.71-16.853h-46.992l-9.878 16.853h-25.33Zm69.303-75.488-21.776 37.455h30.014l-8.238-37.455ZM245.375 249h42.954c21.646.022 35.001 12.035 35.001 29.177 0 19.234-14.658 37.477-38.866 37.477H256.15l-7.73 34.94h-25.355L245.375 249Zm15.46 45.431h22.525c9.007 0 14.865-6.471 14.865-14.248 0-6.25-4.754-9.939-12.484-9.939h-19.609l-5.297 24.187Z" fill="#000"/><path d="M372.41 249h-25.398l-22.353 101.594h25.398L372.41 249Z" fill="#000"/><path fill-rule="evenodd" clip-rule="evenodd" d="M423.759 249c16.961 0 31.334 5.961 40.039 16.564 5.849 7.001 9.214 16.099 9.214 26.835 0 17.224-6.738 37.503-25.735 49.028-9.343 5.634-21.577 9.167-37.477 9.167h-40.97L391.2 249h32.559Zm-24.872 80.393h14.028c21.861 0 34.94-16.302 34.94-34.63 0-13.627-8.153-24.519-22.681-24.519h-13.251l-13.036 59.149Z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M64.03 318.824c0 3.985-.84 7.658-2.54 11.038-1.68 3.38-4.043 6.232-7.051 8.596s-6.602 4.201-10.763 5.529c-4.16 1.329-8.712 1.973-13.654 1.973-5.918 0-11.212-.801-15.92-2.422-4.707-1.622-9.395-4.298-14.102-8.03l7.774-12.64c3.731 3.126 7.09 5.412 10.118 6.857 3.009 1.446 6.075 2.169 9.22 2.169 3.868 0 6.954-.977 9.317-2.989 2.364-2.013 3.516-4.689 3.516-8.069 0-1.446-.215-2.813-.644-4.083-.43-1.27-1.192-2.559-2.344-3.908-1.133-1.328-2.696-2.774-4.708-4.337-1.973-1.563-4.532-3.497-7.676-5.802-2.403-1.7-4.766-3.439-7.032-5.236a50.634 50.634 0 0 1-6.231-5.802 26.532 26.532 0 0 1-4.512-6.877c-1.133-2.54-1.72-5.432-1.72-8.675 0-3.731.782-7.17 2.345-10.237a23.325 23.325 0 0 1 6.406-7.854c2.696-2.188 5.939-3.868 9.747-5.06 3.79-1.192 7.892-1.817 12.365-1.817 4.707 0 9.24.645 13.634 1.876 4.395 1.27 8.458 3.087 12.208 5.49l-7.051 11.37c-4.825-3.38-9.884-5.06-15.197-5.06-3.242 0-5.938.84-8.048 2.54-2.129 1.699-3.164 3.809-3.164 6.349s.918 4.591 2.793 6.526c1.856 1.934 5.06 4.649 9.63 8.146 4.59 3.38 8.419 6.35 11.447 8.89 3.027 2.539 5.41 4.923 7.168 7.17 1.758 2.246 2.97 4.493 3.633 6.798.665 2.306.997 4.826.997 7.6h.058l-.02-.019Zm105.264-22.233c0 7.111-1.074 13.656-3.282 19.634-2.187 5.979-5.196 11.175-9.083 15.649-3.887 4.474-8.457 7.932-13.79 10.394-5.313 2.462-11.056 3.692-17.248 3.692-2.774 0-5.371-.234-7.794-.722a25.875 25.875 0 0 1-6.895-2.443c-2.168-1.133-4.317-2.618-6.446-4.434-2.129-1.817-4.317-4.045-6.621-6.702V389H74.89V253.356h23.245l.117 13.207c4.238-5.295 8.829-9.202 13.751-11.664 4.962-2.481 10.704-3.692 17.228-3.692 5.919 0 11.33 1.113 16.193 3.341 4.903 2.227 9.122 5.333 12.677 9.319 3.555 3.985 6.31 8.733 8.243 14.301 1.934 5.548 2.891 11.702 2.891 18.442h.039l.02-.019Zm-25.276.938c0-9.906-1.992-17.72-6.016-23.464-4.005-5.744-9.454-8.596-16.389-8.596-7.285 0-13.067 3.047-17.306 9.143-4.239 6.095-6.387 14.34-6.387 24.714 0 10.374 2.109 18.111 6.27 23.913 4.16 5.802 9.942 8.694 17.228 8.694 4.356 0 7.989-1.114 10.841-3.341 2.852-2.247 5.157-5.079 6.915-8.518 1.758-3.438 3.008-7.189 3.731-11.214.722-4.044 1.093-7.815 1.093-11.331h-.019.039Zm35.609 46.243h23.85V211h-23.85v132.772Zm125.735.039v-90.572h-23.85v48.744c0 4.337-.176 7.697-.547 10.061a25.839 25.839 0 0 1-1.817 6.448c-3.379 7.482-9.551 11.233-18.537 11.233-7.012 0-11.934-2.54-14.728-7.619-1.093-1.915-1.855-4.103-2.285-6.525-.43-2.423-.645-5.92-.645-10.531v-51.811h-23.85v51.46c0 3.497.039 6.466.098 8.889.059 2.422.215 4.552.469 6.447.234 1.876.527 3.536.82 4.982a19.198 19.198 0 0 0 1.368 4.161c2.187 5.568 5.703 9.769 10.606 12.601 4.903 2.833 10.9 4.24 18.01 4.24 6.407 0 12.013-1.114 16.857-3.341 4.844-2.247 9.532-5.88 14.142-10.96l.058 12.113h23.85v-.039h-.019v.019Zm102.881-.039v-51.343c0-3.497-.039-6.486-.098-8.947-.058-2.482-.195-4.592-.468-6.428a41.409 41.409 0 0 0-.899-4.787 42.825 42.825 0 0 0-1.27-4.083c-2.187-5.411-5.703-9.592-10.606-12.562-4.903-2.969-10.9-4.435-18.049-4.435-6.407 0-12.013 1.114-16.857 3.361-4.844 2.246-9.532 5.9-14.142 10.96l-.039-12.113H321.75v90.377h24.065v-48.783c0-4.22.156-7.502.469-9.847.312-2.344.879-4.532 1.738-6.603 1.563-3.615 3.965-6.369 7.188-8.225 3.223-1.856 7.052-2.794 11.545-2.794 7.012 0 11.934 2.54 14.728 7.58 1.074 1.915 1.836 4.103 2.265 6.506.43 2.403.645 5.9.645 10.491v51.695h23.85v-.02Zm98.779-5.958-36.351-45.209 30.745-32.919-18.088-7.776-31.995 37.061h-2.539V211h-24.065v132.753h24.065v-48.1l35.98 49.917 22.248-7.776h.02l-.02.02ZM600 305.363v-14.809l-72.331-36.299v16.254l56.06 27.293-56.06 27.645v15.903L600 305.402v-.039Z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="600"><path d="M600 0H0v600h600V0Z" fill="#fff"/></mask><g mask="url(#b)"><path fill-rule="evenodd" clip-rule="evenodd" d="m330.104 4.167-12.342 152c-5.837-.667-11.675-1-17.679-1-7.505 0-14.843.5-22.015 1.666l-7.004-73.666c-.167-2.334 1.668-4.334 4.002-4.334h12.509l-6.004-74.5C281.404 2 283.239 0 285.407 0h40.861c2.335 0 4.169 2 3.836 4.333v-.166Zm-103.07 7.5c-.667-2.167-3.002-3.5-5.17-2.667l-38.36 14c-2.168.833-3.169 3.333-2.168 5.333l31.188 68-11.841 4.334c-2.169.833-3.169 3.333-2.169 5.333l31.855 66.833a143.073 143.073 0 0 1 37.192-14.166l-40.36-147h-.167ZM132.97 54l88.227 124.333c-11.175 7.334-21.348 16-30.021 26l-52.869-52c-1.668-1.666-1.501-4.333.167-5.833l9.673-8-52.536-53.167c-1.668-1.666-1.5-4.333.334-5.833l31.188-26.167c1.834-1.5 4.336-1.166 5.67.667h.167Zm-74.05 72c-1.835-1.333-4.504-.667-5.67 1.333l-20.348 35.334c-1.168 2-.334 4.5 1.668 5.5l67.712 32L95.945 211c-1.168 2-.334 4.667 1.834 5.5l67.379 30.833c4.837-12.5 11.341-24.166 19.347-34.666L58.92 126ZM9.052 222c.334-2.333 2.669-3.667 4.837-3.167l147.6 38.5c-3.836 12.5-6.004 25.667-6.337 39.334l-73.884-6A3.85 3.85 0 0 1 77.766 286l2.168-12.333-74.55-7C3.047 266.5 1.546 264.333 1.88 262l7.005-40.167.166.167ZM3.55 321.667c-2.335.166-3.836 2.333-3.503 4.666L7.218 366.5c.333 2.333 2.668 3.667 4.836 3.167l72.383-18.834 2.168 12.334c.334 2.333 2.668 3.666 4.837 3.166l71.382-19.666c-4.17-12.334-6.838-25.5-7.506-39l-151.936 14h.167ZM27.23 427.333c-1.167-2-.333-4.5 1.668-5.5L166.66 356.5c5.171 12.333 12.175 23.833 20.514 34.167l-60.374 43c-1.835 1.333-4.503.833-5.67-1.167l-6.338-11L53.249 464c-1.835 1.333-4.503.667-5.67-1.333l-20.514-35.334h.166Zm166.947-28.666-107.24 108.5c-1.667 1.666-1.5 4.333.334 5.833l31.355 26.167c1.834 1.5 4.336 1.166 5.67-.667l43.363-61 9.673 8.167c1.835 1.5 4.503 1.166 5.838-.834l42.028-61c-11.341-7-21.848-15.5-30.854-25.166h-.167Zm-21.181 174.166c-2.168-.833-3.169-3.333-2.168-5.333l63.543-138.667c11.675 6 24.35 10.5 37.526 13l-18.68 71.667c-.5 2.167-3.002 3.5-5.17 2.667l-11.841-4.334L216.36 584c-.667 2.167-3.002 3.5-5.17 2.667l-38.36-14 .167.166Zm109.408-129.166-12.342 152c-.167 2.333 1.668 4.333 3.836 4.333h40.861c2.335 0 4.17-2 3.836-4.333l-6.004-74.5H325.1c2.335 0 4.17-2 4.003-4.334l-7.005-73.666c-7.171 1.166-14.509 1.666-22.015 1.666-6.004 0-11.841-.333-17.678-1.166Zm147.1-411.5c1-2.167 0-4.5-2.168-5.334l-38.36-14c-2.168-.833-4.503.5-5.17 2.667L363.96 87.667l-11.841-4.334c-2.168-.833-4.503.5-5.17 2.667l-18.68 71.667c13.343 2.666 25.851 7.166 37.526 13l63.71-138.5Zm83.723 60.5-107.239 108.5A145.541 145.541 0 0 0 375.134 176l42.029-61c1.334-1.833 4.003-2.333 5.837-.833l9.673 8.166 43.363-61c1.335-1.833 4.003-2.166 5.671-.666l31.354 26.166c1.835 1.5 1.835 4.167.334 5.834h-.167ZM571.268 178c2.168-1 2.835-3.5 1.667-5.5l-20.513-35.333c-1.168-2-3.836-2.5-5.671-1.334l-61.542 42.5-6.337-10.833c-1.168-2-3.836-2.667-5.671-1.167l-60.374 43c8.339 10.334 15.177 21.834 20.514 34.167l137.76-65.333.167-.167Zm21.681 55.333 7.005 40.167c.333 2.333-1.168 4.333-3.503 4.667l-151.936 14.166c-.667-13.666-3.336-26.666-7.505-39l71.382-19.666c2.168-.667 4.503.833 4.836 3.166l2.168 12.334 72.383-18.834c2.168-.5 4.503.834 4.836 3.167l.334-.167Zm-6.838 147.5c2.168.5 4.503-.833 4.837-3.166l7.004-40.167c.334-2.333-1.167-4.333-3.502-4.667l-74.551-7 2.169-12.333c.333-2.333-1.168-4.333-3.503-4.667l-73.883-6c-.334 13.667-2.502 26.834-6.338 39.334l147.6 38.5.167.166Zm-39.36 91.667c-1.167 2-3.836 2.5-5.671 1.333l-125.585-86.666c8.006-10.5 14.51-22.167 19.347-34.667l67.379 30.833c2.168 1 3.002 3.5 1.834 5.5l-6.337 10.834 67.712 32c2.002 1 2.836 3.5 1.668 5.5L546.751 472.5Zm-167.947-51.167 88.226 124.334c1.334 1.833 4.003 2.166 5.671.666l31.188-26.166c1.834-1.5 1.834-4.167.333-5.834l-52.536-53.166 9.674-8c1.834-1.5 1.834-4.167.166-5.834l-52.869-52c-8.839 10-18.846 18.834-30.02 26h.167Zm-.834 169.334c-2.168.833-4.503-.5-5.171-2.667l-40.36-147a143.04 143.04 0 0 0 37.192-14.167l31.855 66.834c1 2.166 0 4.666-2.168 5.333l-11.842 4.333 31.188 68c1.001 2.167 0 4.5-2.168 5.334l-38.36 14h-.166Z" fill="#fff"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="600"><path d="M600 0H0v600h600V0Z" fill="#fff"/></mask><g mask="url(#b)"><path d="M300 600c165.685 0 300-134.315 300-300S465.685 0 300 0 0 134.315 0 300s134.315 300 300 300Z" fill="#fff"/><path d="M229.85 204.478a8.955 8.955 0 0 0-8.955 8.955v53.731a8.955 8.955 0 0 0 8.955 8.955h43.283V405.97a8.955 8.955 0 0 0 8.956 8.955h53.731a8.955 8.955 0 0 0 8.955-8.955V213.433a8.955 8.955 0 0 0-8.955-8.955H229.85Z" fill="#1C1F2A"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 718 B

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M554.306 249h-80.082c1.214 1.237 2.429 2.518 3.533 3.865 8.967 10.866 13.693 24.515 13.693 39.533 0 23.19-9.761 44.105-25.442 58.196h49.03l23.3-57.909h-29.153l4.859-22.461h57.909l-30.412 80.37h11.926c27.761.177 46.534-22.881 46.534-50.885 0-28.005-17.889-50.709-45.717-50.709" fill="#E85E26"/><path fill-rule="evenodd" clip-rule="evenodd" d="M67.887 249c22.397 0 35.208 12.19 35.208 28.798 0 18.112-11.906 33.262-30.79 36.221l15.753 36.575H62.72l-14.77-34.897H33.085l-7.687 34.897H0L22.31 249h45.577Zm-30.169 45.431h24.674c9.714 0 15.417-6.471 15.417-14.248 0-2.334-.69-4.378-1.993-5.996-1.993-2.467-5.4-3.943-9.939-3.943h-22.81l-5.349 24.187ZM99.385 350.594 158.395 249h29.997l22.241 101.594h-25.338l-3.71-16.853h-46.992l-9.878 16.853h-25.33Zm69.303-75.488-21.776 37.455h30.014l-8.238-37.455ZM245.375 249h42.954c21.646.022 35.001 12.035 35.001 29.177 0 19.234-14.658 37.477-38.866 37.477H256.15l-7.73 34.94h-25.355L245.375 249Zm15.46 45.431h22.525c9.007 0 14.865-6.471 14.865-14.248 0-6.25-4.754-9.939-12.484-9.939h-19.609l-5.297 24.187Z" fill="#fff"/><path d="M372.41 249h-25.398l-22.353 101.594h25.398L372.41 249Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M423.759 249c16.961 0 31.334 5.961 40.039 16.564 5.849 7.001 9.214 16.099 9.214 26.835 0 17.224-6.738 37.503-25.735 49.028-9.343 5.634-21.577 9.167-37.477 9.167h-40.97L391.2 249h32.559Zm-24.872 80.393h14.028c21.861 0 34.94-16.302 34.94-34.63 0-13.627-8.153-24.519-22.681-24.519h-13.251l-13.036 59.149Z" fill="#fff"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v600H0z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<svg width="600" height="600" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M64.03 318.824c0 3.985-.84 7.658-2.54 11.038-1.68 3.38-4.043 6.232-7.051 8.596s-6.602 4.201-10.763 5.529c-4.16 1.329-8.712 1.973-13.654 1.973-5.918 0-11.212-.801-15.92-2.422-4.707-1.622-9.395-4.298-14.102-8.03l7.774-12.64c3.731 3.126 7.09 5.412 10.118 6.857 3.009 1.446 6.075 2.169 9.22 2.169 3.868 0 6.954-.977 9.317-2.989 2.364-2.013 3.516-4.689 3.516-8.069 0-1.446-.215-2.813-.644-4.083-.43-1.27-1.192-2.559-2.344-3.908-1.133-1.328-2.696-2.774-4.708-4.337-1.973-1.563-4.532-3.497-7.676-5.802-2.403-1.7-4.766-3.439-7.032-5.236a50.634 50.634 0 0 1-6.231-5.802 26.532 26.532 0 0 1-4.512-6.877c-1.133-2.54-1.72-5.432-1.72-8.675 0-3.731.782-7.17 2.345-10.237a23.325 23.325 0 0 1 6.406-7.854c2.696-2.188 5.939-3.868 9.747-5.06 3.79-1.192 7.892-1.817 12.365-1.817 4.707 0 9.24.645 13.634 1.876 4.395 1.27 8.458 3.087 12.208 5.49l-7.051 11.37c-4.825-3.38-9.884-5.06-15.197-5.06-3.242 0-5.938.84-8.048 2.54-2.129 1.699-3.164 3.809-3.164 6.349s.918 4.591 2.793 6.526c1.856 1.934 5.06 4.649 9.63 8.146 4.59 3.38 8.419 6.35 11.447 8.89 3.027 2.539 5.41 4.923 7.168 7.17 1.758 2.246 2.97 4.493 3.633 6.798.665 2.306.997 4.826.997 7.6h.058l-.02-.019Zm105.264-22.233c0 7.111-1.074 13.656-3.282 19.634-2.187 5.979-5.196 11.175-9.083 15.649-3.887 4.474-8.457 7.932-13.79 10.394-5.313 2.462-11.056 3.692-17.248 3.692-2.774 0-5.371-.234-7.794-.722a25.875 25.875 0 0 1-6.895-2.443c-2.168-1.133-4.317-2.618-6.446-4.434-2.129-1.817-4.317-4.045-6.621-6.702V389H74.89V253.356h23.245l.117 13.207c4.238-5.295 8.829-9.202 13.751-11.664 4.962-2.481 10.704-3.692 17.228-3.692 5.919 0 11.33 1.113 16.193 3.341 4.903 2.227 9.122 5.333 12.677 9.319 3.555 3.985 6.31 8.733 8.243 14.301 1.934 5.548 2.891 11.702 2.891 18.442h.039l.02-.019Zm-25.276.938c0-9.906-1.992-17.72-6.016-23.464-4.005-5.744-9.454-8.596-16.389-8.596-7.285 0-13.067 3.047-17.306 9.143-4.239 6.095-6.387 14.34-6.387 24.714 0 10.374 2.109 18.111 6.27 23.913 4.16 5.802 9.942 8.694 17.228 8.694 4.356 0 7.989-1.114 10.841-3.341 2.852-2.247 5.157-5.079 6.915-8.518 1.758-3.438 3.008-7.189 3.731-11.214.722-4.044 1.093-7.815 1.093-11.331h-.019.039Zm35.609 46.243h23.85V211h-23.85v132.772Zm125.735.039v-90.572h-23.85v48.744c0 4.337-.176 7.697-.547 10.061a25.839 25.839 0 0 1-1.817 6.448c-3.379 7.482-9.551 11.233-18.537 11.233-7.012 0-11.934-2.54-14.728-7.619-1.093-1.915-1.855-4.103-2.285-6.525-.43-2.423-.645-5.92-.645-10.531v-51.811h-23.85v51.46c0 3.497.039 6.466.098 8.889.059 2.422.215 4.552.469 6.447.234 1.876.527 3.536.82 4.982a19.198 19.198 0 0 0 1.368 4.161c2.187 5.568 5.703 9.769 10.606 12.601 4.903 2.833 10.9 4.24 18.01 4.24 6.407 0 12.013-1.114 16.857-3.341 4.844-2.247 9.532-5.88 14.142-10.96l.058 12.113h23.85v-.039h-.019v.019Zm102.881-.039v-51.343c0-3.497-.039-6.486-.098-8.947-.058-2.482-.195-4.592-.468-6.428a41.409 41.409 0 0 0-.899-4.787 42.825 42.825 0 0 0-1.27-4.083c-2.187-5.411-5.703-9.592-10.606-12.562-4.903-2.969-10.9-4.435-18.049-4.435-6.407 0-12.013 1.114-16.857 3.361-4.844 2.246-9.532 5.9-14.142 10.96l-.039-12.113H321.75v90.377h24.065v-48.783c0-4.22.156-7.502.469-9.847.312-2.344.879-4.532 1.738-6.603 1.563-3.615 3.965-6.369 7.188-8.225 3.223-1.856 7.052-2.794 11.545-2.794 7.012 0 11.934 2.54 14.728 7.58 1.074 1.915 1.836 4.103 2.265 6.506.43 2.403.645 5.9.645 10.491v51.695h23.85v-.02Zm98.779-5.958-36.351-45.209 30.745-32.919-18.088-7.776-31.995 37.061h-2.539V211h-24.065v132.753h24.065v-48.1l35.98 49.917 22.248-7.776h.02l-.02.02ZM600 305.363v-14.809l-72.331-36.299v16.254l56.06 27.293-56.06 27.645v15.903L600 305.402v-.039Z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -6831,6 +6831,10 @@
"message": "Automatically provision users and groups with your preferred identity provider via SCIM provisioning",
"description": "the text, 'SCIM', is an acronym and should not be translated."
},
"scimIntegrationDescription": {
"message": "Automatically provision users and groups with your preferred identity provider via SCIM provisioning. Find supported integrations",
"description": "the text, 'SCIM', is an acronym and should not be translated."
},
"scimEnabledCheckboxDesc": {
"message": "Enable SCIM",
"description": "the text, 'SCIM', is an acronym and should not be translated."
@ -9025,44 +9029,103 @@
"sdksDesc": {
"message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications."
},
"setUpGithubActions": {
"message": "Set up Github Actions"
"singleSignOn": {
"message": "Single sign-on"
},
"setUpKubernetes": {
"message": "Set up Kubernetes"
"ssoDescStart": {
"message": "Configure",
"description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider."
},
"setUpGitlabCICD": {
"message": "Set up GitLab CI/CD"
"ssoDescEnd": {
"message": "for Bitwarden using the implementation guide for your Identity Provider.",
"description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider."
},
"setUpAnsible": {
"message": "Set up Ansible"
"userProvisioning":{
"message": "User provisioning"
},
"rustSDKRepo": {
"message": "View Rust repository"
"scimIntegration": {
"message": "SCIM"
},
"cSharpSDKRepo": {
"message": "View C# repository"
"scimIntegrationDescStart": {
"message": "Configure ",
"description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider"
},
"cPlusPlusSDKRepo": {
"message": "View C++ repository"
"scimIntegrationDescEnd": {
"message": "(System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider.",
"description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider"
},
"jsWebAssemblySDKRepo": {
"message": "View JS WebAssembly repository"
"bwdc":{
"message": "Bitwarden Directory Connector"
},
"javaSDKRepo": {
"message": "View Java repository"
"bwdcDesc": {
"message": "Configure Bitwarden Directory Connector to automatically provision users and groups using the implementation guide for your Identity Provider."
},
"pythonSDKRepo": {
"message": "View Python repository"
"eventManagement":{
"message": "Event management"
},
"phpSDKRepo": {
"message": "View php repository"
"eventManagementDesc":{
"message": "Integrate Bitwarden event logs with your SIEM (system information and event management) system by using the implementation guide for your platform."
},
"rubySDKRepo": {
"message": "View Ruby repository"
"deviceManagement":{
"message": "Device management"
},
"goSDKRepo": {
"message": "View Go repository"
"deviceManagementDesc":{
"message": "Configure device management for Bitwarden using the implementation guide for your platform."
},
"integrationCardTooltip":{
"message": "Launch $INTEGRATION$ implementation guide.",
"placeholders": {
"integration": {
"content": "$1",
"example": "Google"
}
}
},
"smIntegrationTooltip":{
"message": "Set up $INTEGRATION$.",
"placeholders": {
"integration": {
"content": "$1",
"example": "Google"
}
}
},
"smSdkTooltip":{
"message": "View $SDK$ repository",
"placeholders": {
"sdk": {
"content": "$1",
"example": "Rust"
}
}
},
"integrationCardAriaLabel":{
"message": "open $INTEGRATION$ implementation guide in a new tab.",
"placeholders": {
"integration": {
"content": "$1",
"example": "google"
}
}
},
"smSdkAriaLabel":{
"message": "view $SDK$ repository in a new tab.",
"placeholders": {
"sdk": {
"content": "$1",
"example": "rust"
}
}
},
"smIntegrationCardAriaLabel":{
"message": "set up $INTEGRATION$ implementation guide in a new tab.",
"placeholders": {
"integration": {
"content": "$1",
"example": "google"
}
}
},
"createNewClientToManageAsProvider": {
"message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle."

View File

@ -1,6 +1,11 @@
<app-header></app-header>
<p bitTypography="body1">{{ "scimDescription" | i18n }}</p>
<p bitTypography="body1">
{{ "scimIntegrationDescription" | i18n }}
<a bitLink target="_blank" href="https://bitwarden.com/help/about-scim/"
><i class="bwi bwi-question-circle"></i
></a>
</p>
<div *ngIf="loading">
<i

View File

@ -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;
}

View File

@ -4,7 +4,11 @@
<section class="tw-mb-9">
<p bitTypography="body1">{{ "integrationsDesc" | i18n }}</p>
<sm-integration-grid [integrations]="integrations"></sm-integration-grid>
<app-integration-grid
[integrations]="integrations"
[tooltipI18nKey]="'smIntegrationTooltip'"
[ariaI18nKey]="'smIntegrationCardAriaLabel'"
></app-integration-grid>
</section>
<section class="tw-mb-9">
@ -12,5 +16,9 @@
{{ "sdks" | i18n }}
</h2>
<p bitTypography="body1">{{ "sdksDesc" | i18n }}</p>
<sm-integration-grid [integrations]="sdks"></sm-integration-grid>
<app-integration-grid
[integrations]="sdks"
[tooltipI18nKey]="'smSdkTooltip'"
[ariaI18nKey]="'smSdkAriaLabel'"
></app-integration-grid>
</section>

View File

@ -4,14 +4,17 @@ import { By } from "@angular/platform-browser";
import { mock } from "jest-mock-extended";
import { of } from "rxjs";
import { SharedModule } from "@bitwarden/components/src/shared";
import {
IntegrationCardComponent,
IntegrationGridComponent,
} from "@bitwarden/web-vault/app/shared";
import { SYSTEM_THEME_OBSERVABLE } from "../../../../../../libs/angular/src/services/injection-tokens";
import { I18nService } from "../../../../../../libs/common/src/platform/abstractions/i18n.service";
import { ThemeType } from "../../../../../../libs/common/src/platform/enums";
import { ThemeStateService } from "../../../../../../libs/common/src/platform/theming/theme-state.service";
import { I18nPipe } from "../../../../../../libs/components/src/shared/i18n.pipe";
import { IntegrationCardComponent } from "./integration-card/integration-card.component";
import { IntegrationGridComponent } from "./integration-grid/integration-grid.component";
import { IntegrationsComponent } from "./integrations.component";
@Component({
@ -31,18 +34,12 @@ describe("IntegrationsComponent", () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
IntegrationsComponent,
IntegrationGridComponent,
IntegrationCardComponent,
MockHeaderComponent,
MockNewMenuComponent,
I18nPipe,
],
declarations: [IntegrationsComponent, MockHeaderComponent, MockNewMenuComponent],
imports: [IntegrationGridComponent, IntegrationCardComponent, SharedModule],
providers: [
{
provide: I18nService,
useValue: mock<I18nService>({ t: (key) => key }),
useValue: mock<I18nService>(),
},
{
provide: ThemeStateService,

View File

@ -1,9 +1,7 @@
import { Component } from "@angular/core";
import { IntegrationType } from "@bitwarden/common/enums";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Integration } from "./models/integration";
import { Integration } from "@bitwarden/web-vault/app/shared";
@Component({
selector: "sm-integrations",
@ -12,11 +10,10 @@ import { Integration } from "./models/integration";
export class IntegrationsComponent {
private integrationsAndSdks: Integration[] = [];
constructor(i18nService: I18nService) {
constructor() {
this.integrationsAndSdks = [
{
name: "Rust",
linkText: i18nService.t("rustSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk",
image: "../../../../../../../images/secrets-manager/sdks/rust.svg",
imageDarkMode: "../../../../../../../images/secrets-manager/sdks/rust-white.svg",
@ -24,7 +21,6 @@ export class IntegrationsComponent {
},
{
name: "GitHub Actions",
linkText: i18nService.t("setUpGithubActions"),
linkURL: "https://bitwarden.com/help/github-actions-integration/",
image: "../../../../../../../images/secrets-manager/integrations/github.svg",
imageDarkMode: "../../../../../../../images/secrets-manager/integrations/github-white.svg",
@ -32,7 +28,6 @@ export class IntegrationsComponent {
},
{
name: "GitLab CI/CD",
linkText: i18nService.t("setUpGitlabCICD"),
linkURL: "https://bitwarden.com/help/gitlab-integration/",
image: "../../../../../../../images/secrets-manager/integrations/gitlab.svg",
imageDarkMode: "../../../../../../../images/secrets-manager/integrations/gitlab-white.svg",
@ -40,35 +35,30 @@ export class IntegrationsComponent {
},
{
name: "Ansible",
linkText: i18nService.t("setUpAnsible"),
linkURL: "https://bitwarden.com/help/ansible-integration/",
image: "../../../../../../../images/secrets-manager/integrations/ansible.svg",
type: IntegrationType.Integration,
},
{
name: "C#",
linkText: i18nService.t("cSharpSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/csharp",
image: "../../../../../../../images/secrets-manager/sdks/c-sharp.svg",
type: IntegrationType.SDK,
},
{
name: "C++",
linkText: i18nService.t("cPlusPlusSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/cpp",
image: "../../../../../../../images/secrets-manager/sdks/c-plus-plus.png",
type: IntegrationType.SDK,
},
{
name: "Go",
linkText: i18nService.t("goSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/go",
image: "../../../../../../../images/secrets-manager/sdks/go.svg",
type: IntegrationType.SDK,
},
{
name: "Java",
linkText: i18nService.t("javaSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/java",
image: "../../../../../../../images/secrets-manager/sdks/java.svg",
imageDarkMode: "../../../../../../../images/secrets-manager/sdks/java-white.svg",
@ -76,35 +66,30 @@ export class IntegrationsComponent {
},
{
name: "JS WebAssembly",
linkText: i18nService.t("jsWebAssemblySDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/js",
image: "../../../../../../../images/secrets-manager/sdks/wasm.svg",
type: IntegrationType.SDK,
},
{
name: "php",
linkText: i18nService.t("phpSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/php",
image: "../../../../../../../images/secrets-manager/sdks/php.svg",
type: IntegrationType.SDK,
},
{
name: "Python",
linkText: i18nService.t("pythonSDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/python",
image: "../../../../../../../images/secrets-manager/sdks/python.svg",
type: IntegrationType.SDK,
},
{
name: "Ruby",
linkText: i18nService.t("rubySDKRepo"),
linkURL: "https://github.com/bitwarden/sdk/tree/main/languages/ruby",
image: "../../../../../../../images/secrets-manager/sdks/ruby.png",
type: IntegrationType.SDK,
},
{
name: "Kubernetes Operator",
linkText: i18nService.t("setUpKubernetes"),
linkURL: "https://bitwarden.com/help/secrets-manager-kubernetes-operator/",
image: "../../../../../../../images/secrets-manager/integrations/kubernetes.svg",
type: IntegrationType.Integration,

View File

@ -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 {}

View File

@ -46,6 +46,7 @@
"../../apps/web/src/**/*.spec.ts",
"../../libs/common/src/platform/services/**/*.worker.ts",
"src/**/*.stories.ts"
"src/**/*.stories.ts",
"src/**/*.spec.ts"
]
}

View File

@ -32,6 +32,7 @@ export enum FeatureFlag {
VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint",
PM11901_RefactorSelfHostingLicenseUploader = "PM-11901-refactor-self-hosting-license-uploader",
AccessIntelligence = "pm-13227-access-intelligence",
PM14505AdminConsoleIntegrationPage = "pm-14505-admin-console-integration-page",
CriticalApps = "pm-14466-risk-insights-critical-application",
TrialPaymentOptional = "PM-8163-trial-payment",
SecurityTasks = "security-tasks",
@ -81,6 +82,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.VerifiedSsoDomainEndpoint]: FALSE,
[FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader]: FALSE,
[FeatureFlag.AccessIntelligence]: FALSE,
[FeatureFlag.PM14505AdminConsoleIntegrationPage]: FALSE,
[FeatureFlag.CriticalApps]: FALSE,
[FeatureFlag.TrialPaymentOptional]: FALSE,
[FeatureFlag.SecurityTasks]: FALSE,

View File

@ -1,4 +1,9 @@
export enum IntegrationType {
Integration = "integration",
SDK = "sdk",
SSO = "sso",
SCIM = "scim",
BWDC = "bwdc",
EVENT = "event",
DEVICE = "device",
}