From f003c0cc8d81191e6b625aaddcd849f0f8817a34 Mon Sep 17 00:00:00 2001 From: ha2605 Date: Mon, 2 Dec 2024 16:05:54 +0530 Subject: [PATCH 01/11] added secrets and utilised orbs to fetch secrets --- .circleci/config.yml | 104 +++++++++++++ terraform-secret-rotator/README.MD | 137 ++++++++++++++++++ terraform-secret-rotator/backend_configs/dev | 4 + terraform-secret-rotator/main.tf | 13 ++ terraform-secret-rotator/secret-rotator.tf | 34 +++++ terraform-secret-rotator/variables.tf | 18 +++ terraform-secret-rotator/variables/dev.tfvars | 2 + .../variables/prod.tfvars | 2 + .../variables/staging.tfvars | 1 + 9 files changed, 315 insertions(+) create mode 100644 terraform-secret-rotator/README.MD create mode 100644 terraform-secret-rotator/backend_configs/dev create mode 100644 terraform-secret-rotator/main.tf create mode 100644 terraform-secret-rotator/secret-rotator.tf create mode 100644 terraform-secret-rotator/variables.tf create mode 100644 terraform-secret-rotator/variables/dev.tfvars create mode 100644 terraform-secret-rotator/variables/prod.tfvars create mode 100644 terraform-secret-rotator/variables/staging.tfvars diff --git a/.circleci/config.yml b/.circleci/config.yml index cfeadc8da8..d4eb72d643 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,9 +9,21 @@ executors: docker: - image: cimg/node:18.19.1 resource_class: small + terraform_secret: + docker: + - image: hashicorp/terraform:1.3.4 +parameters: + deploy_secrets: + type: boolean + default: false + use_secret_rotator: + type: boolean + default: true orbs: sonarcloud: sonarsource/sonarcloud@2.0.0 + aws-cli: circleci/aws-cli@4.1.2 + aws-secrets-manager: nukengprod/aws-secrets-manager@0.3.61 commands: install-dependencies: @@ -267,6 +279,73 @@ jobs: name: Remove npm and Yarn config files command: | yarn config delete registry + plan-secret-terraform: + executor: terraform_secret + parameters: + env: + type: string + role: + type: string + region: + type: string + steps: + - checkout + - add_ssh_keys: + fingerprints: + - "SHA256:DspF5XjPpSTbO6A10IllXExrPFdhKMytxVBgNEBrYAc" + - aws-cli/setup: + role_arn: << parameters.role >> + - run: + name: Init terraform + command: | + cd terraform-secret-rotator + terraform init -backend-config=backend_configs/<< parameters.env >> + - run: + name: Plan terraform + command: | + cd terraform-secret-rotator + terraform plan -var-file=variables/<< parameters.env >>.tfvars -out=<< parameters.env >>-plan + - persist_to_workspace: + root: ./ + paths: + - terraform-secret-rotator/<< parameters.env >>-plan + + apply-secret-terraform: + executor: terraform_secret + parameters: + env: + type: string + role: + type: string + region: + type: string + steps: + - checkout + - add_ssh_keys: + fingerprints: + - "SHA256:DspF5XjPpSTbO6A10IllXExrPFdhKMytxVBgNEBrYAc" + - aws-cli/setup: + role_arn: << parameters.role >> + - run: + name: Init terraform + command: | + cd terraform-secret-rotator + terraform init -backend-config=backend_configs/<< parameters.env >> + - run: + name: Apply terraform + command: | + cd terraform-secret-rotator + terraform apply -var-file=variables/<< parameters.env >>.tfvars -auto-approve + + get_secret_gh_token_dev: + executor: node + steps: + - aws-cli/setup: + region: SECRETS_REGION + role_arn: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + - aws-secrets-manager/get-aws-secret: + aws-secret-name: times-components/dev/GH_TOKEN + only_on_pr_branch: &only_on_pr_branch filters: @@ -279,6 +358,8 @@ only_on_master_branch: &only_on_master_branch only: - master + + workflows: version: 2 @@ -347,7 +428,30 @@ workflows: <<: *only_on_pr_branch requires: - Approve canary release + - get_secret_gh_token_dev: + filters: pipeline.parameters.use_secret_rotator == true and pipeline.git.branch != "master" - publish_npm: <<: *only_on_master_branch requires: - verdaccio-test + secrets-rotator: + when: + and: + - equal: [true, << pipeline.parameters.deploy_secrets >>] + jobs: + - plan-secret-terraform: + name: plan-terraform-secret-rotator-dev + role: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + env: dev + region: eu-west-1 + - approve-apply-terraform-secret-rotator-dev: + type: approval + requires: + - plan-terraform-secret-rotator-dev + - apply-secret-terraform: + name: apply-terraform-secret-rotator-dev + role: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + env: dev + region: eu-west-1 + requires: + - approve-apply-terraform-secret-rotator-dev \ No newline at end of file diff --git a/terraform-secret-rotator/README.MD b/terraform-secret-rotator/README.MD new file mode 100644 index 0000000000..7e12d11fd4 --- /dev/null +++ b/terraform-secret-rotator/README.MD @@ -0,0 +1,137 @@ +# Secret Rotator README + +## Overview +This document provides an overview of the **Secret Rotator** implementation for managing secrets in the **Sun Savers BACS Service** environment. The secret rotator is designed to automate secret creation, rotation, and retrieval, ensuring secure and efficient secret management across environments. + +--- + +## Features +- Automated creation and rotation of secrets. +- AWS Lambda functions for specific secret rotation tasks. +- Support for multiple secret types such as API keys, passwords, and tokens. +- Integration with AWS Secrets Manager. +- Optional Slack notifications for secret rotation status. + +--- + +## Module Configuration + +### Terraform Module +The `secret_rotator` Terraform module is used to configure the secret rotation settings. + +```hcl +module "secret_rotator_times_components_dev" { + source = "git@github.com:newsuk/nuk-secret-rotator.git?ref=v0.20.0" + create_secrets = true + environment = "dev" + account = "aws-digital-dev-tnlweb" + custom_role_arn = "arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb" + create_role = false + enable_notifications = { + enable = false + slack_channel = "" + slack_token_secret_arn = "" + } + + secrets = { + "times-components/dev/GH_TOKEN" = { + description = "The Github token for dev" + recovery_window_in_days = 0 + enable_rotation = false + tags = { + Environment = "dev" + Repository = var.repository + SecretRotation = "auto" + SecretType = "external" + ServiceName = "Github" + SecretOwner = var.service_owner + } + } + } +} + +``` + +--- + +## CircleCI Integration + +### Secret Retrieval Jobs +The following jobs in the CircleCI pipeline handle secret retrieval: + +- **Retrieve ARTIFACTORY_API_KEY** +- **Retrieve ARTIFACTORY_AUTH_TOKEN** +- **Retrieve ARTIFACTORY_HELM_USERNAME** +- **Retrieve ARTIFACTORY_HELM_PASSWORD** +- **Retrieve GITHUB_API_TOKEN** + +#### Example Job for Retrieving a Secret: +```yaml +get_secret_gh_token_dev: + executor: node + steps: + - aws-cli/setup: + region: SECRETS_REGION + role_arn: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + - aws-secrets-manager/get-aws-secret: + aws-secret-name: times-components/dev/GH_TOKEN +``` + +### Secret Rotation Workflow +The workflow `secrets-rotator` automates secret creation and rotation through Terraform configurations. + +#### Workflow Steps: +1. **Plan Terraform Changes**: + - Prepares the Terraform plan for secret rotator configuration. +2. **Approval**: + - Manual approval step to proceed with applying changes. +3. **Apply Terraform Changes**: + - Executes the Terraform plan to create or update secret configurations. + +#### Example Workflow: +```yaml +secrets-rotator: + when: + and: + - equal: [true, << pipeline.parameters.deploy_secrets >>] + jobs: + - plan-secret-terraform: + name: plan-terraform-secret-rotator-dev + role: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + env: dev + region: eu-west-1 + - approve-apply-terraform-secret-rotator-dev: + type: approval + requires: + - plan-terraform-secret-rotator-dev + - apply-secret-terraform: + name: apply-terraform-secret-rotator-dev + role: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb + env: dev + region: eu-west-1 + requires: + - approve-apply-terraform-secret-rotator-dev +``` + +--- + +## Notifications (Optional) +Slack notifications can be enabled to provide updates on secret rotation status. + +```hcl +enable_notifications = { + enable = true + slack_channel = "your-slack-channel" + slack_token_secret_arn = "your-slack-token-secret-arn" +} +``` + +--- + +## Best Practices +- **Environment Isolation**: + - Use separate secrets for each environment (`dev`, `staging`, `prod`) to ensure security. +- **Access Management**: + - Restrict access to sensitive secrets and roles using AWS IAM policies. +- **Rotation Frequency**: + - Ensure critical secrets are rotated at regular intervals to maintain security. diff --git a/terraform-secret-rotator/backend_configs/dev b/terraform-secret-rotator/backend_configs/dev new file mode 100644 index 0000000000..ed69a4ec69 --- /dev/null +++ b/terraform-secret-rotator/backend_configs/dev @@ -0,0 +1,4 @@ +region = "eu-west-1" +bucket = "times-components-terraform-state" +key = "times-components/terraform.tfstate" +encrypt = true \ No newline at end of file diff --git a/terraform-secret-rotator/main.tf b/terraform-secret-rotator/main.tf new file mode 100644 index 0000000000..b9e107212e --- /dev/null +++ b/terraform-secret-rotator/main.tf @@ -0,0 +1,13 @@ +terraform { + required_version = ">= 1.3.0" +} + +provider "aws" { + region = "eu-west-1" +} + +terraform { + backend "s3" { + # managed by either backend-config configs or cli vars + } +} \ No newline at end of file diff --git a/terraform-secret-rotator/secret-rotator.tf b/terraform-secret-rotator/secret-rotator.tf new file mode 100644 index 0000000000..7126eaa89d --- /dev/null +++ b/terraform-secret-rotator/secret-rotator.tf @@ -0,0 +1,34 @@ +module "secret_rotator_times_components_dev" { + source = "git@github.com:newsuk/nuk-secret-rotator.git?ref=v0.20.0" + create_secrets = true + environment = "dev" + account = "aws-digital-dev-tnlweb" + custom_role_arn = "arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb" + create_role = false + enable_notifications = { + enable = false + slack_channel = "" + slack_token_secret_arn = "" + } + + secrets = { + "times-components/dev/GH_TOKEN" = { + description = "The Github token for dev" + recovery_window_in_days = 0 + enable_rotation = false + tags = { + Environment = "dev" + Repository = var.repository + SecretRotation = "auto" + SecretType = "external" + ServiceName = "Github" + SecretOwner = var.service_owner + } + } + } +} + + + + + diff --git a/terraform-secret-rotator/variables.tf b/terraform-secret-rotator/variables.tf new file mode 100644 index 0000000000..fc137c3ec9 --- /dev/null +++ b/terraform-secret-rotator/variables.tf @@ -0,0 +1,18 @@ +# variable "service_catalogue_id" { +# type = string +# description = "service catalogue id for times-components" +# default = "31" +# } + +variable "repository" { + type = string + description = "repository name for times-components" + default = "times-components" +} + +variable "service_owner" { + type = string + description = "service owner name for times-components" + default = "Times Media" +} + diff --git a/terraform-secret-rotator/variables/dev.tfvars b/terraform-secret-rotator/variables/dev.tfvars new file mode 100644 index 0000000000..f17f162bb1 --- /dev/null +++ b/terraform-secret-rotator/variables/dev.tfvars @@ -0,0 +1,2 @@ +environment = "dev" + diff --git a/terraform-secret-rotator/variables/prod.tfvars b/terraform-secret-rotator/variables/prod.tfvars new file mode 100644 index 0000000000..867ece2375 --- /dev/null +++ b/terraform-secret-rotator/variables/prod.tfvars @@ -0,0 +1,2 @@ +environment = "prod" + diff --git a/terraform-secret-rotator/variables/staging.tfvars b/terraform-secret-rotator/variables/staging.tfvars new file mode 100644 index 0000000000..b227228380 --- /dev/null +++ b/terraform-secret-rotator/variables/staging.tfvars @@ -0,0 +1 @@ +environment = "staging" From 164ee6ae81516489bd6d5afb8e7289104c65720a Mon Sep 17 00:00:00 2001 From: douglasmik <48333391+douglasmik@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:42:01 +0000 Subject: [PATCH 02/11] feat(TMRS-482): add CategorisedArticles (#3976) --- packages/article-extras/__tests__/shared.js | 12 ++- .../__snapshots__/article-extras.test.js.snap | 98 ++++++++++++++++++- .../article-extras/fixtures/article-extras.js | 86 +++++++++++++++- packages/article-extras/src/article-extras.js | 28 +++++- .../article-skeleton/src/article-skeleton.js | 4 +- .../related-articles/src/related-articles.js | 3 +- .../std-with-style.web.test.js.snap | 12 ++- .../web/__snapshots__/std.web.test.js.snap | 12 ++- .../src/templates/standard/index.js | 11 ++- .../src/templates/styles/responsive.js | 5 +- .../src/components/carousel/styles.ts | 1 + .../CategorisedArticles.stories.tsx | 34 +++++++ .../CategorisedArticles.tsx | 42 ++++++++ .../__tests__/CategorisedArticles.test.tsx | 27 +++++ .../CategorisedArticles.test.tsx.snap | 62 ++++++++++++ .../components/categorised-articles/styles.ts | 5 + .../features-carousel/FeaturesCarousel.tsx | 2 +- .../__tests__/index.test.tsx | 4 +- .../components/in-article-info-card/styles.ts | 1 + .../RecommendedArticles.tsx | 4 +- packages/ts-components/src/index.ts | 3 + .../__tests__/formatters.test.tsx | 6 +- .../linkedArticles}/formatters.ts | 4 +- .../linkedArticles}/styles.ts | 0 .../elements/Image/LazyImage/LazyImage.tsx | 2 +- .../__snapshots__/Image.test.tsx.snap | 3 +- 26 files changed, 440 insertions(+), 31 deletions(-) create mode 100644 packages/ts-components/src/components/categorised-articles/CategorisedArticles.stories.tsx create mode 100644 packages/ts-components/src/components/categorised-articles/CategorisedArticles.tsx create mode 100644 packages/ts-components/src/components/categorised-articles/__tests__/CategorisedArticles.test.tsx create mode 100644 packages/ts-components/src/components/categorised-articles/__tests__/__snapshots__/CategorisedArticles.test.tsx.snap create mode 100644 packages/ts-components/src/components/categorised-articles/styles.ts rename packages/ts-components/src/{components/recommended-articles => utils}/__tests__/formatters.test.tsx (94%) rename packages/ts-components/src/{components/recommended-articles => utils/linkedArticles}/formatters.ts (97%) rename packages/ts-components/src/{components/recommended-articles => utils/linkedArticles}/styles.ts (100%) diff --git a/packages/article-extras/__tests__/shared.js b/packages/article-extras/__tests__/shared.js index 5516c29a47..181c26b7af 100644 --- a/packages/article-extras/__tests__/shared.js +++ b/packages/article-extras/__tests__/shared.js @@ -11,7 +11,11 @@ import { iterator } from "@times-components/test-utils"; import { UserState } from "./mocks"; import ArticleExtras from "../src/article-extras"; -import { relatedArticleSlice, topics } from "../fixtures/article-extras"; +import { + relatedArticleSlice, + categorisedArticles, + topics +} from "../fixtures/article-extras"; const commentingConfig = { account: "sp_pCQgrRiN" @@ -45,6 +49,7 @@ export default () => { commentsEnabled registerNode={() => {}} relatedArticleSlice={relatedArticleSlice} + categorisedArticles={categorisedArticles} relatedArticlesVisible commentingConfig={commentingConfig} topics={topics} @@ -56,7 +61,7 @@ export default () => { }, { name: - "no topics and comments when user not logged in, only related articles and sponsored div", + "no topics and comments when user not logged in, only related articles, category articles, and sponsored div", test: () => { UserState.mockStates = []; const testInstance = TestRenderer.create( @@ -66,6 +71,7 @@ export default () => { commentsEnabled registerNode={() => {}} relatedArticleSlice={relatedArticleSlice} + categorisedArticles={categorisedArticles} relatedArticlesVisible commentingConfig={commentingConfig} topics={topics} @@ -85,6 +91,7 @@ export default () => { commentsEnabled registerNode={() => {}} relatedArticleSlice={relatedArticleSlice} + categorisedArticles={categorisedArticles} relatedArticlesVisible commentingConfig={commentingConfig} topics={topics} @@ -104,6 +111,7 @@ export default () => { commentsEnabled registerNode={() => {}} relatedArticleSlice={relatedArticleSlice} + categorisedArticles={categorisedArticles} relatedArticlesVisible commentingConfig={commentingConfig} topics={topics} diff --git a/packages/article-extras/__tests__/web/__snapshots__/article-extras.test.js.snap b/packages/article-extras/__tests__/web/__snapshots__/article-extras.test.js.snap index a865225724..fba06da136 100644 --- a/packages/article-extras/__tests__/web/__snapshots__/article-extras.test.js.snap +++ b/packages/article-extras/__tests__/web/__snapshots__/article-extras.test.js.snap @@ -17,6 +17,7 @@ Array [ id="related-articles" >
@@ -56,14 +57,107 @@ Array [ ] `; -exports[`2. no topics and comments when user not logged in, only related articles and sponsored div 1`] = ` +exports[`2. no topics and comments when user not logged in, only related articles, category articles, and sponsored div 1`] = ` Array [ ,
@@ -105,6 +199,7 @@ Array [ id="related-articles" >
@@ -161,6 +256,7 @@ Array [ id="related-articles" >
diff --git a/packages/article-extras/fixtures/article-extras.js b/packages/article-extras/fixtures/article-extras.js index 911f12566d..33cb315b1e 100644 --- a/packages/article-extras/fixtures/article-extras.js +++ b/packages/article-extras/fixtures/article-extras.js @@ -609,6 +609,90 @@ const relatedArticleSlice = { ], sliceName: "StandardSlice" }; + +const categorisedArticles = { + categoryArticles: { + label: "category", + articles: [ + { + bylines: [ + { + byline: [ + { + attributes: {}, + children: [ + { + attributes: { + value: "Patrick Kidd" + }, + children: [], + name: "text" + } + ], + name: "inline" + } + ] + } + ], + headline: "TMS: Pratchett’s law of the jungle - Disable Saving 2", + label: "Health", + media: { + crops: [ + { + url: + "https://www.thetimes.co.uk/imageserver/image/methode%2Ftimes%2Fprod%2Fweb%2Fbin%2F0547a7be-fb77-11e7-a987-7fcf5e9983dc.jpg?crop=1600%2C1125%2C0%2C104", + ratio: "3:2" + } + ] + }, + publicationName: "TIMES", + publishedDateTime: "2015-03-23T20:39:39.000Z", + categoryPath: "/article/tms-pratchetts-law-of-the-jungle-xgqrcw779" + } + ] + }, + parentCategoryArticles: { + label: "parent", + articles: [ + { + bylines: [ + { + byline: [ + { + attributes: {}, + children: [ + { + attributes: { + value: "Patrick Kidd" + }, + children: [], + name: "text" + } + ], + name: "inline" + } + ] + } + ], + headline: "TMS: Pratchett’s law of the jungle - Disable Saving", + label: "Health", + media: { + crops: [ + { + url: + "https://www.thetimes.co.uk/imageserver/image/methode%2Ftimes%2Fprod%2Fweb%2Fbin%2F0547a7be-fb77-11e7-a987-7fcf5e9983dc.jpg?crop=1600%2C1125%2C0%2C104", + ratio: "3:2" + } + ] + }, + publicationName: "TIMES", + publishedDateTime: "2015-03-23T19:39:39.000Z", + categoryPath: "/article/tms-pratchetts-law-of-the-jungle-xgqrcw779" + } + ] + } +}; + const topics = [ { __typename: "Topic", @@ -637,4 +721,4 @@ const topics = [ } ]; -export { relatedArticleSlice, topics }; +export { relatedArticleSlice, categorisedArticles, topics }; diff --git a/packages/article-extras/src/article-extras.js b/packages/article-extras/src/article-extras.js index 4b03cb2d9b..7c3021dbfd 100644 --- a/packages/article-extras/src/article-extras.js +++ b/packages/article-extras/src/article-extras.js @@ -5,7 +5,11 @@ import ArticleComments from "@times-components/article-comments"; import RelatedArticles from "@times-components/related-articles"; import { MessageContext } from "@times-components/message-bar"; import SaveAndShareBar from "@times-components/save-and-share-bar"; -import { RecommendedFetch, Breadcrumb } from "@times-components/ts-components"; +import { + RecommendedFetch, + Breadcrumb, + CategorisedArticles +} from "@times-components/ts-components"; import ArticleTopics from "./article-topics"; import { @@ -35,6 +39,7 @@ const ArticleExtras = ({ section, articleHeadline, relatedArticleSlice, + categorisedArticles, relatedArticlesVisible, commentingConfig, topics, @@ -56,6 +61,10 @@ const ArticleExtras = ({ return null; }; + const categoryArticles = + (categorisedArticles && categorisedArticles.categoryArticles) || null; + const parentCategoryArticles = + (categorisedArticles && categorisedArticles.parentCategoryArticles) || null; /* Nativo insert Sponsored Articles after the div#sponsored-article element. They are not able to insert directly into that element hence the container div */ const sponsoredArticlesAndRelatedArticles = ( @@ -69,6 +78,7 @@ const ArticleExtras = ({ analyticsStream={analyticsStream} isVisible={relatedArticlesVisible} slice={relatedArticleSlice} + hideBorder={!isRecommendedActive && Boolean(categoryArticles)} /> {isRecommendedActive && ( )} + {!isRecommendedActive && + categoryArticles && ( + + )} + {!isRecommendedActive && + parentCategoryArticles && ( + + )}
PROMOTED CONTENT @@ -141,6 +165,7 @@ ArticleExtras.propTypes = { commentsEnabled: PropTypes.bool.isRequired, registerNode: PropTypes.func.isRequired, relatedArticleSlice: PropTypes.shape({}), + categorisedArticles: PropTypes.shape({}), relatedArticlesVisible: PropTypes.bool.isRequired, commentingConfig: PropTypes.shape({ account: PropTypes.string.isRequired @@ -158,6 +183,7 @@ ArticleExtras.propTypes = { ArticleExtras.defaultProps = { relatedArticleSlice: null, + categorisedArticles: null, topics: null, isSharingSavingEnabled: true, isCommentEnabled: true, diff --git a/packages/article-skeleton/src/article-skeleton.js b/packages/article-skeleton/src/article-skeleton.js index d3cbc7657c..b5ec4cc79c 100644 --- a/packages/article-skeleton/src/article-skeleton.js +++ b/packages/article-skeleton/src/article-skeleton.js @@ -146,7 +146,8 @@ const ArticleSkeleton = ({ window.removeEventListener("scroll", handleScroll); }; }, []); - const { hostName, canonicalUrl, breadcrumbs } = articleDataFromRender || {}; + const { hostName, canonicalUrl, breadcrumbs, categorisedArticles } = + articleDataFromRender || {}; const articleUrl = hostName && canonicalUrl ? `${hostName}${canonicalUrl}` : url; @@ -424,6 +425,7 @@ const ArticleSkeleton = ({ commentsEnabled={commentsEnabled} registerNode={registerNode} relatedArticleSlice={relatedArticleSlice} + categorisedArticles={categorisedArticles} relatedArticlesVisible={ !!observed.get("related-articles") } diff --git a/packages/related-articles/src/related-articles.js b/packages/related-articles/src/related-articles.js index d4568b73d3..18c751ae33 100644 --- a/packages/related-articles/src/related-articles.js +++ b/packages/related-articles/src/related-articles.js @@ -13,7 +13,7 @@ class RelatedArticles extends Component { } render() { - const { isVisible, onPress, slice, heading } = this.props; + const { isVisible, onPress, slice, heading, hideBorder } = this.props; if (!slice) return null; const { items, sliceName } = slice; if ( @@ -61,6 +61,7 @@ class RelatedArticles extends Component { items.map(item => diff --git a/packages/slice-layout/__tests__/web/__snapshots__/std-with-style.web.test.js.snap b/packages/slice-layout/__tests__/web/__snapshots__/std-with-style.web.test.js.snap index 848228f9dd..63ed14ffbf 100644 --- a/packages/slice-layout/__tests__/web/__snapshots__/std-with-style.web.test.js.snap +++ b/packages/slice-layout/__tests__/web/__snapshots__/std-with-style.web.test.js.snap @@ -215,7 +215,9 @@ exports[`2. a single child element 1`] = `
- +
@@ -475,7 +477,9 @@ exports[`3. two child elements 1`] = `
- +
@@ -755,7 +759,9 @@ exports[`4. three child elements 1`] = `
- +
diff --git a/packages/slice-layout/__tests__/web/__snapshots__/std.web.test.js.snap b/packages/slice-layout/__tests__/web/__snapshots__/std.web.test.js.snap index 5fd946d4ea..c0dca9cfee 100644 --- a/packages/slice-layout/__tests__/web/__snapshots__/std.web.test.js.snap +++ b/packages/slice-layout/__tests__/web/__snapshots__/std.web.test.js.snap @@ -5,7 +5,9 @@ exports[`1. no child elements 1`] = `""`; exports[`2. a single child element 1`] = `
- +
@@ -29,7 +31,9 @@ exports[`2. a single child element 1`] = ` exports[`3. two child elements 1`] = `
- +
@@ -65,7 +69,9 @@ exports[`3. two child elements 1`] = ` exports[`4. three child elements 1`] = `
- +
diff --git a/packages/slice-layout/src/templates/standard/index.js b/packages/slice-layout/src/templates/standard/index.js index 5a6a9d8b73..88cd5445d2 100644 --- a/packages/slice-layout/src/templates/standard/index.js +++ b/packages/slice-layout/src/templates/standard/index.js @@ -19,7 +19,7 @@ class StandardSlice extends Component { } render() { - const { renderItems } = this.props; + const { renderItems, hideBorder } = this.props; const items = renderItems(this.config); @@ -28,10 +28,9 @@ class StandardSlice extends Component { } const { ChildrenContainer, ConfigWrapper } = this; - return ( - + {items .map(item => ( @@ -51,7 +50,11 @@ class StandardSlice extends Component { StandardSlice.propTypes = { itemCount: PropTypes.number.isRequired, - renderItems: PropTypes.func.isRequired + renderItems: PropTypes.func.isRequired, + hideBorder: PropTypes.bool +}; +StandardSlice.defaultProps = { + hideBorder: false }; export default StandardSlice; diff --git a/packages/slice-layout/src/templates/styles/responsive.js b/packages/slice-layout/src/templates/styles/responsive.js index 432cb077a0..94980c336c 100644 --- a/packages/slice-layout/src/templates/styles/responsive.js +++ b/packages/slice-layout/src/templates/styles/responsive.js @@ -5,13 +5,14 @@ import { breakpoints, colours, spacing } from "@times-components/ts-styleguide"; export const SliceContainer = styled(TcView)` align-items: center; border-bottom-color: ${colours.functional.keyline}; - border-bottom-width: 1px; + border-bottom-width: ${({ hideBorder }) => (hideBorder ? 0 : "1px")}; border-style: solid; flex: 1; justify-content: center; + ${({ hideBorder }) => hideBorder && "margin-bottom: 12px"}; @media (-webkit-min-device-pixel-ratio: 2) { - border-bottom-width: 0.5px; + border-bottom-width: ${({ hideBorder }) => (hideBorder ? 0 : "0.5px")}; } `; diff --git a/packages/ts-components/src/components/carousel/styles.ts b/packages/ts-components/src/components/carousel/styles.ts index cb8ba07859..d7209a779f 100644 --- a/packages/ts-components/src/components/carousel/styles.ts +++ b/packages/ts-components/src/components/carousel/styles.ts @@ -186,6 +186,7 @@ export const CarouselContainer = styled.div<{ } `; +// @ts-ignore export const StyledCarousel = styled(ReactElasticCarousel)<{ isWide: boolean; sectionColour: string; diff --git a/packages/ts-components/src/components/categorised-articles/CategorisedArticles.stories.tsx b/packages/ts-components/src/components/categorised-articles/CategorisedArticles.stories.tsx new file mode 100644 index 0000000000..8abb314e53 --- /dev/null +++ b/packages/ts-components/src/components/categorised-articles/CategorisedArticles.stories.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { TrackingContextProvider } from '../../helpers/tracking/TrackingContextProvider'; +import previewData from '../../fixtures/preview-data/recommended-articles'; +import analyticsStream from '../../fixtures/analytics-actions/analytics-actions'; +import { CategorisedArticles } from './CategorisedArticles'; + +storiesOf('Typescript Component/Categorised Articles', module).add( + 'Categorised Articles - 1 Article', + () => ( + ', + article_name: '', + widget_headline: '', + widget_section: '
', + widget_type: "today's section" + } + }} + analyticsStream={analyticsStream} + > + + + ) +); diff --git a/packages/ts-components/src/components/categorised-articles/CategorisedArticles.tsx b/packages/ts-components/src/components/categorised-articles/CategorisedArticles.tsx new file mode 100644 index 0000000000..687c8125e1 --- /dev/null +++ b/packages/ts-components/src/components/categorised-articles/CategorisedArticles.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { + Slice, + SliceArticle, + MouseEventType +} from '@times-components/ts-slices'; + +import { useTrackingContext } from '../../helpers/tracking/TrackingContextProvider'; +import { getRecommendedArticlesSlice } from '../../utils/linkedArticles/formatters'; + +import { Header } from '../../utils/linkedArticles/styles'; +import { Container } from './styles'; + +interface CategorisedArticlesProps { + heading: string; + articles: any; +} +export const CategorisedArticles: React.FC = ({ + heading, + articles +}) => { + const { fireAnalyticsEvent } = useTrackingContext(); + + const onClickHandler = (__: MouseEventType, article: SliceArticle) => { + if (fireAnalyticsEvent) { + fireAnalyticsEvent({ + action: 'Clicked', + attrs: { article_parent_name: article.headline } + }); + } + }; + + return ( + +
{`More from ${heading}`}
+ +
+ ); +}; diff --git a/packages/ts-components/src/components/categorised-articles/__tests__/CategorisedArticles.test.tsx b/packages/ts-components/src/components/categorised-articles/__tests__/CategorisedArticles.test.tsx new file mode 100644 index 0000000000..f09425dc84 --- /dev/null +++ b/packages/ts-components/src/components/categorised-articles/__tests__/CategorisedArticles.test.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; +import { CategorisedArticles } from '../CategorisedArticles'; + +describe('render CategorisedArticles', () => { + it('should render header and slice with articles when valid props provided', () => { + const mockArticles = [{ headline: 'Test Article' }]; + const mockFireEvent = jest.fn(); + + jest.mock('../../../helpers/tracking/TrackingContextProvider', () => ({ + useTrackingContext: () => ({ + fireAnalyticsEvent: mockFireEvent + }) + })); + + const { container, asFragment } = render( + + ); + + expect(asFragment()).toMatchSnapshot(); + expect( + container.querySelector('#categorised-articles') + ).toBeInTheDocument(); + expect(screen.getByText('More from Sports')).toBeInTheDocument(); + }); +}); diff --git a/packages/ts-components/src/components/categorised-articles/__tests__/__snapshots__/CategorisedArticles.test.tsx.snap b/packages/ts-components/src/components/categorised-articles/__tests__/__snapshots__/CategorisedArticles.test.tsx.snap new file mode 100644 index 0000000000..dac5ab6f29 --- /dev/null +++ b/packages/ts-components/src/components/categorised-articles/__tests__/__snapshots__/CategorisedArticles.test.tsx.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`render CategorisedArticles should render header and slice with articles when valid props provided 1`] = ` + +
+
+ More from Sports +
+
+
+ +
+
+
+
+`; diff --git a/packages/ts-components/src/components/categorised-articles/styles.ts b/packages/ts-components/src/components/categorised-articles/styles.ts new file mode 100644 index 0000000000..5ea9e4b390 --- /dev/null +++ b/packages/ts-components/src/components/categorised-articles/styles.ts @@ -0,0 +1,5 @@ +import styled from 'styled-components'; + +export const Container = styled.div` + display: none; +`; diff --git a/packages/ts-components/src/components/features-carousel/FeaturesCarousel.tsx b/packages/ts-components/src/components/features-carousel/FeaturesCarousel.tsx index 48b9c7bb80..39f8cc63c9 100644 --- a/packages/ts-components/src/components/features-carousel/FeaturesCarousel.tsx +++ b/packages/ts-components/src/components/features-carousel/FeaturesCarousel.tsx @@ -30,7 +30,7 @@ export const FeaturesCarousel: React.FC = ({ }) => carouselItems ? ( From 87fb305c5e324e0d128719c229c66ddc0bf8227a Mon Sep 17 00:00:00 2001 From: ha2605 Date: Mon, 2 Dec 2024 17:38:41 +0530 Subject: [PATCH 03/11] added secrets code --- .circleci/config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d4eb72d643..3e1e54359e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -428,8 +428,6 @@ workflows: <<: *only_on_pr_branch requires: - Approve canary release - - get_secret_gh_token_dev: - filters: pipeline.parameters.use_secret_rotator == true and pipeline.git.branch != "master" - publish_npm: <<: *only_on_master_branch requires: From 006697ba2929e31df05c357a270700f2c977dc74 Mon Sep 17 00:00:00 2001 From: ha2605 Date: Mon, 2 Dec 2024 17:39:54 +0530 Subject: [PATCH 04/11] added secrets code --- terraform-secret-rotator/secret-rotator.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/terraform-secret-rotator/secret-rotator.tf b/terraform-secret-rotator/secret-rotator.tf index 7126eaa89d..8d4c727396 100644 --- a/terraform-secret-rotator/secret-rotator.tf +++ b/terraform-secret-rotator/secret-rotator.tf @@ -5,6 +5,7 @@ module "secret_rotator_times_components_dev" { account = "aws-digital-dev-tnlweb" custom_role_arn = "arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb" create_role = false + create_kubernetes_external_secrets_role = false enable_notifications = { enable = false slack_channel = "" From 0756c1680375392576db1b193a8c3d6ab17a9a06 Mon Sep 17 00:00:00 2001 From: ha2605 Date: Mon, 2 Dec 2024 17:45:13 +0530 Subject: [PATCH 05/11] added secrets code --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3e1e54359e..d4eb72d643 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -428,6 +428,8 @@ workflows: <<: *only_on_pr_branch requires: - Approve canary release + - get_secret_gh_token_dev: + filters: pipeline.parameters.use_secret_rotator == true and pipeline.git.branch != "master" - publish_npm: <<: *only_on_master_branch requires: From 47690c485255c221577b0cab174fb46bbda93a2e Mon Sep 17 00:00:00 2001 From: times-tools Date: Mon, 2 Dec 2024 12:32:32 +0000 Subject: [PATCH 06/11] chore: Publish 164ee6ae81 [ci skip] - @times-components/article-comments@0.44.24 - @times-components/article-extras@0.33.0 - @times-components/article-in-depth@3.92.5 - @times-components/article-list@9.19.26 - @times-components/article-magazine-comment@3.87.5 - @times-components/article-magazine-standard@3.87.5 - @times-components/article-main-comment@2.92.8 - @times-components/article-main-standard@3.99.8 - @times-components/article-paragraph@1.9.352 - @times-components/article-skeleton@1.141.0 - @times-components/article-summary@3.25.22 - @times-components/article@7.17.44 - @times-components/author-profile@6.19.14 - @times-components/key-facts@2.12.113 - @times-components/related-articles@6.19.0 - @times-components/save-and-share-bar@0.26.3 - @times-components/slice-layout@0.52.0 - @times-components/ssr@2.59.25 - @times-components/ts-components@1.112.0 - @times-components/ts-slices@1.10.0 --- packages/article-comments/CHANGELOG.md | 8 ++++++++ packages/article-comments/package.json | 4 ++-- packages/article-extras/CHANGELOG.md | 11 +++++++++++ packages/article-extras/package.json | 10 +++++----- packages/article-in-depth/CHANGELOG.md | 8 ++++++++ packages/article-in-depth/package.json | 6 +++--- packages/article-list/CHANGELOG.md | 8 ++++++++ packages/article-list/package.json | 4 ++-- packages/article-magazine-comment/CHANGELOG.md | 8 ++++++++ packages/article-magazine-comment/package.json | 6 +++--- packages/article-magazine-standard/CHANGELOG.md | 8 ++++++++ packages/article-magazine-standard/package.json | 6 +++--- packages/article-main-comment/CHANGELOG.md | 8 ++++++++ packages/article-main-comment/package.json | 6 +++--- packages/article-main-standard/CHANGELOG.md | 8 ++++++++ packages/article-main-standard/package.json | 6 +++--- packages/article-paragraph/CHANGELOG.md | 8 ++++++++ packages/article-paragraph/package.json | 4 ++-- packages/article-skeleton/CHANGELOG.md | 12 ++++++++++++ packages/article-skeleton/package.json | 12 ++++++------ packages/article-summary/CHANGELOG.md | 8 ++++++++ packages/article-summary/package.json | 4 ++-- packages/article/CHANGELOG.md | 8 ++++++++ packages/article/package.json | 12 ++++++------ packages/author-profile/CHANGELOG.md | 8 ++++++++ packages/author-profile/package.json | 4 ++-- packages/key-facts/CHANGELOG.md | 8 ++++++++ packages/key-facts/package.json | 4 ++-- packages/related-articles/CHANGELOG.md | 11 +++++++++++ packages/related-articles/package.json | 6 +++--- packages/save-and-share-bar/CHANGELOG.md | 8 ++++++++ packages/save-and-share-bar/package.json | 4 ++-- packages/slice-layout/CHANGELOG.md | 11 +++++++++++ packages/slice-layout/package.json | 2 +- packages/ssr/CHANGELOG.md | 8 ++++++++ packages/ssr/package.json | 6 +++--- packages/ts-components/CHANGELOG.md | 13 +++++++++++++ packages/ts-components/package.json | 6 +++--- packages/ts-slices/CHANGELOG.md | 11 +++++++++++ packages/ts-slices/package.json | 2 +- 40 files changed, 238 insertions(+), 57 deletions(-) diff --git a/packages/article-comments/CHANGELOG.md b/packages/article-comments/CHANGELOG.md index b3605708f9..6f69f8a2b0 100644 --- a/packages/article-comments/CHANGELOG.md +++ b/packages/article-comments/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.44.24](https://github.com/newsuk/times-components/compare/@times-components/article-comments@0.44.23...@times-components/article-comments@0.44.24) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-comments + + + + + ## [0.44.23](https://github.com/newsuk/times-components/compare/@times-components/article-comments@0.44.22...@times-components/article-comments@0.44.23) (2024-11-22) **Note:** Version bump only for package @times-components/article-comments diff --git a/packages/article-comments/package.json b/packages/article-comments/package.json index 8d16748f67..3b6712e538 100644 --- a/packages/article-comments/package.json +++ b/packages/article-comments/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-comments", - "version": "0.44.23", + "version": "0.44.24", "description": "Article Comments", "main": "dist/article-comments", "dev": "src/article-comments", @@ -35,7 +35,7 @@ "dependencies": { "@times-components/link": "3.17.34", "@times-components/tracking": "2.22.34", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "prop-types": "15.7.2", diff --git a/packages/article-extras/CHANGELOG.md b/packages/article-extras/CHANGELOG.md index fabefa9161..3d04cf470e 100644 --- a/packages/article-extras/CHANGELOG.md +++ b/packages/article-extras/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.33.0](https://github.com/newsuk/times-components/compare/@times-components/article-extras@0.32.24...@times-components/article-extras@0.33.0) (2024-12-02) + + +### Features + +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) + + + + + ## [0.32.24](https://github.com/newsuk/times-components/compare/@times-components/article-extras@0.32.23...@times-components/article-extras@0.32.24) (2024-11-22) **Note:** Version bump only for package @times-components/article-extras diff --git a/packages/article-extras/package.json b/packages/article-extras/package.json index aeb3149ba3..1ab2552a7e 100644 --- a/packages/article-extras/package.json +++ b/packages/article-extras/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-extras", - "version": "0.32.24", + "version": "0.33.0", "description": "Extra information components at the bottom of the articles, such as topics, related articles and comments ", "main": "dist/index", "dev": "src/index", @@ -49,14 +49,14 @@ "webpack": "4.30.0" }, "dependencies": { - "@times-components/article-comments": "0.44.23", + "@times-components/article-comments": "0.44.24", "@times-components/article-topics": "4.11.55", "@times-components/button": "2.10.61", "@times-components/context": "1.24.0", "@times-components/message-bar": "0.7.86", - "@times-components/related-articles": "6.18.6", - "@times-components/save-and-share-bar": "0.26.2", - "@times-components/ts-components": "1.111.0", + "@times-components/related-articles": "6.19.0", + "@times-components/save-and-share-bar": "0.26.3", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-in-depth/CHANGELOG.md b/packages/article-in-depth/CHANGELOG.md index dcffec5d58..865df121a3 100644 --- a/packages/article-in-depth/CHANGELOG.md +++ b/packages/article-in-depth/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.92.5](https://github.com/newsuk/times-components/compare/@times-components/article-in-depth@3.92.4...@times-components/article-in-depth@3.92.5) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-in-depth + + + + + ## [3.92.4](https://github.com/newsuk/times-components/compare/@times-components/article-in-depth@3.92.3...@times-components/article-in-depth@3.92.4) (2024-11-22) **Note:** Version bump only for package @times-components/article-in-depth diff --git a/packages/article-in-depth/package.json b/packages/article-in-depth/package.json index 82e321580c..86bf4b6104 100644 --- a/packages/article-in-depth/package.json +++ b/packages/article-in-depth/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-in-depth", - "version": "3.92.4", + "version": "3.92.5", "description": "In Depth Article Template", "main": "dist/article-in-depth", "dev": "src/article-in-depth", @@ -57,11 +57,11 @@ "@times-components/article-byline": "3.13.56", "@times-components/article-label": "2.18.34", "@times-components/article-lead-asset": "1.18.46", - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/caption": "3.8.55", "@times-components/context": "1.24.0", "@times-components/date-publication": "0.30.34", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-list/CHANGELOG.md b/packages/article-list/CHANGELOG.md index 3822a7010b..71a1b5db44 100644 --- a/packages/article-list/CHANGELOG.md +++ b/packages/article-list/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [9.19.26](https://github.com/newsuk/times-components/compare/@times-components/article-list@9.19.25...@times-components/article-list@9.19.26) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-list + + + + + ## [9.19.25](https://github.com/newsuk/times-components/compare/@times-components/article-list@9.19.24...@times-components/article-list@9.19.25) (2024-11-22) **Note:** Version bump only for package @times-components/article-list diff --git a/packages/article-list/package.json b/packages/article-list/package.json index 8d55c54f38..dabfd873e1 100644 --- a/packages/article-list/package.json +++ b/packages/article-list/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-list", - "version": "9.19.25", + "version": "9.19.26", "description": "Paginated list of articles", "main": "dist/article-list", "dev": "src/article-list", @@ -61,7 +61,7 @@ }, "dependencies": { "@times-components/ad": "2.22.23", - "@times-components/article-summary": "3.25.21", + "@times-components/article-summary": "3.25.22", "@times-components/button": "2.10.61", "@times-components/card": "6.15.2", "@times-components/context": "1.24.0", diff --git a/packages/article-magazine-comment/CHANGELOG.md b/packages/article-magazine-comment/CHANGELOG.md index 4330e69fd0..0f494795e4 100644 --- a/packages/article-magazine-comment/CHANGELOG.md +++ b/packages/article-magazine-comment/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.87.5](https://github.com/newsuk/times-components/compare/@times-components/article-magazine-comment@3.87.4...@times-components/article-magazine-comment@3.87.5) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-magazine-comment + + + + + ## [3.87.4](https://github.com/newsuk/times-components/compare/@times-components/article-magazine-comment@3.87.3...@times-components/article-magazine-comment@3.87.4) (2024-11-22) **Note:** Version bump only for package @times-components/article-magazine-comment diff --git a/packages/article-magazine-comment/package.json b/packages/article-magazine-comment/package.json index a796a39f89..b1ee6c4f41 100644 --- a/packages/article-magazine-comment/package.json +++ b/packages/article-magazine-comment/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-magazine-comment", - "version": "3.87.4", + "version": "3.87.5", "description": "Magazine Comment Article Template", "main": "dist/article-magazine-comment", "dev": "src/article-magazine-comment", @@ -57,12 +57,12 @@ "@times-components/article-byline": "3.13.56", "@times-components/article-label": "2.18.34", "@times-components/article-lead-asset": "1.18.46", - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/caption": "3.8.55", "@times-components/context": "1.24.0", "@times-components/date-publication": "0.30.34", "@times-components/image": "6.18.2", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-magazine-standard/CHANGELOG.md b/packages/article-magazine-standard/CHANGELOG.md index 171346651d..826842b213 100644 --- a/packages/article-magazine-standard/CHANGELOG.md +++ b/packages/article-magazine-standard/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.87.5](https://github.com/newsuk/times-components/compare/@times-components/article-magazine-standard@3.87.4...@times-components/article-magazine-standard@3.87.5) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-magazine-standard + + + + + ## [3.87.4](https://github.com/newsuk/times-components/compare/@times-components/article-magazine-standard@3.87.3...@times-components/article-magazine-standard@3.87.4) (2024-11-22) **Note:** Version bump only for package @times-components/article-magazine-standard diff --git a/packages/article-magazine-standard/package.json b/packages/article-magazine-standard/package.json index ae7f5062e0..d195224a08 100644 --- a/packages/article-magazine-standard/package.json +++ b/packages/article-magazine-standard/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-magazine-standard", - "version": "3.87.4", + "version": "3.87.5", "description": "Magazine Standard Article Template", "main": "dist/article-magazine-standard", "dev": "src/article-magazine-standard", @@ -57,11 +57,11 @@ "@times-components/article-byline": "3.13.56", "@times-components/article-label": "2.18.34", "@times-components/article-lead-asset": "1.18.46", - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/caption": "3.8.55", "@times-components/context": "1.24.0", "@times-components/date-publication": "0.30.34", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-main-comment/CHANGELOG.md b/packages/article-main-comment/CHANGELOG.md index fbeac9184b..870e0bdb71 100644 --- a/packages/article-main-comment/CHANGELOG.md +++ b/packages/article-main-comment/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.92.8](https://github.com/newsuk/times-components/compare/@times-components/article-main-comment@2.92.7...@times-components/article-main-comment@2.92.8) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-main-comment + + + + + ## [2.92.7](https://github.com/newsuk/times-components/compare/@times-components/article-main-comment@2.92.6...@times-components/article-main-comment@2.92.7) (2024-11-22) **Note:** Version bump only for package @times-components/article-main-comment diff --git a/packages/article-main-comment/package.json b/packages/article-main-comment/package.json index 91fb24e7be..e3602ec483 100644 --- a/packages/article-main-comment/package.json +++ b/packages/article-main-comment/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-main-comment", - "version": "2.92.7", + "version": "2.92.8", "description": "Main Comment Article Template", "main": "dist/article-main-comment", "dev": "src/article-main-comment", @@ -56,12 +56,12 @@ "@times-components/ad": "2.22.23", "@times-components/article-byline": "3.13.56", "@times-components/article-label": "2.18.34", - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/context": "1.24.0", "@times-components/date-publication": "0.30.34", "@times-components/image": "6.18.2", "@times-components/responsive": "0.27.0", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-main-standard/CHANGELOG.md b/packages/article-main-standard/CHANGELOG.md index e0c39c5ee8..ec994df2a8 100644 --- a/packages/article-main-standard/CHANGELOG.md +++ b/packages/article-main-standard/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.99.8](https://github.com/newsuk/times-components/compare/@times-components/article-main-standard@3.99.7...@times-components/article-main-standard@3.99.8) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-main-standard + + + + + ## [3.99.7](https://github.com/newsuk/times-components/compare/@times-components/article-main-standard@3.99.6...@times-components/article-main-standard@3.99.7) (2024-11-22) **Note:** Version bump only for package @times-components/article-main-standard diff --git a/packages/article-main-standard/package.json b/packages/article-main-standard/package.json index 585e62d64e..ec2e2bd819 100644 --- a/packages/article-main-standard/package.json +++ b/packages/article-main-standard/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-main-standard", - "version": "3.99.7", + "version": "3.99.8", "description": "Main Standard Article Template", "main": "dist/article-main-standard", "dev": "src/article-main-standard", @@ -56,13 +56,13 @@ "@times-components/article-byline": "3.13.56", "@times-components/article-label": "2.18.34", "@times-components/article-lead-asset": "1.18.46", - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/article-topics": "4.11.55", "@times-components/caption": "3.8.55", "@times-components/context": "1.24.0", "@times-components/date-publication": "0.30.34", "@times-components/responsive": "0.27.0", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/article-paragraph/CHANGELOG.md b/packages/article-paragraph/CHANGELOG.md index edacd554d6..d19514daa7 100644 --- a/packages/article-paragraph/CHANGELOG.md +++ b/packages/article-paragraph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.9.352](https://github.com/newsuk/times-components/compare/@times-components/article-paragraph@1.9.351...@times-components/article-paragraph@1.9.352) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-paragraph + + + + + ## [1.9.351](https://github.com/newsuk/times-components/compare/@times-components/article-paragraph@1.9.350...@times-components/article-paragraph@1.9.351) (2024-11-22) **Note:** Version bump only for package @times-components/article-paragraph diff --git a/packages/article-paragraph/package.json b/packages/article-paragraph/package.json index 835ae6d501..1a5831938f 100644 --- a/packages/article-paragraph/package.json +++ b/packages/article-paragraph/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-paragraph", - "version": "1.9.351", + "version": "1.9.352", "description": "Article Paragraph", "main": "dist/index", "dev": "src/index", @@ -32,7 +32,7 @@ }, "homepage": "https://github.com/newsuk/times-components#readme", "dependencies": { - "@times-components/article-skeleton": "1.140.13", + "@times-components/article-skeleton": "1.141.0", "@times-components/context": "1.24.0", "@times-components/markup-forest": "1.9.2", "@times-components/ts-styleguide": "1.50.34", diff --git a/packages/article-skeleton/CHANGELOG.md b/packages/article-skeleton/CHANGELOG.md index ad9fbc142f..7ccc10c349 100644 --- a/packages/article-skeleton/CHANGELOG.md +++ b/packages/article-skeleton/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.141.0](https://github.com/newsuk/times-components/compare/@times-components/article-skeleton@1.140.13...@times-components/article-skeleton@1.141.0) (2024-12-02) + + +### Features + +* **TMD-1082:** update to newsletter title within on click sign up component ([#3990](https://github.com/newsuk/times-components/issues/3990)) ([efddfee](https://github.com/newsuk/times-components/commit/efddfee6358e43a385924af671deedaa03e5ae36)) +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) + + + + + ## [1.140.13](https://github.com/newsuk/times-components/compare/@times-components/article-skeleton@1.140.12...@times-components/article-skeleton@1.140.13) (2024-11-22) **Note:** Version bump only for package @times-components/article-skeleton diff --git a/packages/article-skeleton/package.json b/packages/article-skeleton/package.json index f7ae797b5b..c06a8a6a04 100644 --- a/packages/article-skeleton/package.json +++ b/packages/article-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-skeleton", - "version": "1.140.13", + "version": "1.141.0", "description": "The article skeleton", "main": "dist/article-skeleton", "dev": "src/article-skeleton", @@ -62,14 +62,14 @@ }, "dependencies": { "@times-components/ad": "2.22.23", - "@times-components/article-extras": "0.32.24", + "@times-components/article-extras": "0.33.0", "@times-components/article-image": "7.18.2", - "@times-components/article-paragraph": "1.9.351", + "@times-components/article-paragraph": "1.9.352", "@times-components/article-topics": "4.11.55", "@times-components/caption": "3.8.55", "@times-components/context": "1.24.0", "@times-components/interactive-wrapper": "0.9.90", - "@times-components/key-facts": "2.12.112", + "@times-components/key-facts": "2.12.113", "@times-components/lazy-load": "0.20.0", "@times-components/link": "3.17.34", "@times-components/markup": "3.9.0", @@ -77,10 +77,10 @@ "@times-components/message-bar": "0.7.86", "@times-components/provider-queries": "2.23.3", "@times-components/pull-quote": "3.15.41", - "@times-components/save-and-share-bar": "0.26.2", + "@times-components/save-and-share-bar": "0.26.3", "@times-components/sticky": "0.5.84", "@times-components/tracking": "2.22.34", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/typeset": "0.3.3", "@times-components/user-state": "0.5.51", diff --git a/packages/article-summary/CHANGELOG.md b/packages/article-summary/CHANGELOG.md index 04f63266cf..8abe0d87f4 100644 --- a/packages/article-summary/CHANGELOG.md +++ b/packages/article-summary/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.25.22](https://github.com/newsuk/times-components/compare/@times-components/article-summary@3.25.21...@times-components/article-summary@3.25.22) (2024-12-02) + +**Note:** Version bump only for package @times-components/article-summary + + + + + ## [3.25.21](https://github.com/newsuk/times-components/compare/@times-components/article-summary@3.25.20...@times-components/article-summary@3.25.21) (2024-11-22) **Note:** Version bump only for package @times-components/article-summary diff --git a/packages/article-summary/package.json b/packages/article-summary/package.json index a0c619d589..16843da845 100644 --- a/packages/article-summary/package.json +++ b/packages/article-summary/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article-summary", - "version": "3.25.21", + "version": "3.25.22", "main": "dist/article-summary", "dev": "src/article-summary", "scripts": { @@ -55,7 +55,7 @@ "@times-components/date-publication": "0.30.34", "@times-components/markup": "3.9.0", "@times-components/markup-forest": "1.9.2", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/utils": "6.26.0", "@times-components/video-label": "2.11.63", diff --git a/packages/article/CHANGELOG.md b/packages/article/CHANGELOG.md index 1ca68b8fd0..ecd2617b96 100644 --- a/packages/article/CHANGELOG.md +++ b/packages/article/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [7.17.44](https://github.com/newsuk/times-components/compare/@times-components/article@7.17.43...@times-components/article@7.17.44) (2024-12-02) + +**Note:** Version bump only for package @times-components/article + + + + + ## [7.17.43](https://github.com/newsuk/times-components/compare/@times-components/article@7.17.42...@times-components/article@7.17.43) (2024-11-22) **Note:** Version bump only for package @times-components/article diff --git a/packages/article/package.json b/packages/article/package.json index 9de5571da1..5e58ae56bf 100644 --- a/packages/article/package.json +++ b/packages/article/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/article", - "version": "7.17.43", + "version": "7.17.44", "description": "The article", "main": "dist/article", "dev": "src/article", @@ -53,11 +53,11 @@ }, "dependencies": { "@times-components/ad": "2.22.23", - "@times-components/article-in-depth": "3.92.4", - "@times-components/article-magazine-comment": "3.87.4", - "@times-components/article-magazine-standard": "3.87.4", - "@times-components/article-main-comment": "2.92.7", - "@times-components/article-main-standard": "3.99.7", + "@times-components/article-in-depth": "3.92.5", + "@times-components/article-magazine-comment": "3.87.5", + "@times-components/article-magazine-standard": "3.87.5", + "@times-components/article-main-comment": "2.92.8", + "@times-components/article-main-standard": "3.99.8", "@times-components/context": "1.24.0", "@times-components/message-bar": "0.7.86", "@times-components/provider": "1.41.4", diff --git a/packages/author-profile/CHANGELOG.md b/packages/author-profile/CHANGELOG.md index c9c55ecf14..dbebcf57a2 100644 --- a/packages/author-profile/CHANGELOG.md +++ b/packages/author-profile/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [6.19.14](https://github.com/newsuk/times-components/compare/@times-components/author-profile@6.19.13...@times-components/author-profile@6.19.14) (2024-12-02) + +**Note:** Version bump only for package @times-components/author-profile + + + + + ## [6.19.13](https://github.com/newsuk/times-components/compare/@times-components/author-profile@6.19.12...@times-components/author-profile@6.19.13) (2024-11-22) **Note:** Version bump only for package @times-components/author-profile diff --git a/packages/author-profile/package.json b/packages/author-profile/package.json index f36f8676fb..bd62e8eef7 100644 --- a/packages/author-profile/package.json +++ b/packages/author-profile/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/author-profile", - "version": "6.19.13", + "version": "6.19.14", "description": "Author profile information along with a list of articles they have written ", "main": "dist/author-profile", "dev": "src/author-profile", @@ -59,7 +59,7 @@ "webpack": "4.30.0" }, "dependencies": { - "@times-components/article-list": "9.19.25", + "@times-components/article-list": "9.19.26", "@times-components/gradient": "3.5.61", "@times-components/icons": "2.23.0", "@times-components/image": "6.18.2", diff --git a/packages/key-facts/CHANGELOG.md b/packages/key-facts/CHANGELOG.md index 159003f932..a821d372cf 100644 --- a/packages/key-facts/CHANGELOG.md +++ b/packages/key-facts/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.12.113](https://github.com/newsuk/times-components/compare/@times-components/key-facts@2.12.112...@times-components/key-facts@2.12.113) (2024-12-02) + +**Note:** Version bump only for package @times-components/key-facts + + + + + ## [2.12.112](https://github.com/newsuk/times-components/compare/@times-components/key-facts@2.12.111...@times-components/key-facts@2.12.112) (2024-11-22) **Note:** Version bump only for package @times-components/key-facts diff --git a/packages/key-facts/package.json b/packages/key-facts/package.json index ce0253d8cc..1b26502a92 100644 --- a/packages/key-facts/package.json +++ b/packages/key-facts/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/key-facts", - "version": "2.12.112", + "version": "2.12.113", "description": "Bulleted list of text data ", "main": "dist/key-facts", "dev": "src/key-facts", @@ -56,7 +56,7 @@ "@times-components/markup": "3.9.0", "@times-components/markup-forest": "1.9.2", "@times-components/responsive": "0.27.0", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/utils": "6.26.0", "prop-types": "15.7.2", diff --git a/packages/related-articles/CHANGELOG.md b/packages/related-articles/CHANGELOG.md index 63571c8b05..f2d7b23a8a 100644 --- a/packages/related-articles/CHANGELOG.md +++ b/packages/related-articles/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [6.19.0](https://github.com/newsuk/times-components/compare/@times-components/related-articles@6.18.6...@times-components/related-articles@6.19.0) (2024-12-02) + + +### Features + +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) + + + + + ## [6.18.6](https://github.com/newsuk/times-components/compare/@times-components/related-articles@6.18.5...@times-components/related-articles@6.18.6) (2024-11-22) **Note:** Version bump only for package @times-components/related-articles diff --git a/packages/related-articles/package.json b/packages/related-articles/package.json index 89a986982f..68b283c938 100644 --- a/packages/related-articles/package.json +++ b/packages/related-articles/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/related-articles", - "version": "6.18.6", + "version": "6.19.0", "description": "related articles of an article", "main": "dist/related-articles", "dev": "src/related-articles", @@ -55,12 +55,12 @@ "webpack": "4.30.0" }, "dependencies": { - "@times-components/article-summary": "3.25.21", + "@times-components/article-summary": "3.25.22", "@times-components/card": "6.15.2", "@times-components/context": "1.24.0", "@times-components/link": "3.17.34", "@times-components/markup-forest": "1.9.2", - "@times-components/slice-layout": "0.51.61", + "@times-components/slice-layout": "0.52.0", "@times-components/tracking": "2.22.34", "@times-components/ts-styleguide": "1.50.34", "@times-components/utils": "6.26.0", diff --git a/packages/save-and-share-bar/CHANGELOG.md b/packages/save-and-share-bar/CHANGELOG.md index 46a2a22c1d..9501375acb 100644 --- a/packages/save-and-share-bar/CHANGELOG.md +++ b/packages/save-and-share-bar/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.26.3](https://github.com/newsuk/times-components/compare/@times-components/save-and-share-bar@0.26.2...@times-components/save-and-share-bar@0.26.3) (2024-12-02) + +**Note:** Version bump only for package @times-components/save-and-share-bar + + + + + ## [0.26.2](https://github.com/newsuk/times-components/compare/@times-components/save-and-share-bar@0.26.1...@times-components/save-and-share-bar@0.26.2) (2024-11-22) **Note:** Version bump only for package @times-components/save-and-share-bar diff --git a/packages/save-and-share-bar/package.json b/packages/save-and-share-bar/package.json index b77e26c5a9..6d6aa2fabe 100644 --- a/packages/save-and-share-bar/package.json +++ b/packages/save-and-share-bar/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/save-and-share-bar", - "version": "0.26.2", + "version": "0.26.3", "description": "Save and Share bar ", "main": "dist/save-and-share-bar", "dev": "src/save-and-share-bar", @@ -38,7 +38,7 @@ "@times-components/message-bar": "0.7.86", "@times-components/provider-queries": "2.23.3", "@times-components/tracking": "2.22.34", - "@times-components/ts-components": "1.111.0", + "@times-components/ts-components": "1.112.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/user-state": "0.5.51", "@times-components/utils": "6.26.0", diff --git a/packages/slice-layout/CHANGELOG.md b/packages/slice-layout/CHANGELOG.md index a9c736d893..233a36af7f 100644 --- a/packages/slice-layout/CHANGELOG.md +++ b/packages/slice-layout/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.52.0](https://github.com/newsuk/times-components/compare/@times-components/slice-layout@0.51.61...@times-components/slice-layout@0.52.0) (2024-12-02) + + +### Features + +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) + + + + + ## [0.51.61](https://github.com/newsuk/times-components/compare/@times-components/slice-layout@0.51.60...@times-components/slice-layout@0.51.61) (2024-07-02) **Note:** Version bump only for package @times-components/slice-layout diff --git a/packages/slice-layout/package.json b/packages/slice-layout/package.json index 8c61f69ce1..6f7ec81aed 100644 --- a/packages/slice-layout/package.json +++ b/packages/slice-layout/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/slice-layout", - "version": "0.51.61", + "version": "0.52.0", "description": "Slice layout", "main": "dist/slice-layout", "scripts": { diff --git a/packages/ssr/CHANGELOG.md b/packages/ssr/CHANGELOG.md index 6c19468f1c..42fa7001d6 100644 --- a/packages/ssr/CHANGELOG.md +++ b/packages/ssr/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.59.25](https://github.com/newsuk/times-components/compare/@times-components/ssr@2.59.24...@times-components/ssr@2.59.25) (2024-12-02) + +**Note:** Version bump only for package @times-components/ssr + + + + + ## [2.59.24](https://github.com/newsuk/times-components/compare/@times-components/ssr@2.59.23...@times-components/ssr@2.59.24) (2024-11-22) **Note:** Version bump only for package @times-components/ssr diff --git a/packages/ssr/package.json b/packages/ssr/package.json index 177c7c7e2a..96120a4862 100644 --- a/packages/ssr/package.json +++ b/packages/ssr/package.json @@ -1,7 +1,7 @@ { "name": "@times-components/ssr", "main": "src", - "version": "2.59.24", + "version": "2.59.25", "scripts": { "bundle:dev": "yarn cleanup-dist && webpack --config=webpack.config.js", "bundle:prod": "yarn cleanup-dist && NODE_ENV=production webpack --config=webpack.config.js -p", @@ -52,8 +52,8 @@ "webpack": "4.30.0" }, "dependencies": { - "@times-components/article": "7.17.43", - "@times-components/author-profile": "6.19.13", + "@times-components/article": "7.17.44", + "@times-components/author-profile": "6.19.14", "@times-components/context": "1.24.0", "@times-components/provider": "1.41.4", "@times-components/schema": "0.7.5", diff --git a/packages/ts-components/CHANGELOG.md b/packages/ts-components/CHANGELOG.md index 422aabecfc..7a87dac539 100644 --- a/packages/ts-components/CHANGELOG.md +++ b/packages/ts-components/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.112.0](https://github.com/newsuk/times-components/compare/@times-components/ts-components@1.111.0...@times-components/ts-components@1.112.0) (2024-12-02) + + +### Features + +* **TMD-1082:** update to newsletter title within on click sign up component ([#3990](https://github.com/newsuk/times-components/issues/3990)) ([efddfee](https://github.com/newsuk/times-components/commit/efddfee6358e43a385924af671deedaa03e5ae36)) +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) +* **TMRS-593:** update benefits rail ([#3991](https://github.com/newsuk/times-components/issues/3991)) ([3c6b0e1](https://github.com/newsuk/times-components/commit/3c6b0e184e643c3e81a82229a1c4b514d2a62663)) + + + + + # [1.111.0](https://github.com/newsuk/times-components/compare/@times-components/ts-components@1.110.2...@times-components/ts-components@1.111.0) (2024-11-22) diff --git a/packages/ts-components/package.json b/packages/ts-components/package.json index e44718c219..2c5e72433a 100644 --- a/packages/ts-components/package.json +++ b/packages/ts-components/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/ts-components", - "version": "1.111.0", + "version": "1.112.0", "description": "Reuseable Typescript React Components ", "main": "dist/index.js", "dev": "dist/index.js", @@ -57,8 +57,8 @@ "@times-components/link": "3.17.34", "@times-components/provider": "1.41.4", "@times-components/provider-queries": "2.23.3", - "@times-components/related-articles": "6.18.6", - "@times-components/ts-slices": "1.9.23", + "@times-components/related-articles": "6.19.0", + "@times-components/ts-slices": "1.10.0", "@times-components/ts-styleguide": "1.50.34", "@times-components/utils": "6.26.0", "algoliasearch": "4.9.0", diff --git a/packages/ts-slices/CHANGELOG.md b/packages/ts-slices/CHANGELOG.md index 12e72bd07f..cb28f86f05 100644 --- a/packages/ts-slices/CHANGELOG.md +++ b/packages/ts-slices/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.10.0](https://github.com/newsuk/times-components/compare/@times-components/ts-slices@1.9.23...@times-components/ts-slices@1.10.0) (2024-12-02) + + +### Features + +* **TMRS-482:** add CategorisedArticles ([#3976](https://github.com/newsuk/times-components/issues/3976)) ([164ee6a](https://github.com/newsuk/times-components/commit/164ee6ae81516489bd6d5afb8e7289104c65720a)) + + + + + ## [1.9.23](https://github.com/newsuk/times-components/compare/@times-components/ts-slices@1.9.22...@times-components/ts-slices@1.9.23) (2024-10-14) **Note:** Version bump only for package @times-components/ts-slices diff --git a/packages/ts-slices/package.json b/packages/ts-slices/package.json index 82b4dc375f..5269427ed2 100644 --- a/packages/ts-slices/package.json +++ b/packages/ts-slices/package.json @@ -1,6 +1,6 @@ { "name": "@times-components/ts-slices", - "version": "1.9.23", + "version": "1.10.0", "description": "Reuseable Typescript React Components", "main": "dist/index.js", "dev": "dist/index.js", From 7a5754cd57973dbfba326ac5d97b1e28db0d5ed0 Mon Sep 17 00:00:00 2001 From: ibrahim-kurhan <116718171+ibrahim-kurhan@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:41:32 +0000 Subject: [PATCH 07/11] fix(TMD-000): this pr is just to fix the pipeline issue (#3995) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 94f175fbc9..60dac76708 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Home of The Times' `react` components. We require MacOS with [Node.js](https://nodejs.org) (for specific version please check package.json restrictions), [yarn](https://yarnpkg.com) (latest) + You can try without these requirements, but you'd be on your own. ## Viewing Our Components From c57c0f76bf95daef38d6aca09ab56750b2d76ca2 Mon Sep 17 00:00:00 2001 From: ha2605 Date: Mon, 2 Dec 2024 20:53:11 +0530 Subject: [PATCH 08/11] added secrets code --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d4eb72d643..d845788810 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -341,7 +341,7 @@ jobs: executor: node steps: - aws-cli/setup: - region: SECRETS_REGION + region: "eu-west-1" role_arn: arn:aws:iam::512040659177:role/circle-oidc-nuk-aws-digital-dev-tnlweb - aws-secrets-manager/get-aws-secret: aws-secret-name: times-components/dev/GH_TOKEN From 6c0cb733496b7e22fa3ef8b1fcc3634b6eabbcf6 Mon Sep 17 00:00:00 2001 From: ha2605 Date: Tue, 3 Dec 2024 08:58:48 +0530 Subject: [PATCH 09/11] cahnged readme.md file --- terraform-secret-rotator/README.MD | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/terraform-secret-rotator/README.MD b/terraform-secret-rotator/README.MD index 7e12d11fd4..e55d7a48b9 100644 --- a/terraform-secret-rotator/README.MD +++ b/terraform-secret-rotator/README.MD @@ -59,11 +59,7 @@ module "secret_rotator_times_components_dev" { ### Secret Retrieval Jobs The following jobs in the CircleCI pipeline handle secret retrieval: -- **Retrieve ARTIFACTORY_API_KEY** -- **Retrieve ARTIFACTORY_AUTH_TOKEN** -- **Retrieve ARTIFACTORY_HELM_USERNAME** -- **Retrieve ARTIFACTORY_HELM_PASSWORD** -- **Retrieve GITHUB_API_TOKEN** +- **Retrieve GH_TOKEN** #### Example Job for Retrieving a Secret: ```yaml From 6383ecb600a18cf09d81731859e4394d6fc012d6 Mon Sep 17 00:00:00 2001 From: Josip Vukovic <129039019+josipVuko@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:23:25 +0100 Subject: [PATCH 10/11] Feat/tmpz 775 build button for aduio naration (#3996) * feat/TMPZ-777-audio-player-mobile * feat/TMPZ-777-audio-player-working-player * feat/TMPZ-777-audio-player-working-player * feat/TMPZ-777-audio-player * feat/TMPZ-777-audio-player-lin-sht * feat(TMPZ-775): created audio playe button * feat/TMPZ-777-audio-player-icons * feat/TMPZ-777-audio-player-icons * feat/TMPZ-777-audio-player-tests * feat(TMPZ-775): added imperative handle for audio player * feat/TMPZ-777-audio-player-tests * feat/TMPZ-777-audio-player-tests * feat(TMPZ-775): minor adjustments * feat/TMPZ-777-audio-player-tests * feat/TMPZ-777-audio-player-tests * feat/TMPZ-777-audio-player-tests * feat/TMPZ-777-audio-player-tests * feat/TMPZ-777-audio-player-no-test-cus-of-bad-and-outdated-env * feat/TMPZ-777-audio-player-no-test-cus-of-bad-and-outdated-env * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-no-test-audio * feat/TMPZ-777-audio-player-components-fix * feat/TMPZ-777-audio-player-components-fix-remove-old-player * feat/TMPZ-777-audio-player-with-tests * feat/TMPZ-777-audio-player-with-tests * feat/TMPZ-777-audio-player-with-tests * feat/TMPZ-777-audio-player-with-tests * feat/TMPZ-777-audio-player-analyitcs-test * temporary reduction in thresholds code is in transition * feat/TMPZ-777-audio-player-using-ts-styles * feat/TMPZ-777-audio-player-new-tests * feat/TMPZ-777-audio-player-new-tests * feat/TMPZ-777-audio-player-new-tests * feat/TMPZ-777-audio-player-new-tests * feat/TMPZ-775-build_button_for_aduio_naration-resolve-audio-branch-resolve-lints * feat/TMPZ-775-build_button_for_aduio_naration-writing-helping-with-test * feat/TMPZ-775-build_button_for_aduio_naration-writing-helping-with-test * feat(TMPZ-775): adjusted styles, adjusted tests * feat/TMPZ-775-build_button_for_aduio_naration-test-fix * feat/TMPZ-775-build_button_for_aduio_naration-test-fix * feat(TMPZ-775): removed unused prop from test * feat(TMPZ-775): adjusted tests * feat/TMPZ-775-build_button_for_aduio_naration * feat(TMPZ-775): manualy adjusted snap --------- Co-authored-by: Domagoj Co-authored-by: Adam Osborne --- .eslintrc | 3 +- packages/ts-components/jest.config.js | 6 +- .../article-audio/ArticleAudio.stories.tsx | 14 + .../components/article-audio/ArticleAudio.tsx | 93 +++ .../__tests__/ArticleAudio.test.tsx | 192 +++++ .../article-audio/__tests__/Styles.test.tsx | 61 ++ .../src/components/article-audio/styles.ts | 26 + .../AudioPlayer.stories.tsx | 209 +++++ .../audio-player-components/AudioPlayer.tsx | 324 ++++++++ .../audio-player-components/CollapseIcon.tsx | 25 + .../PlaybackControls.tsx | 104 +++ .../audio-player-components/SeekBar.tsx | 27 + .../TabletDesktopPlayer.tsx | 157 ++++ .../audio-player-components/TimeDisplay.tsx | 18 + .../audio-player-components/TitleScroller.tsx | 13 + .../__tests__/AudioPlayer.test.tsx | 267 ++++++ .../__tests__/CollapseIcon.test.tsx | 89 ++ .../__tests__/PlaybackControls.test.tsx | 330 ++++++++ .../__tests__/SeekBar.test.tsx | 96 +++ .../__tests__/Styles.test.tsx | 777 ++++++++++++++++++ .../__tests__/TabletDesktopPlayer.test.tsx | 304 +++++++ .../__tests__/TimeDisplay.test.tsx | 103 +++ .../__tests__/TitleScroller.test.tsx | 60 ++ .../__tests__/Utils.test.tsx | 37 + .../__snapshots__/Styles.test.tsx.snap | 3 + .../__snapshots__/TitleScroller.test.tsx.snap | 19 + .../audio-player-components/styles.ts | 631 ++++++++++++++ .../audio-player-components/types.ts | 90 ++ .../audio-player-components/utils.ts | 5 + .../__tests__/AnalyticsActions.test.tsx | 62 ++ packages/ts-components/src/index.ts | 1 + packages/ts-components/src/types/externs.d.ts | 9 + 32 files changed, 4151 insertions(+), 4 deletions(-) create mode 100644 packages/ts-components/src/components/article-audio/ArticleAudio.stories.tsx create mode 100644 packages/ts-components/src/components/article-audio/ArticleAudio.tsx create mode 100644 packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx create mode 100644 packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx create mode 100644 packages/ts-components/src/components/article-audio/styles.ts create mode 100644 packages/ts-components/src/components/audio-player-components/AudioPlayer.stories.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/AudioPlayer.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/CollapseIcon.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/PlaybackControls.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/SeekBar.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/TabletDesktopPlayer.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/TimeDisplay.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/TitleScroller.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/AudioPlayer.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/CollapseIcon.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/PlaybackControls.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/SeekBar.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/Styles.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/TabletDesktopPlayer.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/TimeDisplay.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/TitleScroller.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/Utils.test.tsx create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/__snapshots__/Styles.test.tsx.snap create mode 100644 packages/ts-components/src/components/audio-player-components/__tests__/__snapshots__/TitleScroller.test.tsx.snap create mode 100644 packages/ts-components/src/components/audio-player-components/styles.ts create mode 100644 packages/ts-components/src/components/audio-player-components/types.ts create mode 100644 packages/ts-components/src/components/audio-player-components/utils.ts create mode 100644 packages/ts-components/src/fixtures/analytics-actions/__tests__/AnalyticsActions.test.tsx diff --git a/.eslintrc b/.eslintrc index f598c3e2d7..94a5d877f1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,7 +12,8 @@ "devDependencies": ["**/storybook/**"], "optionalDependencies": false } - ] + ], + "@typescript-eslint/prefer-nullish-coalescing": "off" }, "settings": { "import/resolver": { diff --git a/packages/ts-components/jest.config.js b/packages/ts-components/jest.config.js index 3ef8a57203..8533b39d38 100644 --- a/packages/ts-components/jest.config.js +++ b/packages/ts-components/jest.config.js @@ -39,10 +39,10 @@ const buildConfig = dir => { ], coverageThreshold: { global: { - statements: 95.9, + statements: 95.5, branches: 83, - lines: 96, - functions: 96 + lines: 95.5, + functions: 94.40 } } }; diff --git a/packages/ts-components/src/components/article-audio/ArticleAudio.stories.tsx b/packages/ts-components/src/components/article-audio/ArticleAudio.stories.tsx new file mode 100644 index 0000000000..598921865e --- /dev/null +++ b/packages/ts-components/src/components/article-audio/ArticleAudio.stories.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { ArticleAudio } from './ArticleAudio'; + +storiesOf('Typescript Component/Article Audio', module).add( + 'Article Audio', + () => { + return ( +
+ +
+ ); + } +); diff --git a/packages/ts-components/src/components/article-audio/ArticleAudio.tsx b/packages/ts-components/src/components/article-audio/ArticleAudio.tsx new file mode 100644 index 0000000000..3ea2050baf --- /dev/null +++ b/packages/ts-components/src/components/article-audio/ArticleAudio.tsx @@ -0,0 +1,93 @@ +import React, { FC, useState, useRef } from 'react'; +import { AudioButton } from './styles'; +import { AudioPlayer } from '../audio-player-components/AudioPlayer'; +import { PlayIcon, PauseIcon } from '@times-components/icons'; +export interface ArticleAudioProps { + audioSrc: string; +} + +export const ArticleAudio: FC = ({ audioSrc }) => { + const [audioState, setAudioState] = useState< + 'not-started' | 'playing' | 'paused' + >('not-started'); + const [isAudioPlayerVisible, setisAudioPlayerVisible] = useState( + false + ); + const [duration, setDuration] = useState(null); + + const audioRef = useRef(null); + + const handleLoadedMetadata = () => { + if (audioRef.current) { + const totalSeconds = Math.floor(audioRef.current.duration); + const minutes = Math.floor(totalSeconds / 60) + 1; + setDuration(`${minutes}`); + } + }; + + const handlePlayPause = () => { + setisAudioPlayerVisible(true); + + if (audioState === 'playing') { + setAudioState('paused'); + } else { + setAudioState('playing'); + } + }; + + const hidePlayer = () => { + setisAudioPlayerVisible(false); + }; + + return ( +
+
+ ); +}; + +export default ArticleAudio; diff --git a/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx b/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx new file mode 100644 index 0000000000..65f270922b --- /dev/null +++ b/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx @@ -0,0 +1,192 @@ +import React from 'react'; +import { render, fireEvent, act } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; +import { ArticleAudio } from '../ArticleAudio'; + +jest.mock('../styles', () => ({ + AudioButton: ({ children, onClick, style }: any) => ( + + ) +})); + +jest.mock('@times-components/icons', () => ({ + __esModule: true, + PlayIcon: ({ color }: any) => ( + + ), + PauseIcon: ({ color }: any) => ( + + ) +})); + +jest.mock('../../audio-player-components/AudioPlayer', () => ({ + AudioPlayer: ({ onPlay, onPause, onEnded, onClose }: any) => ( +
+ + + + +
+ ) +})); + +describe('ArticleAudio', () => { + beforeEach(() => { + // Mock the duration of the audio element + Object.defineProperty(HTMLMediaElement.prototype, 'duration', { + get(): number { + return 120; // 2 minutes + } + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('renders audio button with correct initial state', () => { + const { getByTestId, getByText, container } = render( + + ); + + // Trigger the 'loadedmetadata' event to set the duration + const audio = container.querySelector('audio') as HTMLAudioElement; + act(() => { + fireEvent.loadedMetadata(audio); + }); + + const audioButton = getByTestId('audio-button'); + expect(audioButton).toBeInTheDocument(); + + expect(audioButton.style.backgroundColor).toBe(''); + expect(audioButton).toHaveStyle('color: #333'); + + // The initial state should display 'Listen' and the duration + expect(getByText('Listen')).toBeInTheDocument(); + expect(getByText('3 min')).toBeInTheDocument(); + + // Since audioState is 'not-started', duration color should be '#696969' + const durationSpan = getByText('3 min'); + expect(durationSpan).toHaveStyle('color: #696969'); + }); + + test('hides AudioPlayer when close button is clicked (using mocked AudioPlayer)', () => { + const { getByTestId, queryByTestId, container, getByText } = render( + + ); + + // Trigger the 'loadedmetadata' event to set the duration + const audio = container.querySelector('audio') as HTMLAudioElement; + act(() => { + fireEvent.loadedMetadata(audio); + }); + + // Initially, the AudioPlayer should not be visible + expect(queryByTestId('audio-player')).not.toBeInTheDocument(); + + // Click the audio button to start playback + const audioButton = getByTestId('audio-button'); + fireEvent.click(audioButton); + + // The mocked AudioPlayer should now be visible + expect(getByTestId('audio-player')).toBeInTheDocument(); + + // Use the mocked Close button inside the AudioPlayer to close it + const closeButton = getByText('Close'); + fireEvent.click(closeButton); + + // The AudioPlayer should no longer be visible + expect(queryByTestId('audio-player')).not.toBeInTheDocument(); + }); + + test('handles play and pause', () => { + const { getByTestId, getByText, container } = render( + + ); + + // Trigger the 'loadedmetadata' event to set the duration + const audio = container.querySelector('audio') as HTMLAudioElement; + act(() => { + fireEvent.loadedMetadata(audio); + }); + + const audioButton = getByTestId('audio-button'); + + // Simulate clicking the play button + fireEvent.click(audioButton); + + // Now, audioState should be 'playing' + expect(audioButton).toHaveStyle('background-color: #1D1D1B'); + expect(audioButton).toHaveStyle('color: #fff'); + expect(getByText('Playing')).toBeInTheDocument(); + + // Since audioState is 'playing', duration color should be '#fff' + const durationSpan = getByText('3 min'); + expect(durationSpan).toHaveStyle('color: #fff'); + + // Simulate clicking the pause button + fireEvent.click(audioButton); + + expect(getByText('Paused')).toBeInTheDocument(); + expect(audioButton).toHaveStyle('background-color: #1D1D1B'); + expect(audioButton).toHaveStyle('color: #fff'); + + // Simulate clicking the play button again + fireEvent.click(audioButton); + + expect(getByText('Playing')).toBeInTheDocument(); + }); + + test('shows AudioPlayer when audio is played', () => { + const { getByTestId, queryByTestId, container } = render( + + ); + + // Trigger the 'loadedmetadata' event to set the duration + const audio = container.querySelector('audio') as HTMLAudioElement; + act(() => { + fireEvent.loadedMetadata(audio); + }); + + expect(queryByTestId('audio-player')).not.toBeInTheDocument(); + + const audioButton = getByTestId('audio-button'); + fireEvent.click(audioButton); + + expect(getByTestId('audio-player')).toBeInTheDocument(); + }); + + test('updates audioState based on AudioPlayer callbacks', () => { + const { getByTestId, getByText, container } = render( + + ); + + // Trigger the 'loadedmetadata' event to set the duration + const audio = container.querySelector('audio') as HTMLAudioElement; + act(() => { + fireEvent.loadedMetadata(audio); + }); + + const audioButton = getByTestId('audio-button'); + fireEvent.click(audioButton); // Start playing + + expect(getByText('Playing')).toBeInTheDocument(); + + const pauseButton = getByText('Pause'); + fireEvent.click(pauseButton); + + expect(getByText('Paused')).toBeInTheDocument(); + + const playButton = getByText('Play'); + fireEvent.click(playButton); + + expect(getByText('Playing')).toBeInTheDocument(); + + const endedButton = getByText('Ended'); + fireEvent.click(endedButton); + + expect(getByText('Listen')).toBeInTheDocument(); + }); +}); diff --git a/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx b/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx new file mode 100644 index 0000000000..bff141f633 --- /dev/null +++ b/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; +import 'jest-styled-components'; +import { AudioButton } from '../styles'; + +describe('AudioButton', () => { + test('renders correctly with default styles', () => { + const { getByTestId } = render( + Test Button + ); + + const button = getByTestId('audio-button'); + + expect(button).toHaveStyleRule('background-color', 'unset'); + expect(button).toHaveStyleRule('border-radius', '0'); + expect(button).toHaveStyleRule('padding', '7px 11px'); + expect(button).toHaveStyleRule('border', '1px solid #333333'); + expect(button).toHaveStyleRule('display', 'flex'); + expect(button).toHaveStyleRule('align-items', 'center'); + expect(button).toHaveStyleRule('color', '#333333'); + expect(button).toHaveStyleRule('font-family', 'Roboto'); + expect(button).toHaveStyleRule('font-weight', '500'); + expect(button).toHaveStyleRule('font-size', '14px'); + expect(button).toHaveStyleRule('line-height', '18px'); + }); + + test('renders svg child with correct styles', () => { + const { getByTestId } = render( + + + + ); + + const button = getByTestId('audio-button'); + + expect(button).toHaveStyleRule('margin-right', '8px', { + modifier: 'svg' + }); + }); + + test('renders span child with correct styles', () => { + const { getByTestId } = render( + + Test Span + + ); + + const button = getByTestId('audio-button'); + + expect(button).toHaveStyleRule('margin-left', '4px', { + modifier: 'span' + }); + expect(button).toHaveStyleRule('font-size', '12px', { + modifier: 'span' + }); + expect(button).toHaveStyleRule('color', '#696969', { + modifier: 'span' + }); + }); +}); diff --git a/packages/ts-components/src/components/article-audio/styles.ts b/packages/ts-components/src/components/article-audio/styles.ts new file mode 100644 index 0000000000..9057d41ef1 --- /dev/null +++ b/packages/ts-components/src/components/article-audio/styles.ts @@ -0,0 +1,26 @@ +import styled from 'styled-components'; +import { colours } from '@times-components/ts-styleguide'; + +export const AudioButton = styled.button` + background-color: unset; + border-radius: 0; + padding: 7px 11px; + border: 1px solid ${colours.functional.primary}; + display: flex; + align-items: center; + color: ${colours.functional.primary}; + font-family: Roboto; + font-weight: 500; + font-size: 14px; + line-height: 18px; + + svg { + margin-right: 8px; + } + + span { + margin-left: 4px; + font-size: 12px; + color: ${colours.functional.secondary}; + } +`; diff --git a/packages/ts-components/src/components/audio-player-components/AudioPlayer.stories.tsx b/packages/ts-components/src/components/audio-player-components/AudioPlayer.stories.tsx new file mode 100644 index 0000000000..14b4af27dd --- /dev/null +++ b/packages/ts-components/src/components/audio-player-components/AudioPlayer.stories.tsx @@ -0,0 +1,209 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { AudioPlayer } from './AudioPlayer'; +import { withKnobs, boolean, number, text } from '@storybook/addon-knobs'; + +storiesOf('Typescript Component/Audio Player Components', module) + .addDecorator(withKnobs) + .addParameters({ + component: AudioPlayer, + docs: { + description: { + component: ` + +A customizable audio player component with various controls. + +## Props + +### \`src\` (Required) + +- **Type**: \`string\` +- **Description**: The URL of the audio source file to be played. + +### \`title\` + +- **Type**: \`string\` +- **Default**: \`'Audio Title'\` +- **Description**: The title of the audio track displayed in the player. + +### \`autoPlay\` + +- **Type**: \`boolean\` +- **Default**: \`false\` +- **Description**: Determines whether the audio should start playing automatically when the component mounts. + +### \`initialVolume\` + +- **Type**: \`number\` (Range between \`0\` and \`1\`) +- **Default**: \`1\` +- **Description**: Sets the initial volume level of the audio player. + +### \`playbackRate\` + +- **Type**: \`number\` +- **Default**: \`1\` +- **Description**: Sets the initial playback speed of the audio. + +### \`isPlayingProp\` + +- **Type**: \`boolean\` +- **Description**: Controls the play/pause state externally. When provided, it overrides the internal state. + +### \`isExpandedProp\` + +- **Type**: \`boolean\` +- **Description**: Controls the expanded/collapsed state externally. When provided, it overrides the internal state. + +### \`allowTogglePlay\` + +- **Type**: \`boolean\` +- **Default**: \`true\` +- **Description**: Enables or disables the play/pause functionality. + +### \`allowSeek\` + +- **Type**: \`boolean\` +- **Default**: \`true\` +- **Description**: Enables or disables the ability to seek through the audio track. + +### \`allowVolumeChange\` + +- **Type**: \`boolean\` +- **Default**: \`true\` +- **Description**: Enables or disables the volume control. Volume control is available on tablet and desktop views. + +### \`allowPlaybackRateChange\` + +- **Type**: \`boolean\` +- **Default**: \`true\` +- **Description**: Enables or disables the ability to change the playback speed. + +### \`allowExpandCollapse\` + +- **Type**: \`boolean\` +- **Default**: \`true\` +- **Description**: Enables or disables the ability to expand or collapse the audio player interface. + +### \`onPlay\` + +- **Type**: \`() => void\` +- **Description**: Callback function invoked when the audio starts playing. + +### \`onPause\` + +- **Type**: \`() => void\` +- **Description**: Callback function invoked when the audio is paused. + +### \`onEnded\` + +- **Type**: \`() => void\` +- **Description**: Callback function invoked when the audio playback ends. + +### \`onTimeUpdate\` + +- **Type**: \`(currentTime: number) => void\` +- **Description**: Callback function invoked when the current playback time updates. + +### \`onVolumeChange\` + +- **Type**: \`(volume: number) => void\` +- **Description**: Callback function invoked when the volume level changes. + +### \`onPlaybackRateChange\` + +- **Type**: \`(rate: number) => void\` +- **Description**: Callback function invoked when the playback rate changes. + +### \`onSeek\` + +- **Type**: \`(time: number) => void\` +- **Description**: Callback function invoked when the playback position changes due to seeking. + +### \`onClose\` + +- **Type**: \`() => void\` +- **Description**: Callback function invoked when the audio player is closed. + +## Usage Examples + +### Basic Usage + + +\`\`\`jsx + +\`\`\` + +### With Custom Title and AutoPlay + +\`\`\`jsx + +\`\`\` + +### Handling Events + +\`\`\`jsx + console.log('Playing')} + onPause={() => console.log('Paused')} + onEnded={() => console.log('Ended')} + onTimeUpdate={(currentTime) => console.log('Current Time:', currentTime)} + onVolumeChange={(volume) => console.log('Volume:', volume)} + onPlaybackRateChange={(rate) => console.log('Playback Rate:', rate)} + onSeek={(time) => console.log('Seeked to:', time)} + onClose={() => console.log('Player Closed')} +/> +\`\`\` + +` + } + } + }) + .add('Default Audio Player', () => { + const src = text( + 'src', + 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3' + ); + const title = text('title', 'Sample Audio Title for Testing'); + const autoPlay = boolean('autoPlay', false); + const initialVolume = number('initialVolume', 0.5, { + range: true, + min: 0, + max: 1, + step: 0.1 + }); + const playbackRate = number('playbackRate', 1, { + range: true, + min: 0.5, + max: 2, + step: 0.1 + }); + const isPlayingProp = boolean('isPlayingProp', false); + const isExpandedProp = boolean('isExpandedProp', true); + const allowTogglePlay = boolean('allowTogglePlay', true); + const allowSeek = boolean('allowSeek', true); + const allowVolumeChange = boolean('allowVolumeChange', true); + const allowPlaybackRateChange = boolean('allowPlaybackRateChange', true); + const allowExpandCollapse = boolean('allowExpandCollapse', true); + + const mockProps = { + src, + title, + autoPlay, + initialVolume, + playbackRate, + isPlayingProp, + isExpandedProp, + allowTogglePlay, + allowSeek, + allowVolumeChange, + allowPlaybackRateChange, + allowExpandCollapse + }; + + return ; + }); diff --git a/packages/ts-components/src/components/audio-player-components/AudioPlayer.tsx b/packages/ts-components/src/components/audio-player-components/AudioPlayer.tsx new file mode 100644 index 0000000000..302d04e1ea --- /dev/null +++ b/packages/ts-components/src/components/audio-player-components/AudioPlayer.tsx @@ -0,0 +1,324 @@ +import React, { + useState, + useEffect, + useRef, + FC, + forwardRef, + useImperativeHandle +} from 'react'; +import { AudioPlayerContainer } from './styles'; +import { StickyAudioPlayerProps, AudioPlayerHandle } from './types'; + +import { CollapseIcon } from './CollapseIcon'; +import { TitleScroller } from './TitleScroller'; +import { SeekBar } from './SeekBar'; +import { TimeDisplay } from './TimeDisplay'; +import { PlaybackControls } from './PlaybackControls'; +import { TabletDesktopPlayer } from './TabletDesktopPlayer'; + +export const AudioPlayer: FC = forwardRef( + ( + { + src, + title = 'Audio Title', + autoPlay = false, + initialVolume = 1, + playbackRate = 1, + isPlayingProp, + isExpandedProp, + allowTogglePlay = true, + allowSeek = true, + allowVolumeChange = true, + allowPlaybackRateChange = true, + allowExpandCollapse = true, + onPlay, + onPause, + onEnded, + onTimeUpdate, + onVolumeChange, + onPlaybackRateChange, + onSeek, + onClose + }, + ref + ) => { + const audioRef = useRef(null); + const [isPlaying, setIsPlaying] = useState( + isPlayingProp !== undefined && isPlayingProp !== null + ? isPlayingProp + : autoPlay + ); + const [isExpanded, setIsExpanded] = useState( + isExpandedProp !== undefined && isExpandedProp !== null + ? isExpandedProp + : true + ); + const [currentTime, setCurrentTime] = useState(0); + const [duration, setDuration] = useState(0); + const [volume, setVolume] = useState(initialVolume); + const [speed, setSpeed] = useState(playbackRate); + const [isSpeedModalOpen, setIsSpeedModalOpen] = useState(false); + const [isVolumeSliderVisible, setIsVolumeSliderVisible] = useState( + false + ); + + // State to track if the view is mobile or tablet/desktop + const [isMobile, setIsMobile] = useState( + typeof window !== 'undefined' ? window.innerWidth <= 520 : true + ); + + // Effect to handle window resize + useEffect(() => { + const handleResize = () => { + if (typeof window !== 'undefined') { + setIsMobile(window.innerWidth <= 520); + } + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + useImperativeHandle( + ref, + (): AudioPlayerHandle => ({ + parentControlToggle: (): void => { + togglePlayPause(); + } + }) + ); + + useEffect( + () => { + if (audioRef.current) { + audioRef.current.volume = volume; + audioRef.current.playbackRate = speed; + } + }, + [volume, speed] + ); + + useEffect( + () => { + if (typeof isPlayingProp === 'boolean') { + if (isPlayingProp && audioRef.current) { + audioRef.current + .play() + .then(() => { + setIsPlaying(true); + }) + .catch(() => { + throw Error('Error attempting to play:'); + }); + } else if (audioRef.current) { + audioRef.current.pause(); + setIsPlaying(false); + } + } + }, + [isPlayingProp] + ); + + useEffect( + () => { + if (typeof isExpandedProp === 'boolean') { + setIsExpanded(isExpandedProp); + } + }, + [isExpandedProp] + ); + + const togglePlayPause = () => { + if (!allowTogglePlay) { + return; + } + if (audioRef.current && audioRef.current.paused) { + audioRef.current + .play() + .then(() => { + setIsPlaying(true); + if (onPlay) { + onPlay(); + } + }) + .catch(() => { + throw Error('Error attempting to play:'); + }); + } else if (audioRef.current) { + audioRef.current.pause(); + setIsPlaying(false); + if (onPause) { + onPause(); + } + } + }; + + const toggleExpand = () => { + if (!allowExpandCollapse) { + return; + } + setIsExpanded(!isExpanded); + }; + + const handleTimeUpdate = () => { + if (!allowSeek) { + return; + } + const newTime = + audioRef.current && + audioRef.current.currentTime !== undefined && + audioRef.current.currentTime !== null + ? audioRef.current.currentTime + : 0; + setCurrentTime(newTime); + if (onTimeUpdate) { + onTimeUpdate(newTime); + } + }; + + const handleLoadedMetadata = () => { + const loadedDuration = + audioRef.current && + audioRef.current.duration !== undefined && + audioRef.current.duration !== null + ? audioRef.current.duration + : 0; + setDuration(loadedDuration); + }; + + const handleSeek = (time: number) => { + if (!allowSeek) { + return; + } + if (audioRef.current) { + const clampedTime = Math.min(Math.max(time, 0), duration); + audioRef.current.currentTime = clampedTime; + setCurrentTime(clampedTime); + if (onSeek) { + onSeek(clampedTime); + } + } + }; + + const handleRewind = () => { + handleSeek(currentTime - 10); + }; + + const handleForward = () => { + handleSeek(currentTime + 10); + }; + + const handleVolumeChange = (newVolume: number) => { + if (!allowVolumeChange) { + return; + } + setVolume(newVolume); + if (audioRef.current) { + audioRef.current.volume = newVolume; + } + if (onVolumeChange) { + onVolumeChange(newVolume); + } + }; + + const handleSpeedChange = (rate: number) => { + if (!allowPlaybackRateChange) { + return; + } + setSpeed(rate); + if (audioRef.current) { + audioRef.current.playbackRate = rate; + } + if (onPlaybackRateChange) { + onPlaybackRateChange(rate); + } + }; + + const speedOptions = [0.5, 0.8, 1.0, 1.2, 1.5, 2]; + + const handleSpeedSelect = (selectedSpeed: number) => { + handleSpeedChange(selectedSpeed); + setIsSpeedModalOpen(false); + }; + + return ( + <> +