Skip to content

Commit

Permalink
Merge pull request #352 from bcgov/development
Browse files Browse the repository at this point in the history
merge development into master
  • Loading branch information
bdolor authored Jan 18, 2023
2 parents 38cf363 + c579961 commit 806e968
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 22 deletions.
2 changes: 1 addition & 1 deletion openshift/templates/app/app-digmkt-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ parameters:
- name: MEMORY_LIMIT
displayName: Resources Memory Limit
required: true
value: 240Mi
value: 360Mi

- name: REPLICAS
displayName: The number of replicas to run
Expand Down
4 changes: 2 additions & 2 deletions openshift/templates/database/patroni-digmkt-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,12 @@ parameters:
- description: Starting amount of memory the container can use.
displayName: Memory Request
name: MEMORY_REQUEST
value: 200Mi
value: 220Mi

- description: Maximum amount of memory the container can use.
displayName: Memory Limit
name: MEMORY_LIMIT
value: 400Mi
value: 660Mi

- description: The OpenShift Namespace where the patroni and postgresql ImageStream
resides.
Expand Down
7 changes: 7 additions & 0 deletions src/back-end/lib/mailer/templates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { prefixPath } from "back-end/lib";
import { CSSProperties, default as React, Fragment, ReactElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { SHOW_TEST_INDICATOR } from "shared/config";
import { VIEWER_USER_ROUTE_PARAM } from "shared/lib/resources/user";

// Styles.

Expand Down Expand Up @@ -406,6 +407,12 @@ const Layout: View<LayoutProps> = ({ title, description, children }) => {
<Row style={styles.classes.description}>{description}</Row>
) : null}
<Fragment>{children}</Fragment>
<Row style={{ ...styles.utilities.text.center }} >
<Link
text="Unsubscribe"
url={makeUrl(`users/${VIEWER_USER_ROUTE_PARAM}?tab=notifications&unsubscribe`)}
/>
</Row>
</Container>
</body>
</html>
Expand Down
4 changes: 2 additions & 2 deletions src/back-end/lib/routers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async function makeRouter(

// If redirectOnSuccess specified, include that as query parameter for callback
if (redirectOnSuccess) {
authQuery.redirect_uri += `?redirectOnSuccess=${redirectOnSuccess}`;
authQuery.redirect_uri += `?redirectOnSuccess=${encodeURIComponent(redirectOnSuccess)}`;
}

if (provider === VENDOR_IDP_SUFFIX || provider === GOV_IDP_SUFFIX) {
Expand Down Expand Up @@ -136,7 +136,7 @@ async function makeRouter(

// If redirectOnSuccess was provided on callback, this must also be provided on token request (redirect_uri must match for each request)
if (redirectOnSuccess) {
data.redirect_uri += `?redirectOnSuccess=${redirectOnSuccess}`;
data.redirect_uri += `?redirectOnSuccess=${encodeURIComponent(redirectOnSuccess)}`;
}

const headers = {
Expand Down
6 changes: 5 additions & 1 deletion src/front-end/typescript/lib/app/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ const router: router_.Router<Route> = {
invitation:
affiliationId && response
? { affiliationId, response }
: undefined
: undefined,
...('unsubscribe' in query && {unsubscribe: true})
}
};
}
Expand Down Expand Up @@ -513,6 +514,9 @@ const router: router_.Router<Route> = {
);
query.push(`invitationResponse=${route.value.invitation.response}`);
}
if (route.value.unsubscribe) {
query.push("unsubscribe")
}
let qs = "";
if (query.length) {
qs = `?${query.join("&")}`;
Expand Down
13 changes: 9 additions & 4 deletions src/front-end/typescript/lib/pages/user/profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
isAdmin,
isPublicSectorEmployee,
isVendor,
VIEWER_USER_ROUTE_PARAM,
User
} from "shared/lib/resources/user";
import { adt, ADT, Id } from "shared/lib/types";
Expand Down Expand Up @@ -50,7 +51,7 @@ export type Msg_<K extends Tab.TabId> = Tab.ParentMsg<K, InnerMsg>;

export type Msg = Msg_<Tab.TabId>;

export interface RouteParams extends Pick<Tab.Params, "invitation"> {
export interface RouteParams extends Pick<Tab.Params, "invitation" | "unsubscribe"> {
userId: Id;
tab?: Tab.TabId;
}
Expand All @@ -75,7 +76,10 @@ function makeInit<K extends Tab.TabId>(): component_.page.Init<
})
) as State_<K>,
[
api.users.readOne(routeParams.userId, (response) =>
api.users.readOne(routeParams.userId === VIEWER_USER_ROUTE_PARAM
? viewerUser.id
: routeParams.userId,
(response) =>
adt("onInitResponse", [routePath, routeParams, response])
) as component_.Cmd<Msg>
]
Expand All @@ -91,7 +95,7 @@ function makeInit<K extends Tab.TabId>(): component_.page.Init<
component_.global.replaceRouteMsg(
adt("signIn" as const, {
redirectOnSuccess: router.routeToUrl(
adt("userProfile", { userId: routeParams.userId })
adt("userProfile", routeParams)
)
})
)
Expand Down Expand Up @@ -183,7 +187,8 @@ function makeComponent<K extends Tab.TabId>(): component_.page.Component<
const [tabState, tabCmds] = tabComponent.init({
profileUser,
viewerUser: state.viewerUser,
invitation: routeParams.invitation
invitation: routeParams.invitation,
unsubscribe: routeParams.unsubscribe
});
// Everything checks out, return valid state.
return [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface Params {
affiliationId: Id;
response: InvitationResponseParam;
};
unsubscribe?: true;
}

export type InitResponse = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,27 @@ import { adt, ADT } from "shared/lib/types";
import { User, UpdateValidationErrors } from "shared/lib/resources/user";

export interface State extends Tab.Params {
showModal: boolean,
newOpportunitiesLoading: number;
newOpportunities: Immutable<Checkbox.State>;
}

export type InnerMsg =
| ADT<"newOpportunities", Checkbox.Msg>
| ADT<
"onToggleNewOpportunitiesResponse",
"onUpdateNotificationsResponse",
api.ResponseValidation<User, UpdateValidationErrors>
>;
>
| ADT<"updateNotifications", boolean>
| ADT<"showModal", boolean>
| ADT<"hideModal">;

export type Msg = component_.page.Msg<InnerMsg, Route>;

const init: component_.base.Init<Tab.Params, State, Msg> = ({
viewerUser,
profileUser
profileUser,
unsubscribe
}) => {
const [newOpportunitiesState, newOpportunitiesCmds] = Checkbox.init({
errors: [],
Expand All @@ -42,10 +47,11 @@ const init: component_.base.Init<Tab.Params, State, Msg> = ({
});
return [
{
showModal: (unsubscribe ?? false) && newOpportunitiesState.child.value,
profileUser,
viewerUser,
newOpportunitiesLoading: 0,
newOpportunities: immutable(newOpportunitiesState)
newOpportunities: immutable(newOpportunitiesState),
},
component_.cmd.mapMany(newOpportunitiesCmds, (msg) =>
adt("newOpportunities", msg)
Expand All @@ -62,6 +68,8 @@ const stopNewOpportunitiesLoading = makeStopLoading<State>(

const update: component_.base.Update<State, Msg> = ({ state, msg }) => {
switch (msg.tag) {
case "hideModal":
return [state.set("showModal", false), []];
case "newOpportunities": {
const valueChanged =
msg.value.tag === "child" && msg.value.value.tag === "onChange";
Expand All @@ -78,21 +86,27 @@ const update: component_.base.Update<State, Msg> = ({ state, msg }) => {
// Checkbox value has changed, so persist to back-end.
const [newState, cmds] = newOppResult;
return [
startNewOpportunitiesLoading(newState),
newState,
[
...cmds,
component_.cmd.dispatch(adt("updateNotifications", FormField.getValue(newState.newOpportunities)))
]
];
}
case "updateNotifications": {
return [
startNewOpportunitiesLoading(state)
.set("showModal", false),
[
api.users.update(
newState.profileUser.id,
adt(
"updateNotifications",
FormField.getValue(newState.newOpportunities)
),
(response) => adt("onToggleNewOpportunitiesResponse", response)
state.profileUser.id,
adt("updateNotifications", msg.value),
(response) => adt("onUpdateNotificationsResponse", response)
) as component_.Cmd<Msg>
]
];
}
case "onToggleNewOpportunitiesResponse": {
case "onUpdateNotificationsResponse": {
state = stopNewOpportunitiesLoading(state);
const response = msg.value;
if (api.isValid(response)) {
Expand Down Expand Up @@ -172,5 +186,30 @@ export const component: Tab.Component<State, Msg> = {
view,
onInitResponse() {
return component_.page.readyMsg();
},
getModal(state) {
if (!state.showModal) {
return component_.page.modal.hide();
}
return component_.page.modal.show({
title: "Unsubscribe?",
body: () =>
`Are you sure you want to unsubscribe? ${state.profileUser.email ?? 'You'} will no longer receive notifications about new opportunities.`,
onCloseMsg: adt("hideModal") as Msg,
actions: [
{
text: "Unsubscribe",
icon: "bell-slash-outline",
color: "success",
msg: adt("updateNotifications", false),
button: true
},
{
text: "Cancel",
color: "secondary",
msg: adt("hideModal")
}
]
});
}
};
2 changes: 2 additions & 0 deletions src/shared/lib/resources/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { FileRecord } from "shared/lib/resources/file";
import { ADT, BodyWithErrors, Id } from "shared/lib/types";
import { ErrorTypeFrom } from "shared/lib/validation";

export const VIEWER_USER_ROUTE_PARAM = "me";

export type KeyCloakIdentityProvider = string;

export enum UserType {
Expand Down

0 comments on commit 806e968

Please sign in to comment.