Skip to content

Commit 5d07911

Browse files
[ui-adminpage] Port usage analytics endpoints to public (#4126)
1 parent cedbf39 commit 5d07911

File tree

3 files changed

+308
-90
lines changed

3 files changed

+308
-90
lines changed

desktop/core/src/desktop/js/apps/admin/Components/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
export const SERVER_LOGS_API_URL = '/api/v1/logs';
1818
export const CHECK_CONFIG_EXAMPLES_API_URL = '/api/v1/check_config';
19-
export const ANALYTICS_PREFERENCES_API_URL = '/about/update_preferences';
2019
export const INSTALL_APP_EXAMPLES_API_URL = '/api/v1/install_app_examples';
2120
export const INSTALL_AVAILABLE_EXAMPLES_API_URL = '/api/v1/available_app_examples';
2221
export const HUE_DOCS_CONFIG_URL = 'https://docs.gethue.com/administrator/configuration/';
22+
export const USAGE_ANALYTICS_API_URL = '/api/v1/usage_analytics';

desktop/core/src/desktop/js/apps/admin/Overview/Analytics.tsx

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,63 +14,81 @@
1414
// See the License for the specific language governing permissions and
1515
// limitations under the License.
1616

17-
import React, { useState } from 'react';
17+
import React from 'react';
1818
import huePubSub from '../../../utils/huePubSub';
1919
import { i18nReact } from '../../../utils/i18nReact';
2020
import Input from 'cuix/dist/components/Input';
21-
import { post } from '../../../api/utils';
22-
import { ANALYTICS_PREFERENCES_API_URL } from '../Components/utils';
21+
import { USAGE_ANALYTICS_API_URL } from '../Components/utils';
22+
import { HueAlert } from '../../../reactComponents/GlobalAlert/types';
23+
import { GLOBAL_INFO_TOPIC } from '../../../reactComponents/GlobalAlert/events';
24+
import useLoadData from '../../../utils/hooks/useLoadData/useLoadData';
25+
import useSaveData from '../../../utils/hooks/useSaveData/useSaveData';
26+
import LoadingErrorWrapper from '../../../reactComponents/LoadingErrorWrapper/LoadingErrorWrapper';
27+
import { HttpMethod } from '../../../api/utils';
2328
import './Overview.scss';
2429

25-
interface UpdatePreferences {
26-
status: number;
27-
message?: string;
30+
interface UsageAnalyticsResponse {
31+
collectUsage?: boolean;
2832
}
2933

3034
const Analytics = (): JSX.Element => {
31-
const [collectUsage, setCollectUsage] = useState<boolean>(false);
3235
const { t } = i18nReact.useTranslation();
36+
const {
37+
data: usageAnalyticsData,
38+
loading: loadingAnalytics,
39+
error: usageAnalyticsError,
40+
reloadData
41+
} = useLoadData<UsageAnalyticsResponse>(USAGE_ANALYTICS_API_URL);
3342

34-
const saveCollectUsagePreference = async (collectUsage: boolean) => {
35-
const response = await post<UpdatePreferences>(ANALYTICS_PREFERENCES_API_URL, {
36-
collect_usage: collectUsage
37-
});
38-
39-
if (response.status === 0) {
40-
const successMessage = collectUsage
43+
const {
44+
save: updateAnalyticsPreference,
45+
loading: updatingAnalyticsPreference,
46+
error: updateAnalyticsPreferenceError
47+
} = useSaveData<{ collect_usage: boolean }>(USAGE_ANALYTICS_API_URL, {
48+
method: HttpMethod.PUT,
49+
onSuccess: response => {
50+
reloadData();
51+
const successMessage = response.collect_usage
4152
? t('Analytics have been activated.')
4253
: t('Analytics have been deactivated.');
43-
huePubSub.publish('hue.global.info', { message: successMessage });
44-
} else {
45-
const errorMessage = collectUsage
46-
? t('Failed to activate analytics.')
47-
: t('Failed to deactivate analytics.');
48-
huePubSub.publish('hue.global.error', { message: errorMessage });
54+
huePubSub.publish<HueAlert>(GLOBAL_INFO_TOPIC, { message: successMessage });
4955
}
50-
};
56+
});
57+
58+
const errors = [
59+
{
60+
enabled: !!usageAnalyticsError,
61+
message: usageAnalyticsError ?? t('An unknown error occurred while fetching data.')
62+
},
63+
{
64+
enabled: !!updateAnalyticsPreferenceError,
65+
message: updateAnalyticsPreferenceError ?? t('Failed to update analytics.')
66+
}
67+
];
5168

52-
const handleCheckboxChange = event => {
53-
const newPreference = event.target.checked;
54-
setCollectUsage(newPreference);
55-
saveCollectUsagePreference(newPreference);
69+
const handleAnalyticsCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
70+
updateAnalyticsPreference({ collect_usage: event.target.checked });
5671
};
5772

5873
return (
59-
<div className="overview-analytics">
60-
<h3>{t('Anonymous usage analytics')}</h3>
61-
<div className="analytics-checkbox-container">
62-
<Input
63-
type="checkbox"
64-
className="analytics__checkbox-icon"
65-
id="usage_analytics"
66-
checked={collectUsage}
67-
onChange={handleCheckboxChange}
68-
/>
69-
<label htmlFor="usage_analytics" className="usage__analytics">
70-
{t('Help improve Hue with anonymous usage analytics.')}
71-
</label>
74+
<LoadingErrorWrapper loading={loadingAnalytics || updatingAnalyticsPreference} errors={errors}>
75+
<div className="overview-analytics">
76+
<h3>{t('Anonymous usage analytics')}</h3>
77+
<div className="analytics-checkbox-container">
78+
<Input
79+
type="checkbox"
80+
className="analytics__checkbox-icon"
81+
id="usage_analytics"
82+
checked={!!usageAnalyticsData?.collectUsage}
83+
onChange={handleAnalyticsCheckboxChange}
84+
disabled={loadingAnalytics || updatingAnalyticsPreference}
85+
/>
86+
<label htmlFor="usage_analytics" className="usage__analytics">
87+
{t('Help improve Hue with anonymous usage analytics.')}
88+
</label>
89+
</div>
7290
</div>
73-
</div>
91+
</LoadingErrorWrapper>
7492
);
7593
};
7694

0 commit comments

Comments
 (0)