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 src/locales/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ export default {
access: 'Access',
answers: 'Answers',
answer: 'Answer',
webinars: "Webinars",
webinars: 'Webinars',
screensaves: 'Screen saves',
'webinars.screenSaves': 'Screen saves',
'menu.Webinars': 'Webinars',
'menu.NewWebinar': 'New webinar',
Expand Down Expand Up @@ -401,7 +402,8 @@ export default {
description_tooltip:
'The editor is WYSIWYG and includes formatting tools whilst retaining the ability to write markdown shortcuts inline and output plain Markdown.',
ai_analysis_enable_label: 'AI Recording Analysis',
ai_analysis_enable_tooltip: 'Check this option to enable AI-powered analysis of user attention and satisfaction during the meeting',
ai_analysis_enable_tooltip:
'Check this option to enable AI-powered analysis of user attention and satisfaction during the meeting',
attributes: 'Attributes',
new_course: 'New course',
new_questionnaire: 'New Questionnaire',
Expand Down
3 changes: 2 additions & 1 deletion src/locales/fr-FR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ export default {
'The editor is WYSIWYG and includes formatting tools whilst retaining the ability to write markdown shortcuts inline and output plain Markdown.',
short_description: 'Short description',
ai_analysis_enable_label: 'Analyse de l’enregistrement par IA',
ai_analysis_enable_tooltip: 'Cochez cette option pour activer l’analyse de l’attention et de la satisfaction des utilisateurs pendant la réunion',
ai_analysis_enable_tooltip:
'Cochez cette option pour activer l’analyse de l’attention et de la satisfaction des utilisateurs pendant la réunion',
description: 'Description',
description_tooltip:
'The editor is WYSIWYG and includes formatting tools whilst retaining the ability to write markdown shortcuts inline and output plain Markdown.',
Expand Down
13 changes: 8 additions & 5 deletions src/locales/pl-PL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ export default {
'stationary_event.edit': 'Formularz Wydarzenia stacjonarne',
'menu.My Profile': 'Mój profil',
'menu.My Profile.My Profile': 'Mój profil',
Webinars: "Webinary",
Webinars: 'Webinary',
'webinars.screenSaves': 'Zapis Ekranu',
screensaves: 'Zapis Ekranu',
stationary_event: 'Wydarzenie stacjonarne',
'menu.reset': 'reset',
finished_at: 'Data zakończenia',
Expand Down Expand Up @@ -240,9 +241,10 @@ export default {
recording_will_be_deleted: 'Po tym czasie zostanie ono skasowane',
engagement_rating: 'Ocena zaangażowania',
ai_analysis_average: 'Średni wynik analizy AI dla całego nagrania {modelType}.',
ai_warn_video_buffer: "Video nagrania jest obecnie przetwarzane, zdjęcia podglądu nagrania na wykresie w poszczególnych przedziałach czasowych mogą być obecnie niedostępne. Spróbuj ponowanie za kilka minut.",
consultationFragment: "konsultacji",
webinarFragment: "webinaru",
ai_warn_video_buffer:
'Video nagrania jest obecnie przetwarzane, zdjęcia podglądu nagrania na wykresie w poszczególnych przedziałach czasowych mogą być obecnie niedostępne. Spróbuj ponowanie za kilka minut.',
consultationFragment: 'konsultacji',
webinarFragment: 'webinaru',
resolution: 'Rozdzielczość danych',
listeners_engagement: 'Zaangażowanie słuchaczy (%)',
detected_emotions: 'Wykryte emocje',
Expand Down Expand Up @@ -386,7 +388,8 @@ export default {
author_tutor: 'Autor / Nauczyciel',
short_description: 'Krótki opis',
ai_analysis_enable_label: 'Analiza nagrania AI',
ai_analysis_enable_tooltip: 'Zaznacz tę opcję aby włączyć analizę badania atencji oraz satystakcji użytkowników na spotkaniu',
ai_analysis_enable_tooltip:
'Zaznacz tę opcję aby włączyć analizę badania atencji oraz satystakcji użytkowników na spotkaniu',
summary: 'Podsumowanie',
summary_tooltip:
'Dany edytor WYSIWYG zawiera narzędzia do formatowania, zachowując jednocześnie możliwość pisania Markdown z klawiatury oraz wyświetlania zwykłego Markdown.',
Expand Down
13 changes: 9 additions & 4 deletions src/pages/Consultations/components/EffectivenessAnalysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
createTableOrderObject,
EMOTION_POOL,
formatPercent,
getLabelColorByValue, getRatingLabelColorByValue,
getLabelColorByValue,
getRatingLabelColorByValue,
} from '@/utils/utils';
import { Link } from '@@/exports';
import {
Expand Down Expand Up @@ -91,7 +92,13 @@ const ValueTag = React.memo(
return isNaN(num) ? '0.00' : num.toFixed(2);
}, [value, isRaw]);

const color = useMemo(() => rating ? getRatingLabelColorByValue(parseFloat(displayValue)) : getLabelColorByValue(parseFloat(displayValue)), [displayValue]);
const color = useMemo(
() =>
rating
? getRatingLabelColorByValue(parseFloat(displayValue))
: getLabelColorByValue(parseFloat(displayValue)),
[displayValue],
);

return (
<StyledValueTag $color={color}>
Expand Down Expand Up @@ -127,8 +134,6 @@ export const EffectivenessAnalysis = ({
[modelType],
);



const columns: ProColumns<RecommenderTerm>[] = useMemo(
() => [
{
Expand Down
39 changes: 23 additions & 16 deletions src/pages/Consultations/components/EffectivenessAnalysisDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import type {
} from '@/pages/Consultations/components/types';
import { getAnalyticsChartFrames, getModelAnalytics } from '@/services/escola-lms/consultations';
import {
ANALYSIS_COLORS, EmotionKey, formatRating,
getRatingLabelColorByValue
ANALYSIS_COLORS,
EmotionKey,
formatRating,
getRatingLabelColorByValue,
} from '@/utils/utils';
import { WarningOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { Card, Col, Select, Space, Typography, message } from 'antd';
import React, { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
import { FormattedMessage, Link, useParams, useSelectedRoutes } from 'umi';
import {WarningOutlined} from "@ant-design/icons";

const { Text } = Typography;

Expand Down Expand Up @@ -69,19 +71,18 @@ const SectionTitle = styled(Text)`
`;

const VideoScreenWarning = styled.div`
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
color: ${ANALYSIS_COLORS.orange};
`;

const VideoScreenWarningText = styled(Text)`
margin: 0;
color: ${ANALYSIS_COLORS.orange};
margin: 0;
color: ${ANALYSIS_COLORS.orange};
`;


const TIME_OPTIONS = [
{ value: 15, label: <FormattedMessage id="time.seconds" values={{ value: 15 }} /> },
{ value: 30, label: <FormattedMessage id="time.seconds" values={{ value: 30 }} /> },
Expand Down Expand Up @@ -207,12 +208,18 @@ const EffectivenessAnalysisDetails = () => {
<FormattedMessage id="engagement_rating" />
</SectionTitle>
<Space size="large">
<RatingValue color={ratingColor}>{formatRating(analysisMeta?.rating || 0)}</RatingValue>
<RatingValue color={ratingColor}>
{formatRating(analysisMeta?.rating || 0)}
</RatingValue>
<RatingDescription type="secondary">
<FormattedMessage
id="ai_analysis_average"
values={{
modelType: <FormattedMessage id={modelType === 'webinar' ? "webinarFragment" : "consultationFragment"}/>,
modelType: (
<FormattedMessage
id={modelType === 'webinar' ? 'webinarFragment' : 'consultationFragment'}
/>
),
}}
/>
</RatingDescription>
Expand All @@ -233,10 +240,10 @@ const EffectivenessAnalysisDetails = () => {
</ControlsRow>
{analysisMeta?.processing_video && (
<VideoScreenWarning>
<WarningOutlined/>
<WarningOutlined />
<VideoScreenWarningText>
<FormattedMessage id="ai_warn_video_buffer"/>
</VideoScreenWarningText>
<FormattedMessage id="ai_warn_video_buffer" />
</VideoScreenWarningText>
</VideoScreenWarning>
)}
{chartData && (
Expand Down
65 changes: 27 additions & 38 deletions src/pages/Consultations/components/ScreenSaves.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FormattedMessage, useIntl } from 'umi';

import FilesBrowser from '@/components/FilesBrowser';
import { sortArrayByKey } from '@/utils/utils';
import type { SortAccessors } from '@/utils/utils';
import { applySort } from '@/utils/utils';

const statusMap = {
reported: 'warning',
Expand All @@ -29,6 +30,24 @@ const ScreenSaves: React.FC<Props> = ({ consultation, webinar, webinarTimestamp
const intl = useIntl();
const resourceId = consultation || webinar;

const consultationSorters: SortAccessors<API.ConsultationAppointment> = useMemo(
() => ({
consultation_term_id: (i) => i.consultation_term_id ?? 0,
user: (i) => `${i.user?.first_name ?? ''} ${i.user?.last_name ?? ''}`.toLowerCase(),
date: (i) => new Date(i.date).getTime(),
status: (i) => i.status ?? '',
}),
[],
);

const webinarSorters: SortAccessors<API.UserItem> = useMemo(
() => ({
id: (i) => i.id ?? 0,
user: (i) => `${i.first_name ?? ''} ${i.last_name ?? ''}`.toLowerCase(),
}),
[],
);

const consultationColumns = useMemo(
(): ProColumns<API.ConsultationAppointment>[] => [
{
Expand Down Expand Up @@ -93,16 +112,13 @@ const ScreenSaves: React.FC<Props> = ({ consultation, webinar, webinarTimestamp
title: <FormattedMessage id="user" defaultMessage="user" />,
dataIndex: 'user',
sorter: true,
render: (_, item) =>
`${item.first_name ?? ''} ${item.last_name ?? ''} ${item.email ?? ''}`,
render: (_, item) => `${item.first_name ?? ''} ${item.last_name ?? ''} ${item.email ?? ''}`,
},
{
title: <FormattedMessage id="active_to" />,
dataIndex: 'active_to',
render: () =>
webinarTimestamp
? moment.unix(webinarTimestamp).format('YYYY-MM-DD HH:mm')
: '-',
webinarTimestamp ? moment.unix(webinarTimestamp).format('YYYY-MM-DD HH:mm') : '-',
},
{
title: 'Analiza obrazu',
Expand Down Expand Up @@ -164,23 +180,10 @@ const ScreenSaves: React.FC<Props> = ({ consultation, webinar, webinarTimestamp
options={{
reload: false,
}}
dataSource={appointments}
request={async (_params, sort) => {
const sortArr = sort && Object.entries(sort)[0];
let filteredData = appointments.filter((item) => item.status === 'approved');

if (sortArr) {
filteredData = sortArrayByKey<API.ConsultationAppointment>(
filteredData,
sortArr[0],
sortArr[1] !== 'ascend',
);
}
return {
data: filteredData,
total: filteredData.length,
success: true,
};
const filtered = appointments.filter((item) => item.status === 'approved');
const data = applySort(filtered, sort as any, consultationSorters);
return { data, total: data.length, success: true };
}}
columns={consultationColumns}
/>
Expand All @@ -200,23 +203,9 @@ const ScreenSaves: React.FC<Props> = ({ consultation, webinar, webinarTimestamp
options={{
reload: false,
}}
dataSource={webinarUsers}
request={async (_params, sort) => {
const sortArr = sort && Object.entries(sort)[0];
let filteredData = [...webinarUsers];

if (sortArr) {
filteredData = sortArrayByKey<API.UserItem>(
filteredData,
sortArr[0],
sortArr[1] !== 'ascend',
);
}
return {
data: filteredData,
total: filteredData.length,
success: true,
};
const data = applySort(webinarUsers, sort as any, webinarSorters);
return { data, total: data.length, success: true };
}}
columns={webinarColumns}
/>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/Consultations/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import ProCard from '@ant-design/pro-card';
import ProForm, {
ProFormDatePicker,
ProFormDigit,
ProFormSelect, ProFormSwitch,
ProFormSelect,
ProFormSwitch,
ProFormText,
} from '@ant-design/pro-form';
import { Alert, Button, Col, Row, Spin } from 'antd';
Expand Down
19 changes: 11 additions & 8 deletions src/pages/Webinars/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ import UserSelect from '@/components/UserSelect';
import UserSubmissions from '@/components/UsersSubmissions';
import WysiwygMarkdown from '@/components/WysiwygMarkdown';
import useValidateFormEdit from '@/hooks/useValidateFormEdit';
import ScreenSaves from '@/pages/Consultations/components/ScreenSaves';
import { settings } from '@/services/escola-lms/settings';
import { createWebinar, getWebinar, updateWebinar } from '@/services/escola-lms/webinars';
import { splitImagePath, tagsArrToIds } from '@/utils/utils';
import ProCard from '@ant-design/pro-card';
import ProForm, {
ProFormDateTimePicker,
ProFormSelect, ProFormSwitch,
ProFormSelect,
ProFormSwitch,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-form';
import { PageContainer } from '@ant-design/pro-layout';
import { Alert, Button, Col, Row, Spin, message } from 'antd';
import moment from 'moment';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { FormattedMessage, history, useIntl, useParams } from 'umi';
import ScreenSaves from "@/pages/Consultations/components/ScreenSaves";
import {settings} from "@/services/escola-lms/settings";
import moment from "moment";

enum TabNames {
ATTRIBUTES = 'attributes',
Expand Down Expand Up @@ -159,9 +160,7 @@ const WebinarForm = () => {
},
{
path: '/',
breadcrumbName: intl.formatMessage({
id: String(data.name),
}),
breadcrumbName: String(data.name),
},
{
path: String(tab),
Expand Down Expand Up @@ -189,6 +188,7 @@ const WebinarForm = () => {
},
}}
>

<ProCard.TabPane key={TabNames.ATTRIBUTES} tab={<FormattedMessage id="attributes" />}>
{manageCourseEdit.disableEdit && (
<Alert
Expand Down Expand Up @@ -459,7 +459,10 @@ const WebinarForm = () => {
key={TabNames.SCREENSAVES}
tab={<FormattedMessage id="webinars.screenSaves" />}
>
<ScreenSaves webinar={Number(webinar)} webinarTimestamp={moment(data.active_to).unix()}/>
<ScreenSaves
webinar={Number(webinar)}
webinarTimestamp={moment(data.active_to).unix()}
/>
</ProCard.TabPane>
)}
</ProCard>
Expand Down
16 changes: 5 additions & 11 deletions src/services/escola-lms/webinars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,9 @@ export async function generateYoutubeToken(body?: { email: string }, options?: A
}

/** GET /api/admin/webinars/:webinarId/users */
export async function getWebinarUsers(
webinarId: number,
options?: AxiosRequestConfig,
) {
return request<API.DefaultResponse<API.UserItem[]>>(
`/api/admin/webinars/${webinarId}/users`,
{
method: 'GET',
...(options || {}),
},
);
export async function getWebinarUsers(webinarId: number, options?: AxiosRequestConfig) {
return request<API.DefaultResponse<API.UserItem[]>>(`/api/admin/webinars/${webinarId}/users`, {
method: 'GET',
...(options || {}),
});
}
Loading
Loading