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 startup assistant to the UI #17731

Merged
merged 50 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
0b3134e
Ensure the DEP enrollment profiles get regenerated when enable releas…
mna Mar 19, 2024
324b5bc
Fix some tests
mna Mar 19, 2024
49f6bb1
Fix test that failed when running the suite, but not in isolation
mna Mar 19, 2024
e642835
Fix-ish for idp/macos setup settings
mna Mar 19, 2024
f946401
Add plan for release implementation
mna Mar 20, 2024
17cf645
Fix worker tests
mna Mar 20, 2024
7ae50b9
setup assistant UI
ghernandez345 Mar 18, 2024
463a947
Queue delayed job for post-dep release, adjust tests
mna Mar 20, 2024
62e321b
Finish integration test, make it pass
mna Mar 20, 2024
cbd3377
Fix dep release test with fleetd config profile also sent
mna Mar 20, 2024
f289693
Add integration test for global manual release
mna Mar 20, 2024
a7e068b
Add team-enrolled release device test
mna Mar 20, 2024
51aa4e3
Refactor integration tests
mna Mar 20, 2024
938983d
Add database migration to re-generate all DEP profiles
mna Mar 20, 2024
b9095ea
Add DB migration, adjust tests
mna Mar 20, 2024
6041f0e
Add schema changes
mna Mar 20, 2024
3d55339
Use hard-coded timestamps so schema.sql is stable
mna Mar 20, 2024
a53a8c4
Add changes file
mna Mar 20, 2024
8c8803e
Fix erroneous comments
mna Mar 20, 2024
c09f3e8
Remove obsolete todo
mna Mar 20, 2024
96995e8
add advanced options section
ghernandez345 Mar 21, 2024
d98e434
fix up some styles
ghernandez345 Mar 21, 2024
bacff62
delete modal
ghernandez345 Mar 21, 2024
76a066f
Merge branch 'feat-prefill-account-name' into feat-ui-startup-assistant
ghernandez345 Mar 21, 2024
53b7f15
get correct config
ghernandez345 Mar 21, 2024
472f30d
change file names and change rendering for uploader section
ghernandez345 Mar 21, 2024
84453cb
update global config for release device
ghernandez345 Mar 21, 2024
1727fe5
update team config release device settings
ghernandez345 Mar 21, 2024
35813ee
pass default release device setting to advanced form
ghernandez345 Mar 21, 2024
8e706f1
get enrollment profile
ghernandez345 Mar 21, 2024
cba0383
show uploader correctly
ghernandez345 Mar 22, 2024
00df0d3
set up deleting mdm profile
ghernandez345 Mar 22, 2024
1d39566
finish up download
ghernandez345 Mar 25, 2024
b976ee9
Merge branch 'feat-prefill-account-name' into mna-17401-post-dep-enro…
ghernandez345 Mar 25, 2024
befd7be
Merge branch 'mna-17401-post-dep-enroll-device-release' into feat-ui-…
ghernandez345 Mar 25, 2024
60b25ea
fix build
ghernandez345 Mar 25, 2024
df85616
change endpoint to update relese device settings
ghernandez345 Mar 25, 2024
770c9d4
Add debugging information to release device job
mna Mar 25, 2024
1c2c1d7
Merge branch 'mna-17401-post-dep-enroll-device-release' into feat-ui-…
ghernandez345 Mar 25, 2024
c4da092
Fix awaiting for empty command uuid
mna Mar 25, 2024
c77820c
Merge branch 'mna-17401-post-dep-enroll-device-release' into feat-ui-…
ghernandez345 Mar 25, 2024
f44ddb3
pass though error messages
ghernandez345 Mar 25, 2024
060532d
finish errors
ghernandez345 Mar 25, 2024
a936cd9
Merge branch 'feat-prefill-account-name' into feat-ui-startup-assistant
ghernandez345 Mar 25, 2024
8dfbf7a
fix build
ghernandez345 Mar 25, 2024
baeb07f
pr updates
ghernandez345 Mar 26, 2024
c84d2e0
change file uploader label
ghernandez345 Mar 26, 2024
1c5c264
use reveal button
ghernandez345 Mar 26, 2024
791f639
remove unuused styles file
ghernandez345 Mar 26, 2024
cb84f76
change apos character
ghernandez345 Mar 26, 2024
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
1 change: 1 addition & 0 deletions frontend/__mocks__/configMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ const DEFAULT_CONFIG_MOCK: IConfig = {
bootstrap_package: "",
enable_end_user_authentication: false,
macos_setup_assistant: null,
enable_release_device_manually: false,
},
macos_migration: {
enable: false,
Expand Down
14 changes: 12 additions & 2 deletions frontend/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ type CardColor = "white" | "gray" | "purple" | "yellow";

interface ICardProps {
children?: React.ReactNode;
/** The size of the border radius. Defaults to `small` */
/** The size of the border radius. Defaults to `small`. */
borderRadiusSize?: BorderRadiusSize;
/** Includes the card shadows. Defaults to `false` */
includeShadow?: boolean;
/** The color of the card. Defaults to `white` */
color?: CardColor;
className?: string;
/** Increases to 40px padding. Defaults to `false` */
/** The size of the padding around the content of the card. Defaults to `large`.
*
* These correspond to the padding sizes in the design system. Look at `padding.scss` for values */
paddingSize?: "small" | "medium" | "large" | "xlarge" | "xxlarge";
/** NOTE: DEPRICATED. Use `paddingSize` prop instead.
*
* Increases to 40px padding. Defaults to `false` */
largePadding?: boolean;
}

Expand All @@ -30,12 +36,16 @@ const Card = ({
color = "white",
className,
largePadding = false,
paddingSize = "large",
}: ICardProps) => {
const classNames = classnames(
baseClass,
`${baseClass}__${color}`,
`${baseClass}__radius-${borderRadiusSize}`,
{
// TODO: simplify this when we've replaced largePadding prop with paddingSize
[`${baseClass}__padding-${paddingSize}`]:
!largePadding && paddingSize !== undefined,
[`${baseClass}__shadow`]: includeShadow,
[`${baseClass}__large-padding`]: largePadding,
},
Expand Down
22 changes: 22 additions & 0 deletions frontend/components/Card/_styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,29 @@
box-shadow: $box-shadow;
}

&__padding-small {
padding: $pad-small;
}

&__padding-medium {
padding: $pad-medium;
}

&__padding-large {
padding: $pad-large;
}

&__padding-xlarge {
padding: $pad-xlarge;
}

&__padding-xxlarge {
padding: $pad-xxlarge;
}

// 40px padding
// TODO: remove when we've replaced all instances of largePadding with
// paddingSize prop
&__large-padding {
padding: $pad-xxlarge;
}
Expand Down
5 changes: 4 additions & 1 deletion frontend/components/FileUploader/FileUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ interface IFileUploaderProps {
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
*/
accept?: string;
/** The text to display on the upload button */
buttonMessage?: string;
className?: string;
onFileUpload: (files: FileList | null) => void;
}
Expand All @@ -45,6 +47,7 @@ const FileUploader = ({
additionalInfo,
isLoading = false,
accept,
buttonMessage = "Upload",
className,
onFileUpload,
}: IFileUploaderProps) => {
Expand Down Expand Up @@ -73,7 +76,7 @@ const FileUploader = ({
variant="brand"
isLoading={isLoading}
>
<label htmlFor="upload-profile">Upload</label>
<label htmlFor="upload-profile">{buttonMessage}</label>
Copy link
Member

Choose a reason for hiding this comment

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

more generic than "upload-profile"?

</Button>
<input
accept={accept}
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/FileUploader/_styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@

&__upload-button {
margin-top: 8px;
// we handle the padding in the label so the entire button is clickable
padding: 0;
}

label {
height: 36px;
width: 78.2667px;
padding: $pad-small $pad-medium;
display: flex;
align-items: center;
justify-content: center;
Expand Down
1 change: 1 addition & 0 deletions frontend/interfaces/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface IMdmConfig {
bootstrap_package: string | null;
enable_end_user_authentication: boolean;
macos_setup_assistant: string | null;
enable_release_device_manually: boolean | null;
};
macos_migration: IMacOsMigrationSettings;
windows_updates: {
Expand Down
3 changes: 2 additions & 1 deletion frontend/interfaces/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export interface ITeam extends ITeamSummary {
macos_setup: {
bootstrap_package: string | null;
enable_end_user_authentication: boolean;
macos_setup_assistant: string | null; // TODO: types?
macos_setup_assistant: string | null;
enable_release_device_manually: boolean | null;
};
windows_updates: {
deadline_days: number | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ISideNavItem } from "pages/admin/components/SideNav/SideNav";

import EndUserAuthentication from "./cards/EndUserAuthentication/EndUserAuthentication";
import BootstrapPackage from "./cards/BootstrapPackage";
import SetupAssistant from "./cards/SetupAssistant";

interface ISetupExperienceCardProps {
currentTeamId?: number;
Expand All @@ -25,6 +26,12 @@ const SETUP_EXPERIENCE_NAV_ITEMS: ISideNavItem<
path: PATHS.CONTROLS_BOOTSTRAP_PACKAGE,
Card: BootstrapPackage,
},
{
title: "Setup assistant",
urlSection: "setup-assistant",
path: PATHS.CONTROLS_SETUP_ASSITANT,
Card: SetupAssistant,
},
];

export default SETUP_EXPERIENCE_NAV_ITEMS;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
font-size: $x-small;

h2 {
font-size: $x-small; // needed to override global h2 style
margin: 0;
font-size: $small;
font-weight: normal;
}

&__preview-img {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { useState } from "react";
import { useQuery } from "react-query";
import { AxiosError } from "axios";

import { IConfig } from "interfaces/config";
import { API_NO_TEAM_ID, ITeamConfig } from "interfaces/team";
import configAPI from "services/entities/config";
import teamsAPI, { ILoadTeamResponse } from "services/entities/teams";
import mdmAPI, {
IAppleSetupEnrollmentProfileResponse,
} from "services/entities/mdm";
import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants";

import SectionHeader from "components/SectionHeader";
import Spinner from "components/Spinner";
import CustomLink from "components/CustomLink";

import SetupAssistantPreview from "./components/SetupAssistantPreview";
import SetupAssistantProfileUploader from "./components/SetupAssistantProfileUploader";
import SetuAssistantProfileCard from "./components/SetupAssistantProfileCard/SetupAssistantProfileCard";
import DeleteAutoEnrollmentProfile from "./components/DeleteAutoEnrollmentProfile";
import AdvancedOptionsForm from "./components/AdvancedOptionsForm";

const baseClass = "setup-assistant";

interface ISetupAssistantProps {
currentTeamId: number;
}

const SetupAssistant = ({ currentTeamId }: ISetupAssistantProps) => {
const [showDeleteProfileModal, setShowDeleteProfileModal] = useState(false);

const { data: globalConfig, isLoading: isLoadingGlobalConfig } = useQuery<
IConfig,
Error
>(["config", currentTeamId], () => configAPI.loadAll(), {
...DEFAULT_USE_QUERY_OPTIONS,
retry: false,
enabled: currentTeamId === API_NO_TEAM_ID,
});

const { data: teamConfig, isLoading: isLoadingTeamConfig } = useQuery<
ILoadTeamResponse,
Error,
ITeamConfig
>(["team", currentTeamId], () => teamsAPI.load(currentTeamId), {
...DEFAULT_USE_QUERY_OPTIONS,
refetchOnWindowFocus: false,
retry: false,
enabled: currentTeamId !== API_NO_TEAM_ID,
select: (res) => res.team,
});

const {
data: enrollmentProfileData,
isLoading: isLoadingEnrollmentProfile,
error: enrollmentProfileError,
refetch: refetchEnrollmentProfile,
} = useQuery<IAppleSetupEnrollmentProfileResponse, AxiosError>(
["enrollment_profile", currentTeamId],
() => mdmAPI.getSetupEnrollmentProfile(currentTeamId),
{
...DEFAULT_USE_QUERY_OPTIONS,
retry: false,
}
);

const getReleaseDeviceSetting = () => {
if (currentTeamId === API_NO_TEAM_ID) {
return (
globalConfig?.mdm.macos_setup.enable_release_device_manually || false
);
}
return teamConfig?.mdm?.macos_setup.enable_release_device_manually || false;
};

const onUpload = () => {
refetchEnrollmentProfile();
};

const onDelete = () => {
setShowDeleteProfileModal(false);
refetchEnrollmentProfile();
};

const defaultReleaseDeviceSetting = getReleaseDeviceSetting();

const isLoading =
isLoadingGlobalConfig || isLoadingTeamConfig || isLoadingEnrollmentProfile;
const enrollmentProfileNotFound = enrollmentProfileError?.status === 404;

return (
<div className={baseClass}>
<SectionHeader title="Setup assistant" />
{isLoading ? (
<Spinner />
) : (
<div className={`${baseClass}__content`}>
<div className={`${baseClass}__upload-container`}>
<p className={`${baseClass}__section-description`}>
Add an automatic enrollment profile to customize the macOS Setup
Assistant.
<CustomLink
url="https://fleetdm.com/learn-more-about/setup-assistant"
text="Learn how"
newTab
/>
</p>
{enrollmentProfileNotFound || !enrollmentProfileData ? (
<SetupAssistantProfileUploader
currentTeamId={currentTeamId}
onUpload={onUpload}
/>
) : (
<SetuAssistantProfileCard
profile={enrollmentProfileData}
onDelete={() => setShowDeleteProfileModal(true)}
/>
)}
<AdvancedOptionsForm
key={String(defaultReleaseDeviceSetting)}
currentTeamId={currentTeamId}
defaultReleaseDevice={defaultReleaseDeviceSetting}
/>
</div>
<div className={`${baseClass}__preview-container`}>
<SetupAssistantPreview />
</div>
</div>
)}
{showDeleteProfileModal && (
<DeleteAutoEnrollmentProfile
currentTeamId={currentTeamId}
onDelete={onDelete}
onCancel={() => setShowDeleteProfileModal(false)}
/>
)}
</div>
);
};

export default SetupAssistant;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.setup-assistant {
&__content {
max-width: $break-xxl;
margin: 0 auto;
display: flex;
justify-content: space-between;
gap: $pad-xxlarge;
}

&__upload-container {
display: flex;
flex-direction: column;
gap: $pad-large;
}

&__section-description {
margin: 0;
}

@media (max-width: $break-md) {
&__content {
flex-direction: column;
}
}
}
Loading
Loading