mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
feat: use api instead of localStorage (#3305)
<!-- Thanks for creating a PR! To make it easier for reviewers and everyone else to understand what your changes relate to, please add some relevant content to the headings below. Feel free to ignore or delete sections that you don't think are relevant. Thank you! ❤️ --> This PR replaces localStorage with api calls for getting/setting project scoped stickiness ## About the changes <!-- Describe the changes introduced. What are they and why are they being introduced? Feel free to also add screenshots or steps to view the changes if they're visual. --> <!-- Does it close an issue? Multiple? --> Closes # <!-- (For internal contributors): Does it relate to an issue on public roadmap? --> <!-- Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: # --> ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? --> --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
e33ebd0229
commit
933455e308
@ -19,7 +19,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import { updateWeightEdit } from 'component/common/util';
|
||||
import { StickinessSelect } from 'component/feature/StrategyTypes/FlexibleStrategy/StickinessSelect/StickinessSelect';
|
||||
import { useDefaultProjectStickiness } from 'hooks/useDefaultProjectStickiness';
|
||||
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
|
||||
|
||||
const StyledFormSubtitle = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
@ -145,7 +145,7 @@ export const EnvironmentVariantsModal = ({
|
||||
|
||||
const { uiConfig } = useUiConfig();
|
||||
const { context } = useUnleashContext();
|
||||
const { defaultStickiness } = useDefaultProjectStickiness(projectId);
|
||||
const { defaultStickiness } = useDefaultProjectSettings(projectId);
|
||||
|
||||
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
|
||||
const { data } = usePendingChangeRequests(projectId);
|
||||
|
@ -12,9 +12,9 @@ import {
|
||||
parseParameterString,
|
||||
} from 'utils/parseParameter';
|
||||
import { StickinessSelect } from './StickinessSelect/StickinessSelect';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
|
||||
import { useDefaultProjectStickiness } from '../../../../hooks/useDefaultProjectStickiness';
|
||||
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
|
||||
import Loader from '../../../common/Loader/Loader';
|
||||
|
||||
interface IFlexibleStrategyProps {
|
||||
parameters: IFeatureStrategyParameters;
|
||||
@ -29,8 +29,7 @@ const FlexibleStrategy = ({
|
||||
editable = true,
|
||||
}: IFlexibleStrategyProps) => {
|
||||
const projectId = useOptionalPathParam('projectId');
|
||||
const { defaultStickiness } = useDefaultProjectStickiness(projectId);
|
||||
|
||||
const { defaultStickiness, loading } = useDefaultProjectSettings(projectId);
|
||||
const onUpdate = (field: string) => (newValue: string) => {
|
||||
updateParameter(field, newValue);
|
||||
};
|
||||
@ -58,6 +57,10 @@ const FlexibleStrategy = ({
|
||||
onUpdate('stickiness')(stickiness);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<RolloutSlider
|
||||
|
@ -10,7 +10,6 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import useToast from 'hooks/useToast';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { GO_BACK } from 'constants/navigate';
|
||||
import { useDefaultProjectStickiness } from 'hooks/useDefaultProjectStickiness';
|
||||
|
||||
const CreateProject = () => {
|
||||
const { setToastData, setToastApiError } = useToast();
|
||||
@ -33,10 +32,8 @@ const CreateProject = () => {
|
||||
errors,
|
||||
} = useProjectForm();
|
||||
|
||||
const { createProject, loading } = useProjectApi();
|
||||
|
||||
const { setDefaultProjectStickiness } =
|
||||
useDefaultProjectStickiness(projectId);
|
||||
const { createProject, setDefaultProjectStickiness, loading } =
|
||||
useProjectApi();
|
||||
|
||||
const handleSubmit = async (e: Event) => {
|
||||
e.preventDefault();
|
||||
@ -48,7 +45,10 @@ const CreateProject = () => {
|
||||
const payload = getProjectPayload();
|
||||
try {
|
||||
await createProject(payload);
|
||||
setDefaultProjectStickiness(payload.projectStickiness);
|
||||
setDefaultProjectStickiness(
|
||||
projectId,
|
||||
payload.projectStickiness
|
||||
);
|
||||
refetchUser();
|
||||
navigate(`/projects/${projectId}`);
|
||||
setToastData({
|
||||
|
@ -14,7 +14,7 @@ import { useContext } from 'react';
|
||||
import AccessContext from 'contexts/AccessContext';
|
||||
import { Alert } from '@mui/material';
|
||||
import { GO_BACK } from 'constants/navigate';
|
||||
import { useDefaultProjectStickiness } from 'hooks/useDefaultProjectStickiness';
|
||||
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
|
||||
|
||||
const EditProject = () => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
@ -22,8 +22,8 @@ const EditProject = () => {
|
||||
const { hasAccess } = useContext(AccessContext);
|
||||
const id = useRequiredPathParam('projectId');
|
||||
const { project } = useProject(id);
|
||||
const { defaultStickiness, setDefaultProjectStickiness } =
|
||||
useDefaultProjectStickiness(id);
|
||||
const { setDefaultProjectStickiness } = useProjectApi();
|
||||
const { defaultStickiness } = useDefaultProjectSettings(id);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const {
|
||||
@ -68,7 +68,10 @@ const EditProject = () => {
|
||||
if (validName) {
|
||||
try {
|
||||
await editProject(id, payload);
|
||||
setDefaultProjectStickiness(payload.projectStickiness);
|
||||
setDefaultProjectStickiness(
|
||||
projectId,
|
||||
payload.projectStickiness
|
||||
);
|
||||
refetch();
|
||||
navigate(`/projects/${id}`);
|
||||
setToastData({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { useDefaultProjectStickiness } from 'hooks/useDefaultProjectStickiness';
|
||||
import { useDefaultProjectSettings } from 'hooks/useDefaultProjectSettings';
|
||||
|
||||
const useProjectForm = (
|
||||
initialProjectId = '',
|
||||
@ -10,7 +10,7 @@ const useProjectForm = (
|
||||
initialProjectStickiness = 'default'
|
||||
) => {
|
||||
const [projectId, setProjectId] = useState(initialProjectId);
|
||||
const { defaultStickiness } = useDefaultProjectStickiness(projectId);
|
||||
const { defaultStickiness } = useDefaultProjectSettings(projectId);
|
||||
|
||||
const [projectName, setProjectName] = useState(initialProjectName);
|
||||
const [projectDesc, setProjectDesc] = useState(initialProjectDesc);
|
||||
|
@ -202,6 +202,19 @@ const useProjectApi = () => {
|
||||
return makeRequest(req.caller, req.id);
|
||||
};
|
||||
|
||||
const setDefaultProjectStickiness = (
|
||||
projectId: string,
|
||||
stickiness: string
|
||||
) => {
|
||||
const path = `api/admin/projects/${projectId}/stickiness`;
|
||||
const req = createRequest(path, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ stickiness }),
|
||||
});
|
||||
|
||||
return makeRequest(req.caller, req.id);
|
||||
};
|
||||
|
||||
return {
|
||||
createProject,
|
||||
validateId,
|
||||
@ -217,6 +230,7 @@ const useProjectApi = () => {
|
||||
errors,
|
||||
loading,
|
||||
searchProjectUser,
|
||||
setDefaultProjectStickiness,
|
||||
};
|
||||
};
|
||||
|
||||
|
62
frontend/src/hooks/useDefaultProjectSettings.ts
Normal file
62
frontend/src/hooks/useDefaultProjectSettings.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import useUiConfig from './api/getters/useUiConfig/useUiConfig';
|
||||
import useSWR, { SWRConfiguration } from 'swr';
|
||||
import { useCallback } from 'react';
|
||||
import handleErrorResponses from './api/getters/httpErrorResponseHandler';
|
||||
|
||||
export interface IStickinessResponse {
|
||||
status: number;
|
||||
|
||||
body?: {
|
||||
defaultStickiness: string;
|
||||
mode?: string;
|
||||
};
|
||||
}
|
||||
const DEFAULT_STICKINESS = 'default';
|
||||
export const useDefaultProjectSettings = (
|
||||
projectId?: string,
|
||||
options?: SWRConfiguration
|
||||
) => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const PATH = `/api/admin/projects/${projectId}/settings`;
|
||||
const { projectScopedStickiness } = uiConfig.flags;
|
||||
|
||||
const { data, error, mutate } = useSWR<IStickinessResponse>(
|
||||
['useDefaultProjectSettings', PATH],
|
||||
() => fetcher(PATH),
|
||||
options
|
||||
);
|
||||
|
||||
const defaultStickiness =
|
||||
Boolean(projectScopedStickiness) && data?.body != null && projectId
|
||||
? data.body.defaultStickiness
|
||||
: DEFAULT_STICKINESS;
|
||||
|
||||
const refetch = useCallback(() => {
|
||||
mutate().catch(console.warn);
|
||||
}, [mutate]);
|
||||
return {
|
||||
defaultStickiness,
|
||||
refetch,
|
||||
loading: !error && !data,
|
||||
status: data?.status,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetcher = async (path: string): Promise<IStickinessResponse> => {
|
||||
const res = await fetch(path);
|
||||
|
||||
if (res.status === 404) {
|
||||
return { status: 404 };
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
await handleErrorResponses('Project stickiness data')(res);
|
||||
}
|
||||
|
||||
return {
|
||||
status: res.status,
|
||||
body: await res.json(),
|
||||
};
|
||||
};
|
@ -1,35 +0,0 @@
|
||||
import useUiConfig from './api/getters/useUiConfig/useUiConfig';
|
||||
import { usePlausibleTracker } from './usePlausibleTracker';
|
||||
|
||||
const DEFAULT_STICKINESS = 'default';
|
||||
export const useDefaultProjectStickiness = (projectId?: string) => {
|
||||
const { trackEvent } = usePlausibleTracker();
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const key = `defaultStickiness.${projectId}`;
|
||||
const { projectScopedStickiness } = uiConfig.flags;
|
||||
const projectStickiness = localStorage.getItem(key);
|
||||
|
||||
const defaultStickiness =
|
||||
Boolean(projectScopedStickiness) &&
|
||||
projectStickiness != null &&
|
||||
projectId
|
||||
? projectStickiness
|
||||
: DEFAULT_STICKINESS;
|
||||
|
||||
const setDefaultProjectStickiness = (stickiness: string) => {
|
||||
if (
|
||||
Boolean(projectScopedStickiness) &&
|
||||
projectId &&
|
||||
stickiness !== ''
|
||||
) {
|
||||
localStorage.setItem(key, stickiness);
|
||||
trackEvent('project_stickiness_set');
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
defaultStickiness,
|
||||
setDefaultProjectStickiness,
|
||||
};
|
||||
};
|
@ -133,7 +133,7 @@ import {
|
||||
importTogglesSchema,
|
||||
importTogglesValidateSchema,
|
||||
importTogglesValidateItemSchema,
|
||||
stickinessSchema,
|
||||
projectSettingsSchema,
|
||||
} from './spec';
|
||||
import { IServerOption } from '../types';
|
||||
import { mapValues, omitKeys } from '../util';
|
||||
@ -257,7 +257,7 @@ export const schemas = {
|
||||
stateSchema,
|
||||
strategiesSchema,
|
||||
strategySchema,
|
||||
stickinessSchema,
|
||||
projectSettingsSchema,
|
||||
tagsBulkAddSchema,
|
||||
tagSchema,
|
||||
tagsSchema,
|
||||
|
@ -129,7 +129,7 @@ export * from './project-overview-schema';
|
||||
export * from './import-toggles-validate-item-schema';
|
||||
export * from './import-toggles-validate-schema';
|
||||
export * from './import-toggles-schema';
|
||||
export * from './stickiness-schema';
|
||||
export * from './project-settings-schema';
|
||||
export * from './tags-bulk-add-schema';
|
||||
export * from './upsert-segment-schema';
|
||||
export * from './batch-features-schema';
|
||||
|
23
src/lib/openapi/spec/project-settings-schema.ts
Normal file
23
src/lib/openapi/spec/project-settings-schema.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
|
||||
export const projectSettingsSchema = {
|
||||
$id: '#/components/schemas/projectSettingsSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['defaultStickiness'],
|
||||
properties: {
|
||||
defaultStickiness: {
|
||||
type: 'string',
|
||||
example: 'userId',
|
||||
nullable: true,
|
||||
},
|
||||
mode: {
|
||||
type: 'string',
|
||||
enum: ['open', 'protected', 'private'],
|
||||
nullable: true,
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type ProjectSettingsSchema = FromSchema<typeof projectSettingsSchema>;
|
@ -1,17 +0,0 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
|
||||
export const stickinessSchema = {
|
||||
$id: '#/components/schemas/stickinessSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['stickiness'],
|
||||
properties: {
|
||||
stickiness: {
|
||||
type: 'string',
|
||||
example: 'userId',
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type StickinessSchema = FromSchema<typeof stickinessSchema>;
|
@ -1,31 +1,32 @@
|
||||
import { Response } from 'express';
|
||||
import Controller from '../../controller';
|
||||
import { IUnleashConfig } from '../../../types/option';
|
||||
import { IUnleashServices } from '../../../types/services';
|
||||
import {
|
||||
IArchivedQuery,
|
||||
IProjectParam,
|
||||
IUnleashConfig,
|
||||
IUnleashServices,
|
||||
NONE,
|
||||
serializeDates,
|
||||
UPDATE_PROJECT,
|
||||
} from '../../../types';
|
||||
import ProjectFeaturesController from './project-features';
|
||||
import EnvironmentsController from './environments';
|
||||
import ProjectHealthReport from './health-report';
|
||||
import ProjectService from '../../../services/project-service';
|
||||
import VariantsController from './variants';
|
||||
import { NONE, UPDATE_PROJECT } from '../../../types/permissions';
|
||||
import {
|
||||
projectsSchema,
|
||||
ProjectsSchema,
|
||||
} from '../../../openapi/spec/projects-schema';
|
||||
import { OpenApiService } from '../../../services/openapi-service';
|
||||
import { serializeDates } from '../../../types/serialize-dates';
|
||||
import { createResponseSchema } from '../../../openapi/util/create-response-schema';
|
||||
import { IAuthRequest } from '../../unleash-types';
|
||||
import {
|
||||
createResponseSchema,
|
||||
emptyResponse,
|
||||
ProjectOverviewSchema,
|
||||
projectOverviewSchema,
|
||||
stickinessSchema,
|
||||
StickinessSchema,
|
||||
} from '../../../../lib/openapi';
|
||||
import { IArchivedQuery, IProjectParam } from '../../../types/model';
|
||||
ProjectSettingsSchema,
|
||||
projectSettingsSchema,
|
||||
projectsSchema,
|
||||
ProjectsSchema,
|
||||
} from '../../../openapi';
|
||||
import { OpenApiService, SettingService } from '../../../services';
|
||||
import { IAuthRequest } from '../../unleash-types';
|
||||
import { ProjectApiTokenController } from './api-token';
|
||||
import { SettingService } from '../../../services';
|
||||
import ProjectArchiveController from './project-archive';
|
||||
|
||||
const STICKINESS_KEY = 'stickiness';
|
||||
@ -78,15 +79,15 @@ export default class ProjectApi extends Controller {
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
path: '/:projectId/stickiness',
|
||||
handler: this.getProjectDefaultStickiness,
|
||||
path: '/:projectId/settings',
|
||||
handler: this.getProjectSettings,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
services.openApiService.validPath({
|
||||
tags: ['Projects'],
|
||||
operationId: 'getProjectDefaultStickiness',
|
||||
operationId: 'getProjectSettings',
|
||||
responses: {
|
||||
200: createResponseSchema('stickinessSchema'),
|
||||
200: createResponseSchema('projectSettingsSchema'),
|
||||
404: emptyResponse,
|
||||
},
|
||||
}),
|
||||
@ -95,15 +96,15 @@ export default class ProjectApi extends Controller {
|
||||
|
||||
this.route({
|
||||
method: 'post',
|
||||
path: '/:projectId/stickiness',
|
||||
handler: this.setProjectDefaultStickiness,
|
||||
path: '/:projectId/settings',
|
||||
handler: this.setProjectSettings,
|
||||
permission: UPDATE_PROJECT,
|
||||
middleware: [
|
||||
services.openApiService.validPath({
|
||||
tags: ['Projects'],
|
||||
operationId: 'setProjectDefaultStickiness',
|
||||
operationId: 'setProjectSettings',
|
||||
responses: {
|
||||
200: createResponseSchema('stickinessSchema'),
|
||||
200: createResponseSchema('projectSettingsSchema'),
|
||||
404: emptyResponse,
|
||||
},
|
||||
}),
|
||||
@ -158,9 +159,9 @@ export default class ProjectApi extends Controller {
|
||||
);
|
||||
}
|
||||
|
||||
async getProjectDefaultStickiness(
|
||||
async getProjectSettings(
|
||||
req: IAuthRequest<IProjectParam, unknown, unknown, unknown>,
|
||||
res: Response<StickinessSchema>,
|
||||
res: Response<ProjectSettingsSchema>,
|
||||
): Promise<void> {
|
||||
if (!this.config.flagResolver.isEnabled('projectScopedStickiness')) {
|
||||
res.status(404);
|
||||
@ -176,33 +177,33 @@ export default class ProjectApi extends Controller {
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
stickinessSchema.$id,
|
||||
{ stickiness: stickinessSettings[projectId] },
|
||||
projectSettingsSchema.$id,
|
||||
{ defaultStickiness: stickinessSettings[projectId] },
|
||||
);
|
||||
}
|
||||
|
||||
async setProjectDefaultStickiness(
|
||||
async setProjectSettings(
|
||||
req: IAuthRequest<
|
||||
IProjectParam,
|
||||
StickinessSchema,
|
||||
StickinessSchema,
|
||||
ProjectSettingsSchema,
|
||||
ProjectSettingsSchema,
|
||||
unknown
|
||||
>,
|
||||
res: Response<StickinessSchema>,
|
||||
res: Response<ProjectSettingsSchema>,
|
||||
): Promise<void> {
|
||||
if (!this.config.flagResolver.isEnabled('projectScopedStickiness')) {
|
||||
res.status(404);
|
||||
return Promise.resolve();
|
||||
}
|
||||
const { projectId } = req.params;
|
||||
const { stickiness } = req.body;
|
||||
const { defaultStickiness } = req.body;
|
||||
const stickinessSettings = await this.settingService.get<{}>(
|
||||
STICKINESS_KEY,
|
||||
{
|
||||
[projectId]: DEFAULT_STICKINESS,
|
||||
},
|
||||
);
|
||||
stickinessSettings[projectId] = stickiness;
|
||||
stickinessSettings[projectId] = defaultStickiness;
|
||||
await this.settingService.insert(
|
||||
STICKINESS_KEY,
|
||||
stickinessSettings,
|
||||
@ -212,8 +213,8 @@ export default class ProjectApi extends Controller {
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
stickinessSchema.$id,
|
||||
{ stickiness: stickiness },
|
||||
projectSettingsSchema.$id,
|
||||
{ defaultStickiness },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -46,15 +46,15 @@ test('Should store and retrieve default project stickiness', async () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const reqBody = { stickiness: 'userId' };
|
||||
const reqBody = { defaultStickiness: 'userId' };
|
||||
|
||||
await appWithDefaultStickiness.request
|
||||
.post('/api/admin/projects/default/stickiness')
|
||||
.post('/api/admin/projects/default/settings')
|
||||
.send(reqBody)
|
||||
.expect(200);
|
||||
|
||||
const { body } = await appWithDefaultStickiness.request
|
||||
.get('/api/admin/projects/default/stickiness')
|
||||
.get('/api/admin/projects/default/settings')
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/);
|
||||
|
||||
|
@ -2863,6 +2863,29 @@ exports[`should serve the OpenAPI spec 1`] = `
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"projectSettingsSchema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"defaultStickiness": {
|
||||
"example": "userId",
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
"mode": {
|
||||
"enum": [
|
||||
"open",
|
||||
"protected",
|
||||
"private",
|
||||
],
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"defaultStickiness",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"projectStatsSchema": {
|
||||
"additionalProperties": false,
|
||||
"description": "Statistics for a project, including the average time to production, number of features created, the project activity and more.
|
||||
@ -3546,19 +3569,6 @@ Stats are divided into current and previous **windows**.
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"stickinessSchema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"stickiness": {
|
||||
"example": "userId",
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"stickiness",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"strategiesSchema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@ -7484,6 +7494,70 @@ If the provided project does not exist, the list of events will be empty.",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/projects/{projectId}/settings": {
|
||||
"get": {
|
||||
"operationId": "getProjectSettings",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "projectId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/projectSettingsSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "projectSettingsSchema",
|
||||
},
|
||||
"404": {
|
||||
"description": "This response has no body.",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
"Projects",
|
||||
],
|
||||
},
|
||||
"post": {
|
||||
"operationId": "setProjectSettings",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "projectId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/projectSettingsSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "projectSettingsSchema",
|
||||
},
|
||||
"404": {
|
||||
"description": "This response has no body.",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
"Projects",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/projects/{projectId}/stale": {
|
||||
"post": {
|
||||
"description": "This endpoint stales the specified features.",
|
||||
@ -7520,70 +7594,6 @@ If the provided project does not exist, the list of events will be empty.",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/projects/{projectId}/stickiness": {
|
||||
"get": {
|
||||
"operationId": "getProjectDefaultStickiness",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "projectId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/stickinessSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "stickinessSchema",
|
||||
},
|
||||
"404": {
|
||||
"description": "This response has no body.",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
"Projects",
|
||||
],
|
||||
},
|
||||
"post": {
|
||||
"operationId": "setProjectDefaultStickiness",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "projectId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/stickinessSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "stickinessSchema",
|
||||
},
|
||||
"404": {
|
||||
"description": "This response has no body.",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
"Projects",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/splash/{id}": {
|
||||
"post": {
|
||||
"operationId": "updateSplashSettings",
|
||||
|
Loading…
Reference in New Issue
Block a user