diff --git a/.eslintrc.json b/.eslintrc.json index 3a4306c330..c606b8f933 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -293,6 +293,12 @@ "no-restricted-imports": ["error", { "patterns": ["@bitwarden/send-ui/*", "src/**/*"] }] } }, + { + "files": ["libs/tools/card/src/**/*.ts"], + "rules": { + "no-restricted-imports": ["error", { "patterns": ["@bitwarden/tools-card/*", "src/**/*"] }] + } + }, { "files": ["libs/vault/src/**/*.ts"], "rules": { diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index c38e0241f7..3295dfc17d 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -24,6 +24,7 @@ ./libs/tools/README.md ./libs/tools/export/vault-export/README.md ./libs/tools/send/README.md +./libs/tools/card/README.md ./libs/vault/README.md ./README.md ./LICENSE_BITWARDEN.txt diff --git a/.storybook/main.ts b/.storybook/main.ts index 28bc2aa085..454da4377d 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -19,6 +19,8 @@ const config: StorybookConfig = { "../apps/browser/src/**/*.stories.@(js|jsx|ts|tsx)", "../bitwarden_license/bit-web/src/**/*.mdx", "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", + "../libs/tools/card/src/**/*.mdx", + "../libs/tools/card/src/**/*.stories.@(js|jsx|ts|tsx)", ], addons: [ getAbsolutePath("@storybook/addon-links"), diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index e52f78583d..0a1c2bf2d1 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2647,6 +2647,15 @@ "message": "Your organization requires you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" }, + "cardMetrics": { + "message": "out of $TOTAL$", + "placeholders": { + "total": { + "content": "$1", + "example": "5" + } + } + }, "verificationRequired": { "message": "Verification required", "description": "Default title for the user verification dialog." diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index c857d952ab..e27d80e595 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -32,6 +32,7 @@ "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/vault": ["../../libs/vault/src"] }, diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 075ae5d729..4647853f71 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -1752,6 +1752,15 @@ "message": "Your organization requires you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" }, + "cardMetrics": { + "message": "out of $TOTAL$", + "placeholders": { + "total": { + "content": "$1", + "example": "5" + } + } + }, "verificationRequired": { "message": "Verification required", "description": "Default title for the user verification dialog." diff --git a/apps/desktop/tsconfig.json b/apps/desktop/tsconfig.json index fe2c669dbc..5fa0db4d80 100644 --- a/apps/desktop/tsconfig.json +++ b/apps/desktop/tsconfig.json @@ -32,6 +32,7 @@ "@bitwarden/node/*": ["../../libs/node/src/*"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/vault": ["../../libs/vault/src"] }, "useDefineForClassFields": false diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 61894f2988..5c876e0a8a 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -7922,6 +7922,15 @@ "message": "Your organization requires you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" }, + "cardMetrics": { + "message": "out of $TOTAL$", + "placeholders": { + "total": { + "content": "$1", + "example": "5" + } + } + }, "notFound": { "message": "$RESOURCE$ not found", "placeholders": { diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 1e17de148f..3b0c897e91 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -26,6 +26,7 @@ "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/vault": ["../../libs/vault/src"], "@bitwarden/web-vault/*": ["src/*"] } diff --git a/bitwarden_license/bit-common/tsconfig.json b/bitwarden_license/bit-common/tsconfig.json index 85ba8cbf60..03f3bd2d2f 100644 --- a/bitwarden_license/bit-common/tsconfig.json +++ b/bitwarden_license/bit-common/tsconfig.json @@ -21,6 +21,7 @@ ], "@bitwarden/vault-export-ui": ["../../libs/tools/export/vault-export/vault-export-core/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/vault": ["../../libs/vault/src"], diff --git a/bitwarden_license/bit-web/tsconfig.json b/bitwarden_license/bit-web/tsconfig.json index 968744d796..3ccdade273 100644 --- a/bitwarden_license/bit-web/tsconfig.json +++ b/bitwarden_license/bit-web/tsconfig.json @@ -26,6 +26,7 @@ "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/vault": ["../../libs/vault/src"], "@bitwarden/web-vault/*": ["../../apps/web/src/*"], diff --git a/libs/shared/tsconfig.libs.json b/libs/shared/tsconfig.libs.json index 312a04f3b0..6057152419 100644 --- a/libs/shared/tsconfig.libs.json +++ b/libs/shared/tsconfig.libs.json @@ -22,6 +22,7 @@ "@bitwarden/key-management": ["../key-management/src"], "@bitwarden/platform": ["../platform/src"], "@bitwarden/send-ui": ["../tools/send/send-ui/src"], + "@bitwarden/tools-card": ["../tools/card/src"], "@bitwarden/node/*": ["../node/src/*"], "@bitwarden/vault": ["../vault/src"] } diff --git a/libs/tools/card/README.md b/libs/tools/card/README.md new file mode 100644 index 0000000000..5e28e62d15 --- /dev/null +++ b/libs/tools/card/README.md @@ -0,0 +1,5 @@ +## Tools Card + +Package name: `@bitwarden/tools-card` + +Generic Tools Card Component diff --git a/libs/tools/card/jest.config.js b/libs/tools/card/jest.config.js new file mode 100644 index 0000000000..b68bda8d5c --- /dev/null +++ b/libs/tools/card/jest.config.js @@ -0,0 +1,13 @@ +const { pathsToModuleNameMapper } = require("ts-jest"); + +const { compilerOptions } = require("../../../shared/tsconfig.libs"); + +/** @type {import('jest').Config} */ +module.exports = { + testMatch: ["**/+(*.)+(spec).+(ts)"], + preset: "jest-preset-angular", + setupFilesAfterEnv: ["/test.setup.ts"], + moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { + prefix: "/../../", + }), +}; diff --git a/libs/tools/card/package.json b/libs/tools/card/package.json new file mode 100644 index 0000000000..904429ba74 --- /dev/null +++ b/libs/tools/card/package.json @@ -0,0 +1,24 @@ +{ + "name": "@bitwarden/tools-card", + "version": "0.0.0", + "description": "Angular card component", + "keywords": [ + "bitwarden" + ], + "author": "Bitwarden Inc.", + "homepage": "https://bitwarden.com", + "repository": { + "type": "git", + "url": "https://github.com/bitwarden/clients" + }, + "license": "GPL-3.0", + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && tsc", + "build:watch": "npm run clean && tsc -watch" + }, + "dependencies": { + "@bitwarden/common": "file:../../../common", + "@bitwarden/components": "file:../../../components" + } +} diff --git a/libs/tools/card/src/card.component.html b/libs/tools/card/src/card.component.html new file mode 100644 index 0000000000..3fd9372087 --- /dev/null +++ b/libs/tools/card/src/card.component.html @@ -0,0 +1,7 @@ +
+ {{ title }} +
+ {{ value }} + {{ "cardMetrics" | i18n: maxValue }} +
+
diff --git a/libs/tools/card/src/card.component.ts b/libs/tools/card/src/card.component.ts new file mode 100644 index 0000000000..9305246c58 --- /dev/null +++ b/libs/tools/card/src/card.component.ts @@ -0,0 +1,30 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { TypographyModule } from "@bitwarden/components"; + +@Component({ + selector: "tools-card", + templateUrl: "./card.component.html", + standalone: true, + imports: [CommonModule, TypographyModule, JslibModule], + host: { + class: + "tw-box-border tw-bg-background tw-block tw-text-main tw-border-solid tw-border tw-border-secondary-300 tw-border [&:not(bit-layout_*)]:tw-rounded-lg tw-p-6", + }, +}) +export class CardComponent { + /** + * The title of the card + */ + @Input() title: string; + /** + * The current value of the card as emphasized text + */ + @Input() value: number; + /** + * The maximum value of the card + */ + @Input() maxValue: number; +} diff --git a/libs/tools/card/src/card.stories.ts b/libs/tools/card/src/card.stories.ts new file mode 100644 index 0000000000..94a794dba1 --- /dev/null +++ b/libs/tools/card/src/card.stories.ts @@ -0,0 +1,36 @@ +import { CommonModule } from "@angular/common"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; + +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { I18nMockService, TypographyModule } from "@bitwarden/components"; + +import { CardComponent } from "./card.component"; + +export default { + title: "Toools/Card", + component: CardComponent, + decorators: [ + moduleMetadata({ + imports: [CardComponent, CommonModule, TypographyModule], + providers: [ + { + provide: I18nService, + useFactory: () => + new I18nMockService({ + cardMetrics: (value) => `out of ${value}`, + }), + }, + ], + }), + ], +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + render: (args) => ({ + props: args, + template: /*html*/ ` + `, + }), +}; diff --git a/libs/tools/card/src/index.ts b/libs/tools/card/src/index.ts new file mode 100644 index 0000000000..d88b9db709 --- /dev/null +++ b/libs/tools/card/src/index.ts @@ -0,0 +1 @@ +export { CardComponent } from "./card.component"; diff --git a/libs/tools/card/test.setup.ts b/libs/tools/card/test.setup.ts new file mode 100644 index 0000000000..a702c63396 --- /dev/null +++ b/libs/tools/card/test.setup.ts @@ -0,0 +1 @@ +import "jest-preset-angular/setup-jest"; diff --git a/libs/tools/card/tsconfig.json b/libs/tools/card/tsconfig.json new file mode 100644 index 0000000000..52eed3035a --- /dev/null +++ b/libs/tools/card/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../shared/tsconfig.libs", + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/libs/tools/card/tsconfig.spec.json b/libs/tools/card/tsconfig.spec.json new file mode 100644 index 0000000000..919530506d --- /dev/null +++ b/libs/tools/card/tsconfig.spec.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"], + "files": ["./test.setup.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index f8ab18b498..80f70e47b0 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -31,6 +31,7 @@ "@bitwarden/importer/core": ["./libs/importer/src"], "@bitwarden/importer/ui": ["./libs/importer/src/components"], "@bitwarden/send-ui": [".libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": [".libs/tools/card/src"], "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/node/*": ["./libs/node/src/*"], "@bitwarden/vault": ["./libs/vault/src"], diff --git a/tsconfig.json b/tsconfig.json index 6764610d2f..225321663c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,6 +34,7 @@ "@bitwarden/key-management": ["./libs/key-management/src"], "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], + "@bitwarden/tools-card": ["./libs/tools/card/src"], "@bitwarden/node/*": ["./libs/node/src/*"], "@bitwarden/web-vault/*": ["./apps/web/src/*"], "@bitwarden/vault": ["./libs/vault/src"], @@ -51,6 +52,7 @@ "apps/browser/src/**/*", "libs/*/src/**/*", "libs/tools/send/**/src/**/*", + "libs/tools/card/src/**/*", "bitwarden_license/bit-web/src/**/*", "bitwarden_license/bit-common/src/**/*" ],