-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/deseng695: Updated Who is Listening Widget, changed colour of…
… Video Widget overlay logo, fixed media query for Map Widget expand link. (#2598) * feature/deseng695: Implemented Who Is Listening widget design, changed icon color for video widget, adjusted viewport for expand map link in map widget. * feature/deseng695: Updated contact create/edit form, minor styling update to image picker. * feature/deseng695: Made changes as per Alex, updated Who is Listening form for better legibility. * feature/deseng695: Removed blank labels from contact form.
- Loading branch information
1 parent
0b61f80
commit bb89f8d
Showing
30 changed files
with
913 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
met-api/migrations/versions/917a911b6ca9_added_widget_listening_table_for_.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
"""Added widget_listening table for storing values particular to the listening widget instance, but not related to contacts. | ||
Revision ID: 917a911b6ca9 | ||
Revises: 70a410c85b24 | ||
Create Date: 2024-10-01 15:34:13.253066 | ||
""" | ||
from alembic import op | ||
import sqlalchemy as sa | ||
from sqlalchemy.dialects import postgresql | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = '917a911b6ca9' | ||
down_revision = '70a410c85b24' | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
op.create_table('widget_listening', | ||
sa.Column('created_date', sa.DateTime(), nullable=False), | ||
sa.Column('updated_date', sa.DateTime(), nullable=True), | ||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), | ||
sa.Column('widget_id', sa.Integer(), nullable=True), | ||
sa.Column('engagement_id', sa.Integer(), nullable=True), | ||
sa.Column('description', sa.Text(), nullable=True), | ||
sa.Column('created_by', sa.String(length=50), nullable=True), | ||
sa.Column('updated_by', sa.String(length=50), nullable=True), | ||
sa.ForeignKeyConstraint(['engagement_id'], ['engagement.id'], ondelete='CASCADE'), | ||
sa.ForeignKeyConstraint(['widget_id'], ['widget.id'], ondelete='CASCADE'), | ||
sa.PrimaryKeyConstraint('id') | ||
) | ||
op.add_column('widget_translation', sa.Column('listening_description', sa.Text(), nullable=True)) | ||
|
||
|
||
def downgrade(): | ||
op.drop_column('widget_translation', 'listening_description') | ||
op.drop_table('widget_listening') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
"""WidgetListening model class. | ||
Manages the who is listening widget | ||
""" | ||
from __future__ import annotations | ||
|
||
from sqlalchemy.sql.schema import ForeignKey | ||
|
||
from .base_model import BaseModel | ||
from .db import db | ||
|
||
|
||
class WidgetListening(BaseModel): # pylint: disable=too-few-public-methods, too-many-instance-attributes | ||
"""Definition of the who is listening widget.""" | ||
|
||
__tablename__ = 'widget_listening' | ||
id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||
widget_id = db.Column(db.Integer, ForeignKey('widget.id', ondelete='CASCADE'), nullable=True) | ||
engagement_id = db.Column(db.Integer, ForeignKey('engagement.id', ondelete='CASCADE'), nullable=True) | ||
description = db.Column(db.Text()) | ||
|
||
@classmethod | ||
def get_listening(cls, widget_id) -> list[WidgetListening]: | ||
"""Get who is listening widget.""" | ||
widget_listening = db.session.query(WidgetListening) \ | ||
.filter(WidgetListening.widget_id == widget_id) \ | ||
.all() | ||
return widget_listening | ||
|
||
@classmethod | ||
def update_listening(cls, listening_widget_id, listening_data: dict) -> WidgetListening: | ||
"""Update who is listening widget.""" | ||
widget_listening: WidgetListening = WidgetListening.query.get(listening_widget_id) | ||
if widget_listening: | ||
for key, value in listening_data.items(): | ||
setattr(widget_listening, key, value) | ||
widget_listening.save() | ||
return widget_listening |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# 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. | ||
"""API endpoints for managing a listening widget resource.""" | ||
from http import HTTPStatus | ||
|
||
from flask import jsonify, request | ||
from flask_cors import cross_origin | ||
from flask_restx import Namespace, Resource | ||
|
||
from met_api.auth import jwt as _jwt | ||
from met_api.exceptions.business_exception import BusinessException | ||
from met_api.schemas import utils as schema_utils | ||
from met_api.schemas.widget_listening import WidgetListeningSchema | ||
from met_api.services.widget_listening_service import WidgetListeningService | ||
from met_api.utils.util import allowedorigins, cors_preflight | ||
|
||
|
||
API = Namespace('widget_listenings', description='Endpoints for Who Is Listening Widget Management') | ||
"""Widget Listenings""" | ||
|
||
|
||
@cors_preflight('GET, POST') | ||
@API.route('') | ||
class Listenings(Resource): | ||
"""Resource for managing Who is Listening widgets.""" | ||
|
||
@staticmethod | ||
@cross_origin(origins=allowedorigins()) | ||
def get(widget_id): | ||
"""Get Who is Listening widget.""" | ||
try: | ||
widget_listening = WidgetListeningService().get_listening(widget_id) | ||
return jsonify(WidgetListeningSchema().dump(widget_listening, many=True)), HTTPStatus.OK | ||
except BusinessException as err: | ||
return str(err), err.status_code | ||
|
||
@staticmethod | ||
@cross_origin(origins=allowedorigins()) | ||
@_jwt.requires_auth | ||
def post(widget_id): | ||
"""Create Who is Listening widget.""" | ||
try: | ||
request_json = request.get_json() | ||
widget_listening = WidgetListeningService().create_listening(widget_id, request_json) | ||
return WidgetListeningSchema().dump(widget_listening), HTTPStatus.OK | ||
except BusinessException as err: | ||
return str(err), err.status_code | ||
|
||
|
||
@cors_preflight('PATCH') | ||
@API.route('/<int:listening_widget_id>') | ||
class Listening(Resource): | ||
"""Resource for managing Who is Listening widgets.""" | ||
|
||
@staticmethod | ||
@cross_origin(origins=allowedorigins()) | ||
@_jwt.requires_auth | ||
def patch(widget_id, listening_widget_id): | ||
"""Update Who is Listening widget.""" | ||
request_json = request.get_json() | ||
valid_format, errors = schema_utils.validate(request_json, 'listening_widget_update') | ||
if not valid_format: | ||
return {'message': schema_utils.serialize(errors)}, HTTPStatus.BAD_REQUEST | ||
try: | ||
widget_listening = WidgetListeningService().update_listening(widget_id, listening_widget_id, request_json) | ||
return WidgetListeningSchema().dump(widget_listening), HTTPStatus.OK | ||
except BusinessException as err: | ||
return str(err), err.status_code |
23 changes: 23 additions & 0 deletions
23
met-api/src/met_api/schemas/schemas/listening_widget_update.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "https://met.gov.bc.ca/.well_known/schemas/listening_widget_update", | ||
"type": "object", | ||
"title": "The root schema", | ||
"description": "The root schema comprises the entire JSON document.", | ||
"default": {}, | ||
"examples": [ | ||
{ | ||
"description": "A Who is Listening widget description" | ||
} | ||
], | ||
"required": [], | ||
"properties": { | ||
"description": { | ||
"$id": "#/properties/description", | ||
"type": "string", | ||
"title": "Who is Listening description", | ||
"description": "The description of this Who is Listening widget.", | ||
"examples": ["A Who is Listening widget description"] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Copyright © 2019 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. | ||
"""Manager for widget listening schema.""" | ||
|
||
from met_api.models.widget_listening import WidgetListening as WidgetListeningModel | ||
|
||
from marshmallow import Schema | ||
from marshmallow_sqlalchemy.fields import Nested | ||
|
||
class WidgetListeningSchema(Schema): # pylint: disable=too-many-ancestors, too-few-public-methods | ||
"""This is the schema for the widget listening model.""" | ||
|
||
class Meta: # pylint: disable=too-few-public-methods | ||
"""All of the fields in the Widget Listening schema.""" | ||
|
||
model = WidgetListeningModel | ||
fields = ('id', 'engagement_id', 'widget_id', 'description') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"""Service for Widget Listening management.""" | ||
from http import HTTPStatus | ||
from typing import Optional | ||
|
||
from met_api.constants.membership_type import MembershipType | ||
from met_api.exceptions.business_exception import BusinessException | ||
from met_api.models.widget_listening import WidgetListening as WidgetListeningModel | ||
from met_api.services import authorization | ||
from met_api.utils.roles import Role | ||
|
||
|
||
class WidgetListeningService: | ||
"""Widget Listening management service.""" | ||
|
||
@staticmethod | ||
def get_listening_by_id(listening_id: int): | ||
"""Get listening by id.""" | ||
widget_listening = WidgetListeningModel.find_by_id(listening_id) | ||
return widget_listening | ||
|
||
@staticmethod | ||
def get_listening(widget_id: int): | ||
"""Get listening by widget id.""" | ||
widget_listening = WidgetListeningModel.get_listening(widget_id) | ||
return widget_listening | ||
|
||
@staticmethod | ||
def create_listening(widget_id: int, listening_details: dict): | ||
"""Create listening for the widget.""" | ||
listening_data = dict(listening_details) | ||
eng_id = listening_data.get('engagement_id') | ||
authorization.check_auth(one_of_roles=(MembershipType.TEAM_MEMBER.name, | ||
Role.EDIT_ENGAGEMENT.value), engagement_id=eng_id) | ||
|
||
widget_listening = WidgetListeningService._create_listening_model(widget_id, listening_data) | ||
widget_listening.commit() | ||
return widget_listening | ||
|
||
@staticmethod | ||
def update_listening(widget_id: int, listening_id: int, listening_data: dict) -> Optional[WidgetListeningModel]: | ||
"""Update listening widget.""" | ||
engagement_id = listening_data.get('engagement_id') | ||
|
||
WidgetListeningService._check_update_listening_auth(engagement_id) | ||
|
||
widget_listening: WidgetListeningModel = WidgetListeningModel.find_by_id(listening_id) | ||
|
||
if not widget_listening: | ||
raise BusinessException( | ||
error='Who is Listening widget not found', | ||
status_code=HTTPStatus.BAD_REQUEST) | ||
|
||
if widget_listening.widget_id != widget_id: | ||
raise BusinessException( | ||
error='Invalid widget ID', | ||
status_code=HTTPStatus.BAD_REQUEST) | ||
|
||
if widget_listening.id != listening_id: | ||
raise BusinessException( | ||
error='Invalid Who is Listening widget ID', | ||
status_code=HTTPStatus.BAD_REQUEST) | ||
|
||
WidgetListeningService._update_widget_listening(widget_listening, listening_data) | ||
|
||
return widget_listening | ||
|
||
@staticmethod | ||
def _check_update_listening_auth(engagement_id): | ||
authorization.check_auth(one_of_roles=(MembershipType.TEAM_MEMBER.name, | ||
Role.EDIT_ENGAGEMENT.value), engagement_id=engagement_id) | ||
|
||
@staticmethod | ||
def _update_widget_listening(widget_listening: WidgetListeningModel, listening_data: dict): | ||
widget_listening.description = listening_data.get('description') | ||
widget_listening.save() | ||
|
||
@staticmethod | ||
def _create_listening_model(widget_id: int, listening_data: dict): | ||
listening_model: WidgetListeningModel = WidgetListeningModel() | ||
listening_model.widget_id = widget_id | ||
listening_model.engagement_id = listening_data.get('engagement_id') | ||
listening_model.description = listening_data.get('description') | ||
listening_model.flush() | ||
return listening_model |
Oops, something went wrong.