Skip to content

Commit 060d103

Browse files
authored
[MI-2135]: Moved filter on the server side to get subscriptions for the requested channel (#75)
* [MI-2135]: Moved filter on the server side to get subscriptions for the requested channel * [MI-2135]: Fixed CI * [MI-2135]: Review fixes: refactored code * [MI-2135]: Review fixes: minor changes * [MI-2135]: Disable CGO for all builds Co-authored-by: Abhishek Verma <[email protected]>
1 parent ce82434 commit 060d103

File tree

9 files changed

+60
-47
lines changed

9 files changed

+60
-47
lines changed

Makefile

+12-12
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,25 @@ ifneq ($(HAS_SERVER),)
6363
ifeq ($(MM_DEBUG),)
6464
ifneq ($(MM_SERVICESETTINGS_ENABLEDEVELOPER),)
6565
@echo Building plugin only for $(DEFAULT_GOOS)-$(DEFAULT_GOARCH) because MM_SERVICESETTINGS_ENABLEDEVELOPER is enabled
66-
cd server && $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
66+
cd server && env CGO_ENABLED=0 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
6767
else
68-
cd server && env GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-amd64;
69-
cd server && env GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-arm64;
70-
cd server && env GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-amd64;
71-
cd server && env GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-arm64;
72-
cd server && env GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-windows-amd64.exe;
68+
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-amd64;
69+
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-arm64;
70+
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-amd64;
71+
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-arm64;
72+
cd server && env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-windows-amd64.exe;
7373
endif
7474
else
7575
$(info DEBUG mode is on; to disable, unset MM_DEBUG)
7676
ifneq ($(MM_SERVICESETTINGS_ENABLEDEVELOPER),)
7777
@echo Building plugin only for $(DEFAULT_GOOS)-$(DEFAULT_GOARCH) because MM_SERVICESETTINGS_ENABLEDEVELOPER is enabled
78-
cd server && $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
78+
cd server && env CGO_ENABLED=0 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
7979
else
80-
cd server && env GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-amd64;
81-
cd server && env GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-arm64;
82-
cd server && env GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-amd64;
83-
cd server && env GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-arm64;
84-
cd server && env GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-windows-amd64.exe;
80+
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-amd64;
81+
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-arm64;
82+
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-amd64;
83+
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-arm64;
84+
cd server && env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-windows-amd64.exe;
8585
endif
8686
endif
8787
endif

server/constants/constants.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ const (
4545
PathParamTeamID = "team_id"
4646

4747
// URL query params constants
48-
QueryParamProject = "project"
48+
QueryParamProject = "project"
49+
QueryParamChannelID = "channel_id"
4950

5051
// Authorization constants
5152
Bearer = "Bearer"

server/plugin/api.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,15 @@ func (p *Plugin) handleGetSubscriptions(w http.ResponseWriter, r *http.Request)
281281
return
282282
}
283283

284+
channelID := r.URL.Query().Get(constants.QueryParamChannelID)
284285
project := r.URL.Query().Get(constants.QueryParamProject)
285286
if project != "" {
286287
subscriptionByProject := []*serializers.SubscriptionDetails{}
287288
for _, subscription := range subscriptionList {
288289
if subscription.ProjectName == project {
289-
subscriptionByProject = append(subscriptionByProject, subscription)
290+
if channelID == "" || subscription.ChannelID == channelID {
291+
subscriptionByProject = append(subscriptionByProject, subscription)
292+
}
290293
}
291294
}
292295
subscriptionList = subscriptionByProject

webapp/src/containers/Rhs/projectDetails/index.tsx

+27-29
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {memo, useEffect, useState} from 'react';
1+
import React, {memo, useEffect, useMemo, useState} from 'react';
22
import {useDispatch, useSelector} from 'react-redux';
33

44
import {GlobalState} from 'mattermost-redux/types/store';
@@ -21,27 +21,26 @@ import {getSubscribeModalState, getWebsocketEventState} from 'selectors';
2121

2222
import usePluginApi from 'hooks/usePluginApi';
2323
import useApiRequestCompletionState from 'hooks/useApiRequestCompletionState';
24-
25-
import {getCurrentChannelSubscriptions} from 'utils/filterData';
24+
import usePreviousState from 'hooks/usePreviousState';
2625

2726
const ProjectDetails = memo((projectDetails: ProjectDetails) => {
2827
const {projectName, organizationName} = projectDetails;
2928

30-
// Hooks
31-
const dispatch = useDispatch();
32-
const {makeApiRequestWithCompletionStatus, makeApiRequest, getApiState, state} = usePluginApi();
33-
3429
// State variables
30+
const [showAllSubscriptions, setShowAllSubscriptions] = useState(false);
3531
const [showProjectConfirmationModal, setShowProjectConfirmationModal] = useState(false);
3632
const [showSubscriptionConfirmationModal, setShowSubscriptionConfirmationModal] = useState(false);
3733
const [subscriptionToBeDeleted, setSubscriptionToBeDeleted] = useState<SubscriptionPayload>();
38-
const [showAllSubscriptions, setShowAllSubscriptions] = useState(false);
39-
const [subscriptionList, setSubscriptionList] = useState<SubscriptionDetails[]>([]);
4034
const {currentChannelId} = useSelector((reduxState: GlobalState) => reduxState.entities.channels);
35+
const subscriptionListApiParams = useMemo<FetchSubscriptionList>(() => ({
36+
project: projectName,
37+
channel_id: showAllSubscriptions ? '' : currentChannelId,
38+
}), [projectName, currentChannelId, showAllSubscriptions]);
4139

42-
const project: FetchSubscriptionList = {project: projectName};
43-
const {data, isLoading} = getApiState(plugin_constants.pluginApiServiceConfigs.getSubscriptionList.apiServiceName, project);
44-
const subscriptionData = data as SubscriptionDetails[];
40+
// Hooks
41+
const previousState = usePreviousState({currentChannelId});
42+
const dispatch = useDispatch();
43+
const {makeApiRequestWithCompletionStatus, makeApiRequest, getApiState, state} = usePluginApi();
4544

4645
const handleResetProjectDetails = () => {
4746
dispatch(resetProjectDetails());
@@ -86,7 +85,7 @@ const ProjectDetails = memo((projectDetails: ProjectDetails) => {
8685
// Fetch subscription list
8786
const fetchSubscriptionList = () => makeApiRequest(
8887
plugin_constants.pluginApiServiceConfigs.getSubscriptionList.apiServiceName,
89-
project,
88+
subscriptionListApiParams,
9089
);
9190

9291
// Handles deletion of a subscription and fetching the modified subscription list
@@ -105,31 +104,27 @@ const ProjectDetails = memo((projectDetails: ProjectDetails) => {
105104

106105
// Reset the state when the component is unmounted
107106
useEffect(() => {
108-
if (!getWebsocketEventState(state).isSubscriptionDeleted) {
109-
fetchSubscriptionList();
110-
}
111-
112107
return () => {
113108
handleResetProjectDetails();
114109
};
115110
}, []);
116111

117112
useEffect(() => {
118-
if (subscriptionData) {
119-
if (showAllSubscriptions) {
120-
setSubscriptionList(subscriptionData);
121-
} else {
122-
setSubscriptionList(getCurrentChannelSubscriptions(subscriptionData, currentChannelId));
123-
}
113+
/**
114+
* Prevent calling API to fetch subscription list twice on switching channel
115+
*
116+
* If the current channel is changed and "showAllSubscriptions" was true on the last channel then
117+
* this useEffect runs twice because "subscriptionListApiParams" is modified twice
118+
* once when "currentChannelId" is updated and other time when "showAllSubscriptions" is set to false
119+
*/
120+
if (showAllSubscriptions && previousState?.currentChannelId !== currentChannelId) {
121+
return;
124122
}
125-
}, [subscriptionData, showAllSubscriptions]);
123+
fetchSubscriptionList();
124+
}, [subscriptionListApiParams]);
126125

127-
// Update subscription list on switching channels
128126
useEffect(() => {
129-
if (subscriptionData) {
130-
setShowAllSubscriptions(false);
131-
setSubscriptionList(getCurrentChannelSubscriptions(subscriptionData, currentChannelId));
132-
}
127+
setShowAllSubscriptions(false);
133128
}, [currentChannelId]);
134129

135130
// Fetch the subscription list when new subscription is created
@@ -140,6 +135,9 @@ const ProjectDetails = memo((projectDetails: ProjectDetails) => {
140135
}
141136
}, [getSubscribeModalState(state).isCreated]);
142137

138+
const {data, isLoading} = getApiState(plugin_constants.pluginApiServiceConfigs.getSubscriptionList.apiServiceName, subscriptionListApiParams);
139+
const subscriptionList = data as SubscriptionDetails[];
140+
143141
const {isLoading: isUnlinkProjectLoading} = getApiState(plugin_constants.pluginApiServiceConfigs.unlinkProject.apiServiceName, projectDetails);
144142
const {isLoading: isDeleteSubscriptionLoading} = getApiState(plugin_constants.pluginApiServiceConfigs.deleteSubscription.apiServiceName, subscriptionToBeDeleted);
145143

webapp/src/hooks/usePreviousState.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {useEffect, useRef} from 'react';
2+
3+
function usePreviousState(value: Record<string, string>) {
4+
const ref = useRef<Record<string, string>>();
5+
useEffect(() => {
6+
ref.current = value;
7+
});
8+
return ref.current;
9+
}
10+
11+
export default usePreviousState;

webapp/src/plugin_constants/apiService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const pluginApiServiceConfigs: Record<ApiServiceName, PluginApiService> =
3636
apiServiceName: 'getChannels',
3737
},
3838
getSubscriptionList: {
39-
path: '/subscriptions?project=',
39+
path: '/subscriptions',
4040
method: 'GET',
4141
apiServiceName: 'getSubscriptionList',
4242
},

webapp/src/services/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ const azureDevOpsPluginApi = createApi({
6767
[Constants.pluginApiServiceConfigs.getSubscriptionList.apiServiceName]: builder.query<SubscriptionDetails[], FetchSubscriptionList>({
6868
query: (params) => ({
6969
headers: {[Constants.common.HeaderCSRFToken]: Cookies.get(Constants.common.MMCSRF)},
70-
url: `${Constants.pluginApiServiceConfigs.getSubscriptionList.path}${params.project}`,
70+
url: Constants.pluginApiServiceConfigs.getSubscriptionList.path,
7171
method: Constants.pluginApiServiceConfigs.getSubscriptionList.method,
72+
params: {...params},
7273
}),
7374
}),
7475
[Constants.pluginApiServiceConfigs.deleteSubscription.apiServiceName]: builder.query<void, APIRequestPayload>({

webapp/src/types/common/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type FetchChannelParams = {
5252

5353
type FetchSubscriptionList = {
5454
project: string;
55+
channel_id: string;
5556
}
5657

5758
type SubscriptionDetails = {

webapp/src/utils/filterData.ts

-2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,3 @@ export const getProjectList = (data: ProjectDetails[]) => {
1919
data.map((project) => projectList.push({value: project.projectName, label: project.projectName, metaData: project.organizationName}));
2020
return projectList;
2121
};
22-
23-
export const getCurrentChannelSubscriptions = (data: SubscriptionDetails[], channelID: string): SubscriptionDetails[] => data.filter(((subscription) => subscription.channelID === channelID));

0 commit comments

Comments
 (0)