mirror of https://github.com/portainer/portainer
feat(cache): introduce cache option [EE-6293] (#10672)
Co-authored-by: testa113 <testa113>pull/10675/head
parent
57ed6ae6a6
commit
4096bb562d
@ -0,0 +1,17 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
import { ApplicationSettingsWidget } from '@/react/portainer/account/AccountView/ApplicationSettings';
|
||||
|
||||
export const accountModule = angular
|
||||
.module('portainer.app.react.components.account', [])
|
||||
.component(
|
||||
'applicationSettingsWidget',
|
||||
r2a(
|
||||
withUIRouter(withReactQuery(withCurrentUser(ApplicationSettingsWidget))),
|
||||
[]
|
||||
)
|
||||
).name;
|
@ -1,7 +1,7 @@
|
||||
import { UserId } from '../types';
|
||||
|
||||
export const queryKeys = {
|
||||
export const userQueryKeys = {
|
||||
base: () => ['users'] as const,
|
||||
user: (id: UserId) => [...queryKeys.base(), id] as const,
|
||||
me: () => [...queryKeys.base(), 'me'] as const,
|
||||
user: (id: UserId) => [...userQueryKeys.base(), id] as const,
|
||||
me: () => [...userQueryKeys.base(), 'me'] as const,
|
||||
};
|
||||
|
@ -0,0 +1,86 @@
|
||||
import { Form, Formik } from 'formik';
|
||||
|
||||
import { useCurrentUser } from '@/react/hooks/useUser';
|
||||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
import { updateAxiosAdapter } from '@/portainer/services/axios';
|
||||
import { withError } from '@/react-tools/react-query';
|
||||
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { LoadingButton } from '@@/buttons';
|
||||
import { SwitchField } from '@@/form-components/SwitchField';
|
||||
|
||||
import { useUpdateUserMutation } from '../../useUpdateUserMutation';
|
||||
|
||||
type FormValues = {
|
||||
useCache: boolean;
|
||||
};
|
||||
|
||||
export function ApplicationSettingsForm() {
|
||||
const { user } = useCurrentUser();
|
||||
const updateSettingsMutation = useUpdateUserMutation();
|
||||
|
||||
const initialValues = {
|
||||
useCache: user.UseCache,
|
||||
};
|
||||
|
||||
return (
|
||||
<Formik<FormValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
validateOnMount
|
||||
enableReinitialize
|
||||
>
|
||||
{({ isValid, dirty, values, setFieldValue }) => (
|
||||
<Form className="form-horizontal">
|
||||
<TextTip color="orange" className="mb-3">
|
||||
Enabling front-end data caching can mean that changes to Kubernetes
|
||||
clusters made by other users or outside of Portainer may take up to
|
||||
five minutes to show in your session. This caching only applies to
|
||||
Kubernetes environments.
|
||||
</TextTip>
|
||||
<SwitchField
|
||||
label="Enable front-end data caching for Kubernetes environments"
|
||||
checked={values.useCache}
|
||||
onChange={(value) => setFieldValue('useCache', value)}
|
||||
labelClass="col-lg-2 col-sm-3" // match the label width of the other fields in the page
|
||||
fieldClass="!mb-4"
|
||||
/>
|
||||
<div className="form-group">
|
||||
<div className="col-sm-12">
|
||||
<LoadingButton
|
||||
loadingText="Saving..."
|
||||
isLoading={updateSettingsMutation.isLoading}
|
||||
disabled={!isValid || !dirty}
|
||||
className="!ml-0"
|
||||
data-cy="account-applicationSettingsSaveButton"
|
||||
>
|
||||
Save
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
);
|
||||
|
||||
function handleSubmit(values: FormValues) {
|
||||
updateSettingsMutation.mutate(
|
||||
{
|
||||
Id: user.Id,
|
||||
UseCache: values.useCache,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
updateAxiosAdapter(values.useCache);
|
||||
notifySuccess(
|
||||
'Success',
|
||||
'Successfully updated application settings.'
|
||||
);
|
||||
// a full reload is required to update the angular $http cache setting
|
||||
setTimeout(() => window.location.reload(), 2000); // allow 2s to show the success notification
|
||||
},
|
||||
...withError('Unable to update application settings'),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { Settings } from 'lucide-react';
|
||||
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
|
||||
import { ApplicationSettingsForm } from './ApplicationSettingsForm';
|
||||
|
||||
export function ApplicationSettingsWidget() {
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<Widget>
|
||||
<WidgetTitle icon={Settings} title="Application settings" />
|
||||
<WidgetBody>
|
||||
<ApplicationSettingsForm />
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1 @@
|
||||
export { ApplicationSettingsWidget } from './ApplicationSettingsWidget';
|
@ -0,0 +1,32 @@
|
||||
import { useMutation } from 'react-query';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { User } from '@/portainer/users/types';
|
||||
import {
|
||||
mutationOptions,
|
||||
withInvalidate,
|
||||
queryClient,
|
||||
} from '@/react-tools/react-query';
|
||||
import { userQueryKeys } from '@/portainer/users/queries/queryKeys';
|
||||
import { useCurrentUser } from '@/react/hooks/useUser';
|
||||
|
||||
export function useUpdateUserMutation() {
|
||||
const {
|
||||
user: { Id: userId },
|
||||
} = useCurrentUser();
|
||||
|
||||
return useMutation(
|
||||
(user: Partial<User>) => updateUser(user, userId),
|
||||
mutationOptions(withInvalidate(queryClient, [userQueryKeys.base()]))
|
||||
// error notification should be handled by the caller
|
||||
);
|
||||
}
|
||||
|
||||
async function updateUser(user: Partial<User>, userId: number) {
|
||||
try {
|
||||
const { data } = await axios.put(`/users/${userId}`, user);
|
||||
return data;
|
||||
} catch (error) {
|
||||
throw parseAxiosError(error);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue