Skip to content
Draft
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
27 changes: 26 additions & 1 deletion ui/src/app/environments/environmentsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export const environmentsSlice = createSlice({
if (state.currentEnvironment === action.payload.environmentKey) {
state.revision = action.payload.revision;
}
},
environmentAdded: (state, action) => {
state.environments[action.payload.key] = action.payload;
}
}
});
Expand All @@ -77,6 +80,7 @@ export const selectRevision = (state: RootState) => state.environments.revision;
export const {
currentEnvironmentChanged,
environmentsChanged,
environmentAdded,
revisionChanged
} = environmentsSlice.actions;

Expand Down Expand Up @@ -152,7 +156,28 @@ export const environmentsApi = createApi({
invalidatesTags: () => [
{ type: 'Environment' },
{ type: 'BranchEnvironment' }
]
],
async onQueryStarted(
{ environmentKey, key },
{ dispatch, queryFulfilled }
) {
try {
await queryFulfilled;
dispatch(
environmentsSlice.actions.environmentAdded({
key,
configuration: {
base: environmentKey,
remote: '',
branch: key,
directory: ''
}
})
);
} catch {
// Mutation failed, no cache updates needed
}
}
}),
deleteBranchEnvironment: builder.mutation<
void,
Expand Down
162 changes: 113 additions & 49 deletions ui/src/app/flags/flagsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { PayloadAction, createSlice } from '@reduxjs/toolkit';
import { createApi } from '@reduxjs/toolkit/query/react';
import { SortingState } from '@tanstack/react-table';

import { revisionChanged } from '~/app/environments/environmentsApi';

import { IFlag, IFlagList } from '~/types/Flag';
import { INamespaceList } from '~/types/Namespace';
import { IResourceListResponse, IResourceResponse } from '~/types/Resource';
Expand Down Expand Up @@ -32,6 +34,22 @@ export const flagsTableSlice = createSlice({
export const selectSorting = (state: RootState) => state.flagsTable.sorting;
export const { setSorting } = flagsTableSlice.actions;

function enrichFlag(flag: IFlag): IFlag {
return {
...flag,
rollouts: flag.rollouts?.map((r: IRollout, i: number) => ({
...r,
id: uuid(),
rank: i
})),
rules: flag.rules?.map((r: IRule, i: number) => ({
...r,
id: uuid(),
rank: i
}))
};
}

export const flagsApi = createApi({
reducerPath: 'flags',
baseQuery,
Expand Down Expand Up @@ -81,28 +99,12 @@ export const flagsApi = createApi({
{ type: 'Flag', id: environmentKey + '/' + namespaceKey }
],
transformResponse: (response: IResourceResponse<IFlag>): IFlag => {
return {
...response.resource.payload,
rollouts: response.resource.payload.rollouts?.map(
(r: IRollout, i: number) => ({
...r,
id: uuid(),
rank: i
})
),
rules: response.resource.payload.rules?.map(
(r: IRule, i: number) => ({
...r,
id: uuid(),
rank: i
})
)
};
return enrichFlag(response.resource.payload);
}
}),
// create a new flag in the namespace
createFlag: builder.mutation<
IFlag,
IResourceResponse<IFlag>,
{
environmentKey: string;
namespaceKey: string;
Expand All @@ -124,17 +126,42 @@ export const flagsApi = createApi({
}
};
},
invalidatesTags: (
_result,
_error,
{ environmentKey, namespaceKey, values }
) => [
{ type: 'Flag', id: environmentKey + '/' + namespaceKey },
{
type: 'Flag',
id: environmentKey + '/' + namespaceKey + '/' + values.key
async onQueryStarted(
{ environmentKey, namespaceKey },
{ dispatch, queryFulfilled }
) {
try {
const { data, meta } = await queryFulfilled;
if (meta?.revision) {
dispatch(
revisionChanged({ environmentKey, revision: meta.revision })
);
}
const payload = data.resource.payload;
dispatch(
flagsApi.util.upsertQueryData(
'getFlag',
{
environmentKey,
namespaceKey,
flagKey: data.resource.key
},
enrichFlag(payload)
)
);
dispatch(
flagsApi.util.updateQueryData(
'listFlags',
{ environmentKey, namespaceKey },
(draft) => {
draft.flags.push(payload);
}
)
);
} catch {
// Mutation failed, no cache updates needed
}
]
}
}),
// delete the flag from the namespace
deleteFlag: builder.mutation<
Expand All @@ -152,21 +179,34 @@ export const flagsApi = createApi({
method: 'DELETE'
};
},
invalidatesTags: (
_result,
_error,
{ environmentKey, namespaceKey, flagKey }
) => [
{ type: 'Flag', id: environmentKey + '/' + namespaceKey },
{
type: 'Flag',
id: environmentKey + '/' + namespaceKey + '/' + flagKey
async onQueryStarted(
{ environmentKey, namespaceKey, flagKey },
{ dispatch, queryFulfilled }
) {
try {
const { meta } = await queryFulfilled;
if (meta?.revision) {
dispatch(
revisionChanged({ environmentKey, revision: meta.revision })
);
}
dispatch(
flagsApi.util.updateQueryData(
'listFlags',
{ environmentKey, namespaceKey },
(draft) => {
draft.flags = draft.flags.filter((f) => f.key !== flagKey);
}
)
);
} catch {
// Mutation failed, no cache updates needed
}
]
}
}),
// update the flag in the namespace
updateFlag: builder.mutation<
IFlag,
IResourceResponse<IFlag>,
{
environmentKey: string;
namespaceKey: string;
Expand All @@ -190,17 +230,41 @@ export const flagsApi = createApi({
}
};
},
invalidatesTags: (
_result,
_error,
{ environmentKey, namespaceKey, flagKey }
) => [
{ type: 'Flag', id: environmentKey + '/' + namespaceKey },
{
type: 'Flag',
id: environmentKey + '/' + namespaceKey + '/' + flagKey
async onQueryStarted(
{ environmentKey, namespaceKey, flagKey },
{ dispatch, queryFulfilled }
) {
try {
const { data, meta } = await queryFulfilled;
if (meta?.revision) {
dispatch(
revisionChanged({ environmentKey, revision: meta.revision })
);
}
const payload = data.resource.payload;
dispatch(
flagsApi.util.upsertQueryData(
'getFlag',
{ environmentKey, namespaceKey, flagKey },
enrichFlag(payload)
)
);
dispatch(
flagsApi.util.updateQueryData(
'listFlags',
{ environmentKey, namespaceKey },
(draft) => {
const idx = draft.flags.findIndex((f) => f.key === flagKey);
if (idx >= 0) {
draft.flags[idx] = payload;
}
}
)
);
} catch {
// Mutation failed, no cache updates needed
}
]
}
}),
// copy the flag from one namespace to another one
copyFlag: builder.mutation<
Expand Down
Loading
Loading