Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 4 additions & 2 deletions apps/demos/Demos/Autocomplete/Overview/React/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ const clientsStore = new CustomStore({
useDefaultSearch: true,
load: (loadOptions: LoadOptions) => {
let params = '?';
['skip', 'take', 'filter'].forEach((option: string): void => {
type LoadOptionKey = keyof LoadOptions;
const loadOptionKeys: LoadOptionKey[] = ['skip', 'take', 'filter'];
loadOptionKeys.forEach((option: LoadOptionKey): void => {
if (option in loadOptions && isNotEmpty(loadOptions[option])) {
params += `${option}=${JSON.stringify(loadOptions[option])}&`;
params += `${option as string}=${JSON.stringify(loadOptions[option])}&`;
}
});
params = params.slice(0, -1);
Expand Down
3 changes: 2 additions & 1 deletion apps/demos/Demos/Autocomplete/Overview/ReactJs/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const clientsStore = new CustomStore({
useDefaultSearch: true,
load: (loadOptions) => {
let params = '?';
['skip', 'take', 'filter'].forEach((option) => {
const loadOptionKeys = ['skip', 'take', 'filter'];
loadOptionKeys.forEach((option) => {
if (option in loadOptions && isNotEmpty(loadOptions[option])) {
params += `${option}=${JSON.stringify(loadOptions[option])}&`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function App() {
min={minDateValue}
max={maxDateValue}
defaultValue={initialValue}
disabledDates={weekendDisabled ? isDateDisabled : null}
disabledDates={weekendDisabled ? isDateDisabled : undefined}
/>
</div>
<div className="options">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function App() {
min={minDateValue}
max={maxDateValue}
defaultValue={initialValue}
disabledDates={weekendDisabled ? isDateDisabled : null}
disabledDates={weekendDisabled ? isDateDisabled : undefined}
/>
</div>
<div className="options">
Expand Down
4 changes: 2 additions & 2 deletions apps/demos/Demos/Calendar/Overview/React/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const ruleLabel = { 'aria-label': 'Week Number Rule' };

export default function App() {
const [zoomLevel, setZoomLevel] = useState<CalendarTypes.CalendarZoomLevel>('month');
const [currentValue, setCurrentValue] = useState<Date>(new Date());
const [currentValue, setCurrentValue] = useState<Date | undefined>(new Date());
const [useCellTemplate, setUseCellTemplate] = useState<boolean | null>(null);
const [disabled, setDisabled] = useState<boolean>(false);
const [showWeekNumbers, setShowWeekNumbers] = useState<boolean>(false);
Expand Down Expand Up @@ -104,7 +104,7 @@ export default function App() {
showWeekNumbers={showWeekNumbers}
disabled={disabled}
zoomLevel={zoomLevel}
cellComponent={useCellTemplate ? CustomCell : null}
cellComponent={useCellTemplate ? CustomCell : undefined}
/>
</div>
<div className="options">
Expand Down
2 changes: 1 addition & 1 deletion apps/demos/Demos/Calendar/Overview/ReactJs/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function App() {
showWeekNumbers={showWeekNumbers}
disabled={disabled}
zoomLevel={zoomLevel}
cellComponent={useCellTemplate ? CustomCell : null}
cellComponent={useCellTemplate ? CustomCell : undefined}
/>
</div>
<div className="options">
Expand Down
7 changes: 4 additions & 3 deletions apps/demos/Demos/Chat/AIAndChatbotIntegration/React/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useCallback, useState } from 'react';
import Chat, { type ChatTypes } from 'devextreme-react/chat';
import Chat from 'devextreme-react/chat';
import type { ChatTypes } from 'devextreme-react/chat';
import { loadMessages } from 'devextreme-react/common/core/localization';
import {
user,
Expand Down Expand Up @@ -42,11 +43,11 @@ export default function App() {
insertMessage({ id: Date.now(), ...message });

if (!alerts.length) {
(event.target as HTMLElement).blur();
(event?.target as HTMLElement).blur();

await processAIRequest(message);

(event.target as HTMLElement).focus();
(event?.target as HTMLElement).focus();
}
}, [insertMessage, alerts.length, processAIRequest]);

Expand Down
23 changes: 14 additions & 9 deletions apps/demos/Demos/Chat/AIAndChatbotIntegration/React/useApi.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useCallback, useState } from 'react';
import { AzureOpenAI, OpenAI } from 'openai';
import { type ChatTypes } from 'devextreme-react/chat';
import type { ChatTypes } from 'devextreme-react/chat';
import { CustomStore, DataSource } from 'devextreme-react/common/data';
import type { AIResponse } from 'devextreme/common/ai-integration';
import {
ALERT_TIMEOUT, assistant,
AzureOpenAIConfig, REGENERATION_TEXT,
ALERT_TIMEOUT,
assistant,
AzureOpenAIConfig,
REGENERATION_TEXT,
} from './data.ts';

type Message = (OpenAI.ChatCompletionUserMessageParam | OpenAI.ChatCompletionAssistantMessageParam) & {
Expand All @@ -14,11 +17,11 @@ type Message = (OpenAI.ChatCompletionUserMessageParam | OpenAI.ChatCompletionAss
const chatService = new AzureOpenAI(AzureOpenAIConfig);

const wait = (delay: number): Promise<void> =>
new Promise((resolve) => {
new Promise((resolve): void => {
setTimeout(resolve, delay);
});

export async function getAIResponse(messages: Message[], delay?: number): Promise<string> {
export async function getAIResponse(messages: Message[], delay?: number): Promise<AIResponse> {
const params = {
messages,
model: AzureOpenAIConfig.deployment,
Expand All @@ -33,7 +36,7 @@ export async function getAIResponse(messages: Message[], delay?: number): Promis
await wait(delay);
}

return data.choices[0].message?.content;
return data.choices[0].message?.content ?? '';
}

const store: ChatTypes.Message[] = [];
Expand All @@ -59,7 +62,7 @@ export const dataSource = new DataSource({
});

const dataItemToMessage = (item: ChatTypes.Message): Message => ({
role: item.author.id as Message['role'],
role: item.author?.id as Message['role'],
content: item.text,
});

Expand Down Expand Up @@ -116,9 +119,11 @@ export const useApi = () => {
try {
const aiResponse = await getAIResponse(messageHistory.slice(0, -1));

updateLastMessageContent(aiResponse);
if (typeof aiResponse === 'string') {
updateLastMessageContent(aiResponse);
}
} catch {
updateLastMessageContent(messageHistory.at(-1)?.content);
updateLastMessageContent(messageHistory.at(-1)?.content as string);
alertLimitReached();
}
}, [alertLimitReached, updateLastMessageContent]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export default function App() {
async ({ message, event }) => {
insertMessage({ id: Date.now(), ...message });
if (!alerts.length) {
event.target.blur();
(event?.target).blur();
await processAIRequest(message);
event.target.focus();
(event?.target).focus();
}
},
[insertMessage, alerts.length, processAIRequest],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export async function getAIResponse(messages, delay) {
if (delay) {
await wait(delay);
}
return data.choices[0].message?.content;
return data.choices[0].message?.content ?? '';
}
const store = [];
const customStore = new CustomStore({
Expand All @@ -46,7 +46,7 @@ export const dataSource = new DataSource({
paginate: false,
});
const dataItemToMessage = (item) => ({
role: item.author.id,
role: item.author?.id,
content: item.text,
});
const getMessageHistory = () => [...dataSource.items()].map(dataItemToMessage);
Expand Down Expand Up @@ -97,7 +97,9 @@ export const useApi = () => {
updateLastMessageContent(REGENERATION_TEXT);
try {
const aiResponse = await getAIResponse(messageHistory.slice(0, -1));
updateLastMessageContent(aiResponse);
if (typeof aiResponse === 'string') {
updateLastMessageContent(aiResponse);
}
} catch {
updateLastMessageContent(messageHistory.at(-1)?.content);
alertLimitReached();
Expand Down
26 changes: 15 additions & 11 deletions apps/demos/Demos/Chat/Customization/React/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useState, useCallback } from 'react';
import Chat, { type ChatTypes } from 'devextreme-react/chat';
import Chat from 'devextreme-react/chat';
import type { ChatTypes } from 'devextreme-react/chat';
import SelectBox from 'devextreme-react/select-box';
import CheckBox from 'devextreme-react/check-box';
import type { CheckBoxTypes } from 'devextreme-react/check-box';
import type { Format } from 'devextreme-react/common/core/localization';

import {
Expand All @@ -13,15 +15,17 @@ import {
dayHeaderLabel,
} from './data.ts';

type CheckBoxValue = CheckBoxTypes.Properties['value'];

export default function App() {
const [messages, setMessages] = useState<ChatTypes.Message[]>(initialMessages);
const [showAvatar, setShowAvatar] = useState<boolean>(true);
const [showUsername, setShowUsername] = useState<boolean>(true);
const [showDayHeaders, setDayHeaders] = useState<boolean>(true);
const [showAvatar, setShowAvatar] = useState<CheckBoxValue>(true);
const [showUsername, setShowUsername] = useState<CheckBoxValue>(true);
const [showDayHeaders, setDayHeaders] = useState<CheckBoxValue>(true);
const [dayHeaderFormat, setDayHeaderFormat] = useState<Format>(headerFormats[0]);
const [showMessageTimestamp, setMessageTimestamp] = useState<boolean>(true);
const [showMessageTimestamp, setMessageTimestamp] = useState<CheckBoxValue>(true);
const [messageTimestampFormat, setMessageTimestampFormat] = useState<Format>(messageTimestamps[0]);
const [isDisabled, setDisabled] = useState<boolean>(false);
const [isDisabled, setDisabled] = useState<CheckBoxTypes.Properties['value']>(false);

const onMessageEntered = useCallback(({ message }: ChatTypes.MessageEnteredEvent): void => {
setMessages((prevMessages) => [...prevMessages, message]);
Expand All @@ -34,11 +38,11 @@ export default function App() {
height={710}
items={messages}
user={currentUser}
disabled={isDisabled}
showAvatar={showAvatar}
showUserName={showUsername}
showDayHeaders={showDayHeaders}
showMessageTimestamp={showMessageTimestamp}
disabled={!!isDisabled}
showAvatar={!!showAvatar}
showUserName={!!showUsername}
showDayHeaders={!!showDayHeaders}
showMessageTimestamp={!!showMessageTimestamp}
dayHeaderFormat={dayHeaderFormat}
messageTimestampFormat={messageTimestampFormat}
onMessageEntered={onMessageEntered}
Expand Down
10 changes: 5 additions & 5 deletions apps/demos/Demos/Chat/Customization/ReactJs/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export default function App() {
height={710}
items={messages}
user={currentUser}
disabled={isDisabled}
showAvatar={showAvatar}
showUserName={showUsername}
showDayHeaders={showDayHeaders}
showMessageTimestamp={showMessageTimestamp}
disabled={!!isDisabled}
showAvatar={!!showAvatar}
showUserName={!!showUsername}
showDayHeaders={!!showDayHeaders}
showMessageTimestamp={!!showMessageTimestamp}
dayHeaderFormat={dayHeaderFormat}
messageTimestampFormat={messageTimestampFormat}
onMessageEntered={onMessageEntered}
Expand Down
14 changes: 8 additions & 6 deletions apps/demos/Demos/Chat/MessageEditing/React/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ import {
const editingStrategy = {
enabled: true,
disabled: false,
custom: ({ component, message }: { component: ReturnType<ChatRef['instance']>, message: ChatTypes.Message }): boolean => {
const { items, user } = component.option();
custom: ({ component, message }: { component?: ReturnType<ChatRef['instance']>, message?: ChatTypes.Message }): boolean => {
const { items, user } = component?.option() ?? {};
const userId = user?.id;

const lastNotDeletedMessage = items?.findLast((item: ChatTypes.Message): boolean => item.author?.id === userId && !item.isDeleted);

return message.id === lastNotDeletedMessage?.id;
return message?.id === lastNotDeletedMessage?.id;
},
};
} as const;

type EditingStrategyKey = keyof typeof editingStrategy;

const store: ChatTypes.Message[] = [...initialMessages];

Expand Down Expand Up @@ -85,12 +87,12 @@ export default function App() {
}, []);

const handleAllowUpdatingChange = useCallback((e: SelectBoxTypes.ValueChangedEvent): void => {
const strategy = editingStrategy[e.value];
const strategy = editingStrategy[e.value as EditingStrategyKey];
setAllowUpdating(() => strategy);
}, []);

const handleAllowDeletingChange = useCallback((e: SelectBoxTypes.ValueChangedEvent): void => {
const strategy = editingStrategy[e.value];
const strategy = editingStrategy[e.value as EditingStrategyKey];
setAllowDeleting(() => strategy);
}, []);

Expand Down
4 changes: 2 additions & 2 deletions apps/demos/Demos/Chat/MessageEditing/ReactJs/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ const editingStrategy = {
enabled: true,
disabled: false,
custom: ({ component, message }) => {
const { items, user } = component.option();
const { items, user } = component?.option() ?? {};
const userId = user?.id;
const lastNotDeletedMessage = items?.findLast(
(item) => item.author?.id === userId && !item.isDeleted,
);
return message.id === lastNotDeletedMessage?.id;
return message?.id === lastNotDeletedMessage?.id;
},
};
const store = [...initialMessages];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function App() {

return (
<div>
<div className={rtlEnabled ? 'dx-rtl' : null}>
<div className={rtlEnabled ? 'dx-rtl' : undefined}>
<div className="options">
<div className="caption">Options</div>
<div className="dx-fieldset">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function App() {
}, []);
return (
<div>
<div className={rtlEnabled ? 'dx-rtl' : null}>
<div className={rtlEnabled ? 'dx-rtl' : undefined}>
<div className="options">
<div className="caption">Options</div>
<div className="dx-fieldset">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ export default function App() {
const changeFavoriteState = useCallback(() => {
const updatedHouses = [...houses];
const updatedCurrentHouse = updatedHouses.find((house: HouseType): boolean => house === currentHouse);
updatedCurrentHouse.Favorite = !updatedCurrentHouse.Favorite;
if (updatedCurrentHouse) {
updatedCurrentHouse.Favorite = !updatedCurrentHouse.Favorite;
}
setHouses(updatedHouses);

notify({
message: `This item has been ${updatedCurrentHouse.Favorite ? 'added to' : 'removed from'} the Favorites list!`,
message: `This item has been ${updatedCurrentHouse?.Favorite ? 'added to' : 'removed from'} the Favorites list!`,
width: 450,
},
updatedCurrentHouse.Favorite ? 'success' : 'error',
updatedCurrentHouse?.Favorite ? 'success' : 'error',
2000);
}, [houses, currentHouse]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ export default function App() {
const changeFavoriteState = useCallback(() => {
const updatedHouses = [...houses];
const updatedCurrentHouse = updatedHouses.find((house) => house === currentHouse);
updatedCurrentHouse.Favorite = !updatedCurrentHouse.Favorite;
if (updatedCurrentHouse) {
updatedCurrentHouse.Favorite = !updatedCurrentHouse.Favorite;
}
setHouses(updatedHouses);
notify(
{
message: `This item has been ${
updatedCurrentHouse.Favorite ? 'added to' : 'removed from'
updatedCurrentHouse?.Favorite ? 'added to' : 'removed from'
} the Favorites list!`,
width: 450,
},
updatedCurrentHouse.Favorite ? 'success' : 'error',
updatedCurrentHouse?.Favorite ? 'success' : 'error',
2000,
);
}, [houses, currentHouse]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function App() {
treeView.unselectAll();
} else {
const values = e.value || treeBoxValue;
values?.forEach((value): void => {
values?.forEach((value: string): void => {
treeView.selectItem(value);
});
}
Expand Down
Loading