Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add links to lifecycle pill #6845

Merged
merged 6 commits into from
Jan 30, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions website/docs/docs/introduction.md
Original file line number Diff line number Diff line change
@@ -17,13 +17,6 @@ Read more about why we want to enable analysts to work more like software engine

Use dbt to quickly and collaboratively transform data and deploy analytics code following software engineering best practices like version control, modularity, portability, CI/CD, and documentation. This means anyone on the data team comfortable with SQL can safely contribute to production-grade data pipelines.

<!-- removing per Leona's feedback and pending review
To cater to the diverse needs of data teams, dbt offers two primary solutions:

- [**dbt Cloud**](#dbt-cloud) &mdash; A comprehensive, full managed service enabling teams to develop, test, deploy, and explore data products safely and reliably.
- [**dbt Core**](#dbt-core) &mdash; An open-source CLI tool that's suitable for users who prefer a manual setup.
-->

### dbt Cloud

dbt Cloud offers the fastest, most reliable, and scalable way to deploy dbt. Allowing data teams to optimize their data transformation by developing, testing, scheduling, and investigating data models using a single, fully managed service through a web-based user interface (UI).
59 changes: 31 additions & 28 deletions website/src/components/expandable/index.js
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ function slugify(text) {
.replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/\s+/g, '-') // replace spaces with -
.replace(/[^\w\-]+/g, '') // remove all non-word chars
.replace(/\-\-+/g, '-') // replace multipl - with a single -
.replace(/\-\-+/g, '-') // replace multiple - with a single -
.replace(/^-+/, '') // trim - from the start
.replace(/-+$/, ''); // trim - from the end
}
@@ -39,43 +39,46 @@ function Expandable({ children, alt_header = null, lifecycle }) {
popup.classList.add('copy-popup');
popup.innerText = 'Link copied!';

// Add close button ('x')
const closeButton = document.createElement('span');
closeButton.classList.add('close-button');
closeButton.innerHTML = ' &times;'; // '×' symbol for 'x'
closeButton.addEventListener('click', () => {
if (document.body.contains(popup)) {
document.body.removeChild(popup);
}
});
popup.appendChild(closeButton);
// Add close button ('x')
const closeButton = document.createElement('span');
closeButton.classList.add('close-button');
closeButton.innerHTML = ' &times;'; // '×' symbol for 'x'
closeButton.addEventListener('click', () => {
if (document.body.contains(popup)) {
document.body.removeChild(popup);
}
});
popup.appendChild(closeButton);

document.body.appendChild(popup);
document.body.appendChild(popup);

setTimeout(() => {
if (document.body.contains(popup)) {
document.body.removeChild(popup);
}
}, 3000);
};
setTimeout(() => {
if (document.body.contains(popup)) {
document.body.removeChild(popup);
}
}, 3000);
};

useEffect(() => {
if (window.location.hash === `#${anchorId}`) {
setOn(true);
const element = document.getElementById(anchorId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
useEffect(() => {
if (window.location.hash === `#${anchorId}`) {
setOn(true);
const element = document.getElementById(anchorId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}
}
}, [anchorId]);
}, [anchorId]);

return (
<div id={anchorId} className={`${styles.expandableContainer} `}>
<div id={anchorId} className={`${styles.expandableContainer}`}>
<div className={styles.header} onClick={handleToggleClick}>
<span className={`${styles.toggle} ${isOn ? styles.toggleDown : styles.toggleRight}`}></span>
&nbsp;
<span className={styles.headerText}>
{alt_header}<Lifecycle status={lifecycle} />
{alt_header}
<span onClick={(e) => e.stopPropagation()}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this stops the copy link propagation so that users can click the pill for the link or click on the icon to copy the url

<Lifecycle status={lifecycle} />
</span>
</span>
<span onClick={handleCopyClick} className={styles.copyIcon}></span>
</div>
58 changes: 48 additions & 10 deletions website/src/components/lifeCycle/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from 'react'
/* eslint-disable */

import React from 'react';
import styles from './styles.module.css';
import { STATUS_URLS } from './lifecycle-urls.js';

const statusColors = {
enterprise: '#EBEDF0',
@@ -12,28 +15,63 @@ const statusColors = {
};

const fontColors = {
enterprise: '#262A38',
team: '#262A38',
developer: '#262A38',
// lifecycle statuses use the css determined font color (white)
};
enterprise: '#262A38',
team: '#262A38',
developer: '#262A38',
preview: '#ffff',
beta: '#ffff',
ga: '#ffff',
};

// URL mapping for predefined lifecycle statuses. urls defined in ../lifeCycle/lifecycle-urls.js file so we can update them in one place
const statusUrls = STATUS_URLS;

export default function Lifecycle(props) {
const statuses = props.status?.split(',')
const statuses = props.status?.split(',');
if (!props.status || !statuses?.length) {
return null;
}

return (
<>
{statuses.map((status, index) => {
const isKnownStatus = Object.prototype.hasOwnProperty.call(statusColors, status);
const url = isKnownStatus ? statusUrls[status] || props.customUrl || null : null;

const style = {
backgroundColor: props.backgroundColor || statusColors[status] || '#047377', // default to teal if no match
color: fontColors[status] || '#fff' // default font color if no matc
backgroundColor: props.backgroundColor || statusColors[status] || '#d3d3d3', // Default gray for unknown status
color: fontColors[status] || '#000', // Default black for unknown status
cursor: url ? 'pointer' : 'default', // Non-clickable for unknown status
transition: 'background-color 0.2s ease, transform 0.2s ease, text-decoration 0.2s ease',
padding: '5px 10px',
borderRadius: '16px',
textDecoration: url ? 'underline' : 'none', // Underline for clickable pills only
};

// Render a clickable pill for known statuses with a URL
if (url) {
return (
<a
key={index}
href={url}
target="_blank"
rel="noopener noreferrer"
className={`${styles.lifecycle} lifecycle`}
style={style}
title={`Go to ${url}`} // optional tooltip for better UX
>
{status}
</a>
);
}

// Render a static pill for unknown or unlinked statuses
return (
<span key={index} className={`${styles.lifecycle} lifecycle-badge`} style={style}>
<span
key={index}
className={`${styles.lifecycle} lifecycle`}
style={style}
>
{status}
</span>
);
11 changes: 11 additions & 0 deletions website/src/components/lifeCycle/lifecycle-urls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const PRODUCT_LIFECYCLE_URL = 'https://docs.getdbt.com/docs/dbt-versions/product-lifecycles';
const PLAN_URL = 'https://www.getdbt.com/pricing';

export const STATUS_URLS = {
enterprise: PLAN_URL,
team: PLAN_URL,
developer: 'https://www.getdbt.com/signup',
beta: PRODUCT_LIFECYCLE_URL,
preview: PRODUCT_LIFECYCLE_URL,
ga: PRODUCT_LIFECYCLE_URL,
};
17 changes: 16 additions & 1 deletion website/src/components/lifeCycle/styles.module.css
Original file line number Diff line number Diff line change
@@ -5,11 +5,26 @@
font-weight: 600; /* Normal font weight */
padding: 1px 8px; /* Adjust padding for a more pill-like shape */
border-radius: 16px; /* Larger border-radius for rounded edges */
margin-left: 8px; /* Margin to separate from the header text */
margin-left: 16px; /* Margin to separate from the header text */
vertical-align: middle; /* Align with the title */
display: inline-block; /* Use inline-block for better control */
text-transform: capitalize; /* Uppercase text */
line-height: 1.6; /* Adjust line height for vertical alignment */
text-decoration: none; /* No underline by default */
transition: background-color 0.2s ease, transform 0.2s ease, text-decoration 0.2s ease;
cursor: pointer;
}

.lifecycle:hover {
background-color: #EBEDF0;
color: #e3f2fd;
text-decoration: underline;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
transform: scale(1.09); /* Slightly enlarge the pill */
}

.lifecycle:focus {
outline: 2px solid #EBEDF0; /* Focus outline for accessibility */
outline-offset: 2px;
}


Unchanged files with check annotations Beta

version: dbtVersion,
EOLDate,
isPrerelease,
latestStableRelease,

Check warning on line 43 in website/src/theme/DocRoot/Layout/Main/index.js

GitHub Actions / eslint-check

'latestStableRelease' is assigned a value but never used
} = useContext(VersionContext);
const {
pageAvailable,

Check warning on line 47 in website/src/theme/DocRoot/Layout/Main/index.js

GitHub Actions / eslint-check

'pageAvailable' is assigned a value but never used
firstAvailableVersion,
lastAvailableVersion

Check warning on line 49 in website/src/theme/DocRoot/Layout/Main/index.js

GitHub Actions / eslint-check

'lastAvailableVersion' is assigned a value but never used
} = pageVersionCheck(dbtVersion, versionedPages, currentDocRoute);
const hasFirstAvailableVersion =

Check warning on line 52 in website/src/theme/DocRoot/Layout/Main/index.js

GitHub Actions / eslint-check

'hasFirstAvailableVersion' is assigned a value but never used
firstAvailableVersion && firstAvailableVersion !== "0";
// Check whether this version is a isPrerelease, and show banner if so