Skip to content

Commit

Permalink
Add new embed card style
Browse files Browse the repository at this point in the history
Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Co-authored-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
Co-authored-by: Sergio Castaño Arteaga <tegioz@icloud.com>
  • Loading branch information
tegioz and cynthia-sg committed May 9, 2024
1 parent 78a0623 commit 5dfce2c
Show file tree
Hide file tree
Showing 19 changed files with 705 additions and 214 deletions.
1 change: 1 addition & 0 deletions ADOPTERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ If you are using **Landscape2**, please consider adding your landscape to this l
*(ordered alphabetically)*

- [Academy Software Foundation](https://aswf.landscape2.io)
- [Alliance for OpenUSD](https://aousd.landscape2.io)
- [CAMARA Project](https://camara.landscape2.io)
- [Cloud Native Computing Foundation](https://landscape.cncf.io)
- [Continuous Delivery Foundation](https://cdf.landscape2.io)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ In addition to the information available in the landscape data file, the tool co

- **GitHub**: a list of comma separated GitHub tokens with `public_repo` scope can be provided in the `GITHUB_TOKENS` environment variable. When these tokens are not provided no information from GitHub will be collected. If the expected number of items in the landscape is large it is recommended to provide more than one token to avoid hitting rate limits and speed up the collection of data (the concurrency of the process will be based on the number of tokens provided).

- **Crunchbase**: a Crunchbase API key can be provided in the `CRUNCHBASE_API_KEY` environment variable. If this token is not provided no information from Crunchbase will be collected.
- **Crunchbase**: a Crunchbase API key can be provided in the `CRUNCHBASE_API_KEY` environment variable. If this token is not provided no information from Crunchbase will be collected. Please note that landscape2 *needs access to the full Crunchbase API*, which requires an [Enterprise or Application license](https://data.crunchbase.com/docs/using-the-api).

## Installation

Expand Down
56 changes: 55 additions & 1 deletion crates/core/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ impl From<legacy::LandscapeData> for LandscapeData {
unnamed_organization: legacy_item.unnamed_organization,
..Default::default()
};
item.set_id();

// Additional categories
if let Some(second_path) = legacy_item.second_path {
Expand Down Expand Up @@ -436,6 +435,8 @@ impl From<legacy::LandscapeData> for LandscapeData {
}
}

item.set_id();
item.set_website();
data.items.push(item);
}
}
Expand Down Expand Up @@ -488,6 +489,7 @@ pub struct Item {
pub logo: String,
pub name: String,
pub subcategory: String,
pub website: String,

#[serde(skip_serializing_if = "Option::is_none")]
pub accepted_at: Option<NaiveDate>,
Expand Down Expand Up @@ -658,6 +660,26 @@ impl Item {
normalize_name(&self.name)
);
}

/// Set item's website.
///
/// The homepage URL is the preferred source for the website. However, when
/// it matches the primary repository URL, we'll fallback to the homepage
/// URL defined in the Crunchbase data -when available-.
pub fn set_website(&mut self) {
if let Some(primary_repository) = self.primary_repository() {
if self.homepage_url == primary_repository.url {
if let Some(crunchbase_data) = &self.crunchbase_data {
if let Some(cb_homepage_url) = &crunchbase_data.homepage_url {
self.website.clone_from(cb_homepage_url);
return;
}
}
}
}

self.website.clone_from(&self.homepage_url);
}
}

/// Crunchbase acquisition details.
Expand Down Expand Up @@ -1356,6 +1378,7 @@ mod tests {
training_type: Some("training_type".to_string()),
twitter_url: Some("twitter_url".to_string()),
unnamed_organization: Some(false),
website: "homepage_url".to_string(),
youtube_url: Some("youtube_url".to_string()),
}],
};
Expand Down Expand Up @@ -1488,4 +1511,35 @@ mod tests {
item.set_id();
assert_eq!(item.id, "category--subcategory--item".to_string());
}

#[test]
fn item_set_website_from_crunchbase_data() {
let mut item = Item {
crunchbase_data: Some(Organization {
homepage_url: Some("crunchbase_homepage_url".to_string()),
..Default::default()
}),
homepage_url: "repository_url".to_string(),
repositories: Some(vec![Repository {
url: "repository_url".to_string(),
primary: Some(true),
..Default::default()
}]),
..Default::default()
};

item.set_website();
assert_eq!(item.website, "crunchbase_homepage_url".to_string());
}

#[test]
fn item_set_website_from_homepage_url() {
let mut item = Item {
homepage_url: "homepage_url".to_string(),
..Default::default()
};

item.set_website();
assert_eq!(item.website, "homepage_url".to_string());
}
}
117 changes: 112 additions & 5 deletions crates/core/src/datasets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Datasets {
pub fn new(i: &NewDatasetsInput) -> Self {
Datasets {
base: Base::new(i.landscape_data, i.settings, i.guide, i.qr_code),
embed: Embed::new(i.landscape_data),
embed: Embed::new(i.landscape_data, i.settings),
full: Full::new(i.landscape_data, i.crunchbase_data, i.github_data),
stats: Stats::new(i.landscape_data, i.settings),
}
Expand Down Expand Up @@ -252,8 +252,10 @@ pub mod base {
/// This dataset contains some information about all the embeddable views that
/// can be generated from the information available in the landscape data.
pub mod embed {
use super::base::Item;
use crate::data::{Category, LandscapeData};
use crate::{
data::{self, AdditionalCategory, Category, LandscapeData},
settings::LandscapeSettings,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

Expand All @@ -266,13 +268,14 @@ pub mod embed {

impl Embed {
/// Create a new Embed instance from the data provided.
pub fn new(landscape_data: &LandscapeData) -> Self {
pub fn new(landscape_data: &LandscapeData, settings: &LandscapeSettings) -> Self {
let mut views = HashMap::new();

for category in &landscape_data.categories {
// Full category view
let key = category.normalized_name.clone();
let view = EmbedView {
foundation: settings.foundation.clone(),
category: category.clone(),
items: landscape_data
.items
Expand All @@ -287,6 +290,7 @@ pub mod embed {
for subcategory in &category.subcategories {
let key = format!("{}--{}", category.normalized_name, subcategory.normalized_name,);
let view = EmbedView {
foundation: settings.foundation.clone(),
category: Category {
name: category.name.clone(),
normalized_name: category.normalized_name.clone(),
Expand Down Expand Up @@ -314,10 +318,59 @@ pub mod embed {
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct EmbedView {
pub category: Category,
pub foundation: String,

#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub items: Vec<Item>,
}

/// Embed dataset item information.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Item {
pub category: String,
pub id: String,
pub name: String,
pub logo: String,
pub subcategory: String,
pub website: String,

#[serde(skip_serializing_if = "Option::is_none")]
pub additional_categories: Option<Vec<AdditionalCategory>>,

#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub maturity: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub member_subcategory: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub organization_name: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub primary_repository_url: Option<String>,
}

impl From<&data::Item> for Item {
fn from(data_item: &data::Item) -> Self {
Item {
additional_categories: data_item.additional_categories.clone(),
category: data_item.category.clone(),
description: data_item.description().cloned(),
id: data_item.id.clone(),
name: data_item.name.clone(),
logo: data_item.logo.clone(),
maturity: data_item.maturity.clone(),
member_subcategory: data_item.member_subcategory.clone(),
organization_name: data_item.crunchbase_data.as_ref().and_then(|org| org.name.clone()),
primary_repository_url: data_item.primary_repository().map(|r| r.url.clone()),
subcategory: data_item.subcategory.clone(),
website: data_item.website.clone(),
}
}
}
}

/// Full dataset.
Expand Down Expand Up @@ -588,9 +641,14 @@ mod tests {
}],
items: vec![item.clone()],
};
let settings = LandscapeSettings {
foundation: "Foundation".to_string(),
..Default::default()
};

let embed = Embed::new(&landscape_data);
let embed = Embed::new(&landscape_data, &settings);
let expected_embed_view = EmbedView {
foundation: "Foundation".to_string(),
category: data::Category {
name: "Category 1".to_string(),
normalized_name: "category-1".to_string(),
Expand All @@ -612,6 +670,55 @@ mod tests {
pretty_assertions::assert_eq!(embed, expected_embed);
}

#[test]
fn embed_item_from_data_item() {
let data_item = data::Item {
additional_categories: Some(vec![AdditionalCategory {
category: "Category 2".to_string(),
subcategory: "Subcategory 3".to_string(),
}]),
category: "Category 1".to_string(),
crunchbase_data: Some(Organization {
name: Some("Organization".to_string()),
..Default::default()
}),
description: Some("Description".to_string()),
id: "id".to_string(),
logo: "logo.svg".to_string(),
maturity: Some("graduated".to_string()),
member_subcategory: Some("Member subcategory".to_string()),
name: "Item".to_string(),
repositories: Some(vec![Repository {
url: "https://repository.url".to_string(),
primary: Some(true),
..Default::default()
}]),
subcategory: "Subcategory 1".to_string(),
website: "https://homepage.url".to_string(),
..Default::default()
};

let item = embed::Item::from(&data_item);
let expected_item = embed::Item {
additional_categories: Some(vec![AdditionalCategory {
category: "Category 2".to_string(),
subcategory: "Subcategory 3".to_string(),
}]),
category: "Category 1".to_string(),
description: Some("Description".to_string()),
id: "id".to_string(),
logo: "logo.svg".to_string(),
maturity: Some("graduated".to_string()),
member_subcategory: Some("Member subcategory".to_string()),
name: "Item".to_string(),
organization_name: Some("Organization".to_string()),
primary_repository_url: Some("https://repository.url".to_string()),
subcategory: "Subcategory 1".to_string(),
website: "https://homepage.url".to_string(),
};
pretty_assertions::assert_eq!(item, expected_item);
}

#[test]
fn full_new() {
let item = data::Item {
Expand Down
2 changes: 2 additions & 0 deletions ui/embed/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ const App = () => {
fallback={
<StyleView
items={data()!.items}
foundation={data()!.foundation}
style={itemsStyleView()}
size={itemsSize()}
alignment={itemsAlignment()}
Expand Down Expand Up @@ -338,6 +339,7 @@ const App = () => {
</SubcategoryTitle>
<StyleView
items={items}
foundation={data()!.foundation}
style={itemsStyleView()}
size={itemsSize()}
alignment={itemsAlignment()}
Expand Down
Loading

0 comments on commit 5dfce2c

Please sign in to comment.