Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c7bc444
updates copy button
hannahbergam Apr 13, 2026
4eb4c52
pr feedback
hannahbergam Apr 13, 2026
dfe1e26
Merge remote-tracking branch 'origin/levelbuilder' into dts_candidate…
deploy-code-org Apr 14, 2026
d44c9e0
Merge pull request #72115 from code-dot-org/dts_candidate_2026-04-14
deploy-code-org Apr 14, 2026
2d4dddb
Merge pull request #72116 from code-dot-org/staging
deploy-code-org Apr 14, 2026
0b4c0ff
[Pt.1] Replace primitive colors with semantic tokens in component-lib…
levadadenys Apr 14, 2026
b8ae2ce
Ceara/aitt aidiff expand general context no sections (#72095)
cearachew Apr 14, 2026
ae98f3f
Ceara/test claude45 (#71526)
cearachew Apr 14, 2026
398a355
Merge pull request #72122 from code-dot-org/staging
deploy-code-org Apr 14, 2026
8d263e5
Productionize grades-in-sign-up behind DCDO flag (#72042)
bethanyaconnor Apr 14, 2026
e249a9d
Merge pull request #72124 from code-dot-org/staging
deploy-code-org Apr 14, 2026
7dce17b
pr feedback
hannahbergam Apr 14, 2026
5dc3f6a
Merge pull request #72107 from code-dot-org/hbergam/teacher-copy-chat
hannahbergam Apr 14, 2026
6da5a33
Merge pull request #72129 from code-dot-org/staging
deploy-code-org Apr 14, 2026
efef011
Add development AWS secret for Azure AI Image moderation key (#72127)
edcodedotorg Apr 14, 2026
2fa6585
Merge pull request #72133 from code-dot-org/staging
deploy-code-org Apr 14, 2026
8e98f0a
Reduce Drone Unit Test Parallelization (#72134)
Hamms Apr 14, 2026
cdfc594
[Design2-342] Pt.8 Deprecate DSCO Button in component-library, replac…
levadadenys Apr 14, 2026
862b86d
Further Fine-tune Drone Unit Test Parallelization (#72138)
Hamms Apr 14, 2026
1f90621
Merge pull request #72139 from code-dot-org/staging
deploy-code-org Apr 14, 2026
b129181
Lab2: add intro flows menu (#72101)
molly-moen Apr 14, 2026
4c5bff1
Merge pull request #72143 from code-dot-org/staging
deploy-code-org Apr 14, 2026
b605ae2
Merge commit '4c5bff10' into dtl_candidate_4c5bff10
deploy-code-org Apr 15, 2026
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
3 changes: 3 additions & 0 deletions apps/src/Globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ declare module '*.module.scss' {
export default classes;
}

// Type definition for plain SCSS files imported in TypeScript files
declare module '*.scss';

// Declaring dashboard as 'any' because it is not well documented.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const dashboard: any;
Expand Down
16 changes: 11 additions & 5 deletions apps/src/aiDifferentiation/AiDiffChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,19 @@ const AiDiffChatHeader: React.FC<AiDiffChatHeaderProps> = ({
<div className={style.chatHeaderButtons}>
<ActionDropdown
size="s"
useIconButton={false}
triggerButtonProps={{
size: 's',
color: 'gray',
type: 'secondary',
text: commonI18n.aiDifferentiation_suggest_prompt(),
size: 'small',
color: 'tertiary',
variant: 'outlined',
children: commonI18n.aiDifferentiation_suggest_prompt(),
'aria-label': commonI18n.aiDifferentiation_suggest_prompt(),
iconLeft: {iconName: 'solid-pen-sparkle', iconFamily: 'kit'},
startIcon: (
<FontAwesomeV6Icon
iconName="solid-pen-sparkle"
iconFamily="kit"
/>
),
}}
labelText={commonI18n.aiDifferentiation_suggest_prompt()}
name="aiDiffChatHeaderDropdown"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
import React from 'react';
import {useSelector} from 'react-redux';

import {selectAllVisibleMessages, sendAnalytics} from '@cdo/apps/aichat/redux';
import IconButtonWithTooltip from '@cdo/apps/lab2/views/components/IconButtonWithTooltip';
import {EVENTS} from '@cdo/apps/metrics/AnalyticsConstants';
import copyToClipboard from '@cdo/apps/util/copyToClipboard';
import {useAppDispatch} from '@cdo/apps/util/reduxHooks';
import {useAppDispatch, useAppSelector} from '@cdo/apps/util/reduxHooks';
import {AiInteractionStatus as Status} from '@cdo/generated-scripts/sharedConstants';

import {timestampToDateTime} from '../../redux/utils';
import {
ChatEvent,
ChatEventDescriptionKey,
isChatMessage,
isModelUpdate,
isNotification,
isUserActionEvent,
WorkspaceTeacherViewTab,
} from '../../types';
import {AI_CUSTOMIZATIONS_LABELS} from '../modelCustomization/constants';

const CopyChatHistoryButton: React.FunctionComponent = () => {
const messages = useSelector(selectAllVisibleMessages);
const visibleMessages = useAppSelector(selectAllVisibleMessages);
const studentChatHistory = useAppSelector(
state => state.aichat.studentChatHistory
);
const selectedTab = useAppSelector(
state => state.aichat.chatWorkspaceSelectedTab
);
const isViewingStudentHistory =
selectedTab === WorkspaceTeacherViewTab.STUDENT_CHAT_HISTORY;
const messages = isViewingStudentHistory
? studentChatHistory
: visibleMessages;
const dispatch = useAppDispatch();

const handleCopy = () => {
Expand Down Expand Up @@ -72,6 +85,16 @@ function chatEventToFormattedString(chatEvent: ChatEvent) {
if (isNotification(chatEvent)) {
return `[${formattedTimestamp} - Notification] ${chatEvent.text}`;
}

if (isUserActionEvent(chatEvent)) {
const descriptions: {[key in ChatEventDescriptionKey]: string} = {
CLEAR_CHAT: 'The user cleared the chat workspace.',
LOAD_LEVEL: 'The user loaded the level.',
};
return `[${formattedTimestamp} - User Action] ${
descriptions[chatEvent.descriptionKey]
}`;
}
}

export default CopyChatHistoryButton;
74 changes: 31 additions & 43 deletions apps/src/aichat/views/assets/UploadButton.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {ActionDropdown} from '@code-dot-org/component-library/dropdown';
import FontAwesomeV6Icon from '@code-dot-org/component-library/fontAwesomeV6Icon';
import {
Button as MuiButton,
ButtonProps as MuiButtonProps,
} from '@mui/material';
import {Button as MuiButton, IconButton as MuiIconButton} from '@mui/material';
import React, {ChangeEvent, useState} from 'react';

import StarterAssetsDialog from '@cdo/apps/lab2/views/components/starterAssetsDialog';
Expand Down Expand Up @@ -91,56 +88,33 @@ const UploadButton: React.FC<UploadButtonProps> = ({
);
};

// TODO: Set of legacy DSCO props, remove once Dropdowns are moved to MUI.
const DSCO_buttonPropsCommon = {
type: 'secondary' as const,
color: 'gray' as const,
const buttonPropsCommon = {
variant: 'outlined' as const,
color: 'tertiary' as const,
};

const DSCO_buttonPropsWithLabel = {
...DSCO_buttonPropsCommon,
text: 'Add file',
iconLeft: {iconName: 'plus'},
};

const DSCO_buttonPropsIconOnly = {
...DSCO_buttonPropsCommon,
icon: {iconName: 'plus', iconStyle: 'solid' as const},
};

const DSCO_commonProps = {
size: 'xs',
disabled: numStagedFiles >= MAX_NUM_FILES || isDisabled,
} as const;

const buttonPropsCommon: MuiButtonProps = {
variant: 'outlined',
color: 'secondary',
};

const buttonPropsWithLabel: MuiButtonProps = {
const buttonPropsWithLabel = {
...buttonPropsCommon,
children: 'Add file',
startIcon: <FontAwesomeV6Icon iconName="plus" iconStyle="solid" />,
};

const buttonPropsIconOnly: MuiButtonProps = {
const buttonPropsIconOnly = {
...buttonPropsCommon,
startIcon: <FontAwesomeV6Icon iconName="plus" iconStyle="solid" />,
children: <FontAwesomeV6Icon iconName="plus" iconStyle="solid" />,
};

const commonProps = {
size: 'extraSmall',
disabled: numStagedFiles >= MAX_NUM_FILES || isDisabled,
} as const;
const isButtonDisabled = numStagedFiles >= MAX_NUM_FILES || isDisabled;

const uploadButton = hasStarterAssets ? (
<ActionDropdown
{...DSCO_commonProps}
size="xs"
disabled={isButtonDisabled}
name="uploadDropdown"
labelText={'Upload'}
useIconButton={!showLabel}
triggerButtonProps={
showLabel ? DSCO_buttonPropsWithLabel : DSCO_buttonPropsIconOnly
showLabel ? buttonPropsWithLabel : buttonPropsIconOnly
}
menuVerticalPlacement="top"
options={[
Expand All @@ -165,13 +139,27 @@ const UploadButton: React.FC<UploadButtonProps> = ({
},
]}
/>
) : (
) : showLabel ? (
<MuiButton
type="button"
{...(showLabel ? buttonPropsWithLabel : buttonPropsIconOnly)}
{...commonProps}
variant={buttonPropsCommon.variant}
color={buttonPropsCommon.color}
size="extraSmall"
disabled={isButtonDisabled}
onClick={onDeviceUploadClick}
/>
startIcon={<FontAwesomeV6Icon iconName="plus" iconStyle="solid" />}
>
Add file
</MuiButton>
) : (
<MuiIconButton
variant={buttonPropsCommon.variant}
color={buttonPropsCommon.color}
size="extraSmall"
disabled={isButtonDisabled}
onClick={onDeviceUploadClick}
>
<FontAwesomeV6Icon iconName="plus" iconStyle="solid" />
</MuiIconButton>
);

return (
Expand Down
11 changes: 3 additions & 8 deletions apps/src/aichat/views/modelCustomization/SetupCustomization.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import SimpleDropdown from '@code-dot-org/component-library/dropdown/simpleDropdown';
import FontAwesomeV6Icon from '@code-dot-org/component-library/fontAwesomeV6Icon';
import Slider, {SliderProps} from '@code-dot-org/component-library/slider';
import {Button as MuiButton} from '@mui/material';
import classNames from 'classnames';
Expand Down Expand Up @@ -153,17 +154,11 @@ const SetupCustomization: React.FunctionComponent = () => {
},
className: styles.temperatureSlider,
leftButtonProps: {
icon: {
iconName: 'minus',
title: 'Decrease',
},
children: <FontAwesomeV6Icon iconName="minus" title="Decrease" />,
['aria-label']: 'Decrease',
},
rightButtonProps: {
icon: {
iconName: 'plus',
title: 'Increase',
},
children: <FontAwesomeV6Icon iconName="plus" title="Increase" />,
['aria-label']: 'Increase',
},
};
Expand Down
2 changes: 1 addition & 1 deletion apps/src/code-studio/components/ShareAllowedDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class ShareAllowedDialog extends React.Component {
}
primaryButtonProps={{
onClick: this.close,
text: i18n.ok(),
children: i18n.ok(),
id: 'uitest-sharing-disabled-button',
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,12 @@ export default class LandingPageWorkshopsTable extends React.Component {
description="Are you sure you want to cancel your enrollment in this course?"
primaryButtonProps={{
onClick: this.cancelEnrollment,
text: 'Yes - cancel my enrollment',
color: 'destructive',
children: 'Yes - cancel my enrollment',
color: 'error',
}}
secondaryButtonProps={{
onClick: this.dismissCancelModal,
text: 'No - stay enrolled in this class',
children: 'No - stay enrolled in this class',
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export default function RegionalWorkshopCatalog({
title={regionalPartnerName}
description={regionalPartnerInfo}
primaryButtonProps={{
text: 'Return to workshops',
children: 'Return to workshops',
onClick: () => setShowRPInfoDialog(false),
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,13 @@ export const WorkshopForm: FC<WorkshopFormProps> = ({config}) => {
description="You're making an important update to your workshop, would you like your enrollees to be notified via email?"
mode="light"
primaryButtonProps={{
text: 'Notify',
isPending: loadingState === 'notifyLoading',
children: 'Notify',
loading: loadingState === 'notifyLoading',
onClick: () => publish(true),
}}
secondaryButtonProps={{
text: "Don't notify",
isPending: loadingState === 'dontNotifyLoading',
children: "Don't notify",
loading: loadingState === 'dontNotifyLoading',
onClick: () => publish(false),
}}
onClose={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,16 +438,16 @@ export const WorkshopEnrollments: FC = () => {
</Box>
}
primaryButtonProps={{
text: `Remove enrollment${s}`,
size: 's',
children: `Remove enrollment${s}`,
size: 'small',
onClick: handleRemoveEnrollments,
color: 'destructive',
color: 'error',
}}
secondaryButtonProps={{
size: 's',
text: 'Cancel',
type: 'secondary',
color: 'gray',
size: 'small',
children: 'Cancel',
color: 'tertiary',
variant: 'outlined',
onClick: () => {
setActiveDialog(null);
setRemoveEnrollmentError('');
Expand Down Expand Up @@ -501,16 +501,16 @@ export const WorkshopEnrollments: FC = () => {
</Box>
}
primaryButtonProps={{
text: `Move enrollment${s}`,
size: 's',
children: `Move enrollment${s}`,
size: 'small',
onClick: handleMoveEnrollments,
disabled: !moveToWorkshopId,
}}
secondaryButtonProps={{
size: 's',
text: 'Cancel',
type: 'secondary',
color: 'gray',
size: 'small',
children: 'Cancel',
color: 'tertiary',
variant: 'outlined',
onClick: () => {
setActiveDialog(null);
setMoveToWorkshopId('');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const dialogs = [
description:
'Ending this workshop will close the attendance. Are you sure you want to end this workshop now?',
primaryButtonProps: {
color: 'destructive' as const,
color: 'error' as const,
},
},
{
Expand Down Expand Up @@ -351,17 +351,17 @@ export const WorkshopStatusSection: React.FC<WorkshopStatusSectionProps> = ({
title={`${label} Workshop?`}
description={description}
primaryButtonProps={{
text: `${label} Workshop`,
size: 's',
children: `${label} Workshop`,
size: 'small',
disabled: isUpdating,
onClick: generateHandler(stateKey),
...primaryButtonProps,
}}
secondaryButtonProps={{
size: 's',
text: 'Cancel',
type: 'secondary',
color: 'gray',
size: 'small',
children: 'Cancel',
color: 'tertiary',
variant: 'outlined',
onClick: () => setActiveDialog(null),
disabled: isUpdating,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ const CancelWorkshopEnrollmentButton: React.FC<
description="Are you sure you want to cancel your registration?"
primaryButtonProps={{
onClick: handleCancel,
text: 'Yes, cancel registration',
color: 'destructive',
children: 'Yes, cancel registration',
color: 'error',
}}
secondaryButtonProps={{
onClick: () => setShowConfirmation(false),
text: 'No, keep registration',
children: 'No, keep registration',
}}
onClose={() => setShowConfirmation(false)}
/>
Expand Down
Loading