Skip to content

Commit

Permalink
Changes for subscription to project or everything (#1896)
Browse files Browse the repository at this point in the history
* updates on engagement publish

* update email template

* adding action drop down

* updated changes for User Management

* access user details page for users without a role

* updating variable name

* updating the schema

* updating as per review comments

* updating schema

* adding changes for clone and delete

* fixing linting

* update

* fix for report setting on analytics

* fixing lint

* Adding Viewer role changes

* Changes for subscription to project or everything

* removing changes for viewer role

* updating feedbacks
  • Loading branch information
VineetBala-AOT authored Jul 27, 2023
1 parent 80fd232 commit 8e2df2e
Show file tree
Hide file tree
Showing 18 changed files with 224 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""add_subscribe_to_project
Revision ID: 5a1258a76598
Revises: 0329d7d10a5f
Create Date: 2023-07-26 11:54:08.922003
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '5a1258a76598'
down_revision = '0329d7d10a5f'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute('CREATE TYPE subscriptiontype AS ENUM (\'ENGAGEMENT\', \'PROJECT\', \'TENANT\');')
op.add_column('subscription', sa.Column('project_id', sa.String(length=50), nullable=True))
op.add_column('subscription', sa.Column('type', sa.Enum('ENGAGEMENT', 'PROJECT', 'TENANT', name='subscriptiontype'), nullable=True))
# ### end Alembic commands ###

def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('subscription', 'type')
op.drop_column('subscription', 'project_id')
op.execute("""DROP TYPE subscriptiontype""")
# ### end Alembic commands ###
30 changes: 30 additions & 0 deletions met-api/src/met_api/constants/subscription_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright © 2021 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Constants for subscription."""
from enum import IntEnum


class SubscriptionType(IntEnum):
"""Enum of Subscription Type.
User is able to subscribe to various notifications from the application. Subscription Type helps determine
the subscription user has chosen.
ENGAGEMENT - Provides user with notification on a particular engagement
PROJECT - Provides user with notification on all engagements within a particular project
TENANT - Provides user with notification on all engagements within a tenant
"""

ENGAGEMENT = 1
PROJECT = 2
TENANT = 3
6 changes: 6 additions & 0 deletions met-api/src/met_api/models/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from met_api.schemas.subscription import SubscriptionSchema

from met_api.constants.subscription_type import SubscriptionType

from .base_model import BaseModel
from .db import db

Expand All @@ -21,6 +23,8 @@ class Subscription(BaseModel): # pylint: disable=too-few-public-methods
engagement_id = db.Column(db.Integer, nullable=True)
participant_id = db.Column(db.Integer, ForeignKey('participant.id'), nullable=True)
is_subscribed = db.Column(db.Boolean, nullable=False)
project_id = db.Column(db.String(50))
type = db.Column(db.Enum(SubscriptionType), nullable=True)

@classmethod
def get(cls) -> Subscription:
Expand Down Expand Up @@ -53,6 +57,8 @@ def create(cls, subscription: SubscriptionSchema, session=None) -> Subscription:
engagement_id=subscription.get('engagement_id', None),
participant_id=subscription.get('participant_id', None),
is_subscribed=subscription.get('is_subscribed', None),
project_id=subscription.get('project_id', None),
type=subscription.get('type', None),
created_date=datetime.utcnow(),
created_by=subscription.get('created_by', None),
)
Expand Down
4 changes: 2 additions & 2 deletions met-api/src/met_api/resources/email_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def post():
try:
requestjson = request.get_json()
email_verification = EmailVerificationSchema().load(requestjson)
EmailVerificationService().create(email_verification)
return {}, HTTPStatus.OK
created_email_verification = EmailVerificationService().create(email_verification)
return created_email_verification, HTTPStatus.OK
except KeyError as err:
return str(err), HTTPStatus.INTERNAL_SERVER_ERROR
except ValueError as err:
Expand Down
2 changes: 1 addition & 1 deletion met-api/src/met_api/resources/engagement_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class EngagementMetadata(Resource):

@staticmethod
@cross_origin(origins=allowedorigins())
@auth.require
@auth.optional
def get(engagement_id):
"""Fetch a single engagement metadata matching the provided id."""
try:
Expand Down
14 changes: 14 additions & 0 deletions met-api/src/met_api/resources/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,17 @@ def post():
return str(err), HTTPStatus.INTERNAL_SERVER_ERROR
except ValueError as err:
return str(err), HTTPStatus.INTERNAL_SERVER_ERROR

@staticmethod
@cross_origin(origins=allowedorigins())
def patch():
"""Update a existing subscription partially."""
try:
request_json = request.get_json()
subscription = SubscriptionSchema().load(request_json, partial=True)
SubscriptionService().update_subscription_for_participant_eng(subscription)
return {}, HTTPStatus.OK
except KeyError as err:
return str(err), HTTPStatus.INTERNAL_SERVER_ERROR
except ValueError as err:
return str(err), HTTPStatus.INTERNAL_SERVER_ERROR
2 changes: 2 additions & 0 deletions met-api/src/met_api/schemas/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Meta: # pylint: disable=too-few-public-methods
engagement_id = fields.Int(data_key='engagement_id')
participant_id = fields.Int(data_key='participant_id')
is_subscribed = fields.Bool(data_key='is_subscribed')
project_id = fields.Str(data_key='project_id')
type = fields.Str(data_key='type')
created_by = fields.Str(data_key='created_by')
created_date = fields.Str(data_key='created_date')
updated_by = fields.Str(data_key='updated_by')
Expand Down
3 changes: 2 additions & 1 deletion met-web/src/apiManager/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ const Endpoints = {
Subscription: {
GET: `${AppConfig.apiUrl}/subscription/participant_id`,
CREATE: `${AppConfig.apiUrl}/subscription/`,
UPDATE: `${AppConfig.apiUrl}/subscription/`,
UNSUBSCRIBE: `${AppConfig.apiUrl}/subscription/`,
CREATE_UPDATE: `${AppConfig.apiUrl}/subscription/manage`,
CONFIRM_SUBSCRIPTION: `${AppConfig.apiUrl}/subscription/manage`,
},
PublicSubmission: {
CREATE: `${AppConfig.apiUrl}/submissions/public/verification_token`,
Expand Down
3 changes: 3 additions & 0 deletions met-web/src/components/common/Modals/EmailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const EmailModal = ({
updateModal,
header,
subText,
signupoptions,
termsOfService,
handleConfirm,
isSaving,
Expand Down Expand Up @@ -60,6 +61,8 @@ const EmailModal = ({
</Grid>
))}

{signupoptions}

<Grid item xs={12}>
{termsOfService}
</Grid>
Expand Down
1 change: 1 addition & 0 deletions met-web/src/components/common/Modals/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface ModalProps {
header: string;
subText: Array<ModalSubtext>;
email: string;
signupoptions: ReactNode;
termsOfService: ReactNode;
handleConfirm: () => void;
updateEmail: (email: string) => void;
Expand Down
36 changes: 35 additions & 1 deletion met-web/src/components/engagement/view/ActionContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React, { createContext, useState, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { getEngagement, patchEngagement } from '../../../services/engagementService';
import { createDefaultEngagement, Engagement } from '../../../models/engagement';
import { getEngagementMetadata } from '../../../services/engagementMetadataService';
import {
createDefaultEngagement,
createDefaultEngagementMetadata,
Engagement,
EngagementMetadata,
} from '../../../models/engagement';
import { useAppDispatch } from 'hooks';
import { openNotification } from 'services/notificationService/notificationSlice';
import { Widget } from 'models/widget';
Expand All @@ -19,8 +25,10 @@ interface EngagementSchedule {

export interface EngagementViewContext {
savedEngagement: Engagement;
engagementMetadata: EngagementMetadata;
isEngagementLoading: boolean;
isWidgetsLoading: boolean;
isEngagementMetadataLoading: boolean;
scheduleEngagement: (_engagement: EngagementSchedule) => Promise<Engagement>;
widgets: Widget[];
mockStatus: SubmissionStatus;
Expand All @@ -38,8 +46,10 @@ export const ActionContext = createContext<EngagementViewContext>({
return Promise.reject();
},
savedEngagement: createDefaultEngagement(),
engagementMetadata: createDefaultEngagementMetadata(),
isEngagementLoading: true,
isWidgetsLoading: true,
isEngagementMetadataLoading: true,
widgets: [],
mockStatus: SubmissionStatus.Upcoming,
updateMockStatus: (status: SubmissionStatus) => {
Expand All @@ -55,10 +65,12 @@ export const ActionProvider = ({ children }: { children: JSX.Element | JSX.Eleme
engagementIdParam ? Number(engagementIdParam) : null,
);
const [savedEngagement, setSavedEngagement] = useState<Engagement>(createDefaultEngagement());
const [engagementMetadata, setEngagementMetadata] = useState<EngagementMetadata>(createDefaultEngagementMetadata());
const [mockStatus, setMockStatus] = useState(savedEngagement.submission_status);
const [widgets, setWidgets] = useState<Widget[]>([]);
const [isEngagementLoading, setEngagementLoading] = useState(true);
const [isWidgetsLoading, setIsWidgetsLoading] = useState(true);
const [isEngagementMetadataLoading, setIsEngagementMetadataLoading] = useState(true);

const [getWidgetsTrigger] = useLazyGetWidgetsQuery();

Expand Down Expand Up @@ -155,6 +167,25 @@ export const ActionProvider = ({ children }: { children: JSX.Element | JSX.Eleme
}
};

const fetchEngagementMetadata = async () => {
if (!savedEngagement.id) {
return;
}
try {
const result = await getEngagementMetadata(Number(engagementId));
setEngagementMetadata(result);
setIsEngagementMetadataLoading(false);
} catch (error) {
setIsEngagementMetadataLoading(false);
dispatch(
openNotification({
severity: 'error',
text: 'Error occurred while fetching Engagement Metadata',
}),
);
}
};

const handleFetchEngagementIdBySlug = async () => {
if (!slug) {
return;
Expand All @@ -177,16 +208,19 @@ export const ActionProvider = ({ children }: { children: JSX.Element | JSX.Eleme

useEffect(() => {
fetchWidgets();
fetchEngagementMetadata();
}, [savedEngagement]);

return (
<ActionContext.Provider
value={{
savedEngagement,
engagementMetadata,
isEngagementLoading,
scheduleEngagement,
widgets,
isWidgetsLoading,
isEngagementMetadataLoading,
updateMockStatus,
mockStatus,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { openNotification } from 'services/notificationService/notificationSlice
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import { SubscriptionType } from './subscribe';
import { verifyEmailVerification } from 'services/emailVerificationService';
import { createSubscription, unSubscribe } from 'services/subscriptionService';
import { confirmSubscription, unSubscribe } from 'services/subscriptionService';

export type SubscriptionParams = {
engagementId: string;
Expand Down Expand Up @@ -57,7 +57,7 @@ export const Subscription = () => {
const token = scriptionKey;
const subscribed_email = await verifyEmailVerification(token);
const subscribed = JSON.stringify(subscribed_email);
await createSubscription({
await confirmSubscription({
engagement_id: parseInt(engagementId ?? ''),
participant_id: JSON.parse(subscribed).participant_id,
is_subscribed: 'true',
Expand Down
Loading

0 comments on commit 8e2df2e

Please sign in to comment.