feat: show organization information on templates page (#14224)

This commit is contained in:
Kayla Washburn-Love
2024-08-12 09:15:13 -06:00
committed by GitHub
parent 9715ae5932
commit 59a80d70dc
7 changed files with 63 additions and 17 deletions
@@ -13,12 +13,14 @@ import type {
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { Loader } from "components/Loader/Loader";
import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata";
import { selectFeatureVisibility } from "./entitlements";
export interface DashboardValue {
entitlements: Entitlements;
experiments: Experiments;
appearance: AppearanceConfig;
organizations: Organization[];
showOrganizations: boolean;
}
export const DashboardContext = createContext<DashboardValue | undefined>(
@@ -52,6 +54,11 @@ export const DashboardProvider: FC<PropsWithChildren> = ({ children }) => {
return <Loader fullscreen />;
}
const hasMultipleOrganizations = organizationsQuery.data.length > 1;
const organizationsEnabled =
experimentsQuery.data.includes("multi-organization") &&
selectFeatureVisibility(entitlementsQuery.data).multiple_organizations;
return (
<DashboardContext.Provider
value={{
@@ -59,6 +66,7 @@ export const DashboardProvider: FC<PropsWithChildren> = ({ children }) => {
experiments: experimentsQuery.data,
appearance: appearanceQuery.data,
organizations: organizationsQuery.data,
showOrganizations: hasMultipleOrganizations || organizationsEnabled,
}}
>
{children}
+2 -9
View File
@@ -4,7 +4,6 @@
import { useEffectEvent } from "hooks/hookPolyfills";
import type { DashboardValue } from "./dashboard/DashboardProvider";
import { selectFeatureVisibility } from "./dashboard/entitlements";
import { useDashboard } from "./dashboard/useDashboard";
type LinkThunk = (state: DashboardValue) => string;
@@ -27,13 +26,7 @@ export const linkToUsers = withFilter("/users", "status:active");
export const linkToTemplate =
(organizationName: string, templateName: string): LinkThunk =>
(dashboard) => {
const hasMultipleOrganizations = dashboard.organizations.length > 1;
const organizationsEnabled =
dashboard.experiments.includes("multi-organization") &&
selectFeatureVisibility(dashboard.entitlements).multiple_organizations;
return hasMultipleOrganizations || organizationsEnabled
(dashboard) =>
dashboard.showOrganizations
? `/templates/${organizationName}/${templateName}`
: `/templates/${templateName}`;
};
@@ -13,7 +13,7 @@ import { DeploySettingsContext } from "../DeploySettingsPage/DeploySettingsLayou
import { Sidebar } from "./Sidebar";
type OrganizationSettingsValue = {
organizations: Organization[] | undefined;
organizations: Organization[];
};
export const useOrganizationSettings = (): OrganizationSettingsValue => {
@@ -3,11 +3,13 @@ import { Helmet } from "react-helmet-async";
import { useQuery } from "react-query";
import { templateExamples, templates } from "api/queries/templates";
import { useAuthenticated } from "contexts/auth/RequireAuth";
import { useDashboard } from "modules/dashboard/useDashboard";
import { pageTitle } from "utils/page";
import { TemplatesPageView } from "./TemplatesPageView";
export const TemplatesPage: FC = () => {
const { permissions } = useAuthenticated();
const { showOrganizations } = useDashboard();
const templatesQuery = useQuery(templates());
const examplesQuery = useQuery({
@@ -23,6 +25,7 @@ export const TemplatesPage: FC = () => {
</Helmet>
<TemplatesPageView
error={error}
showOrganizations={showOrganizations}
canCreateTemplates={permissions.createTemplates}
examples={examplesQuery.data}
templates={templatesQuery.data}
@@ -69,6 +69,13 @@ export const WithTemplates: Story = {
},
};
export const MultipleOrganizations: Story = {
args: {
...WithTemplates.args,
showOrganizations: true,
},
};
export const EmptyCanCreate: Story = {
args: {
canCreateTemplates: true,
@@ -81,10 +81,11 @@ const TemplateHelpTooltip: FC = () => {
};
interface TemplateRowProps {
showOrganizations: boolean;
template: Template;
}
const TemplateRow: FC<TemplateRowProps> = ({ template }) => {
const TemplateRow: FC<TemplateRowProps> = ({ showOrganizations, template }) => {
const getLink = useLinks();
const templatePageLink = getLink(
linkToTemplate(template.organization_name, template.name),
@@ -120,7 +121,23 @@ const TemplateRow: FC<TemplateRowProps> = ({ template }) => {
</TableCell>
<TableCell css={styles.secondary}>
{Language.developerCount(template.active_user_count)}
{showOrganizations ? (
<Stack
spacing={0}
css={{
width: "100%",
}}
>
<span css={styles.cellPrimaryLine}>
{template.organization_display_name}
</span>
<span css={styles.cellSecondaryLine}>
Used by {Language.developerCount(template.active_user_count)}
</span>
</Stack>
) : (
Language.developerCount(template.active_user_count)
)}
</TableCell>
<TableCell css={styles.secondary}>
@@ -156,16 +173,18 @@ const TemplateRow: FC<TemplateRowProps> = ({ template }) => {
export interface TemplatesPageViewProps {
error?: unknown;
showOrganizations: boolean;
canCreateTemplates: boolean;
examples: TemplateExample[] | undefined;
templates: Template[] | undefined;
canCreateTemplates: boolean;
}
export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
templates,
error,
examples,
showOrganizations,
canCreateTemplates,
examples,
templates,
}) => {
const isLoading = !templates;
const isEmpty = templates && templates.length === 0;
@@ -209,7 +228,9 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
<TableHead>
<TableRow>
<TableCell width="35%">{Language.nameLabel}</TableCell>
<TableCell width="15%">{Language.usedByLabel}</TableCell>
<TableCell width="15%">
{showOrganizations ? "Organization" : Language.usedByLabel}
</TableCell>
<TableCell width="10%">{Language.buildTimeLabel}</TableCell>
<TableCell width="15%">{Language.lastUpdatedLabel}</TableCell>
<TableCell width="1%"></TableCell>
@@ -225,7 +246,11 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
/>
) : (
templates?.map((template) => (
<TemplateRow key={template.id} template={template} />
<TemplateRow
key={template.id}
showOrganizations={showOrganizations}
template={template}
/>
))
)}
</TableBody>
@@ -276,6 +301,15 @@ const styles = {
actionCell: {
whiteSpace: "nowrap",
},
cellPrimaryLine: (theme) => ({
color: theme.palette.text.primary,
fontWeight: 600,
}),
cellSecondaryLine: (theme) => ({
fontSize: 13,
color: theme.palette.text.secondary,
lineHeight: "150%",
}),
secondary: (theme) => ({
color: theme.palette.text.secondary,
}),
+1
View File
@@ -41,6 +41,7 @@ export const withDashboardProvider = (
experiments,
appearance: MockAppearanceConfig,
organizations: [MockDefaultOrganization],
showOrganizations: false,
}}
>
<Story />