Skip to content
Open
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
3 changes: 2 additions & 1 deletion appointment-frontend/public/config/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"VUE_APP_ROOT_API": "http://localhost:5000/api/v1",
"hideBCServicesCard": false,
"BCEIDRegistrationUrl": "https://www.test.bceid.ca/os/?7521&SkipTo=Basic",
"VUE_APP_GOOGLE_STATIC_MAP_API_KEY": "AIzaSyDdUTtNy6pLWILtlqHtcaXsFSprFQ9UroI"
"VUE_APP_GOOGLE_STATIC_MAP_API_KEY": "AIzaSyDdUTtNy6pLWILtlqHtcaXsFSprFQ9UroI",
"VUE_APP_FEEDBACK_API": "http://localhost:5001/api/v1"
}
5 changes: 4 additions & 1 deletion appointment-frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<v-app id="app">
<div class="app-body" :class="{'app-mobile': $vuetify.breakpoint.xs}">
<app-header :key="$store.state.refreshKey"></app-header>
<feedback></feedback>
<main class="main-block container">
<v-btn
color="secondary"
Expand All @@ -28,6 +29,7 @@ import { Component, Vue } from 'vue-property-decorator'
import { mapActions, mapGetters } from 'vuex'
import CommonUtils from './utils/common-util'
import ConfigHelper from '@/utils/config-helper'
import { Feedback } from './components/feedback'
import { KCUserProfile } from '@/models/KCUserProfile'
import KeyCloakService from '@/services/keycloak.services'
import { SessionStorageKeys } from '@/utils'
Expand All @@ -38,7 +40,8 @@ import { getModule } from 'vuex-module-decorators'
@Component({
components: {
AppHeader,
AppFooter
AppFooter,
Feedback
},
computed: {
...mapGetters('auth', [
Expand Down
563 changes: 563 additions & 0 deletions appointment-frontend/src/components/feedback/Feedback.vue

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions appointment-frontend/src/components/feedback/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Feedback from './Feedback.vue'

export {
Feedback
}
36 changes: 36 additions & 0 deletions appointment-frontend/src/models/feedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export interface FeedbackModel{
feedbackType: string,
feedbackHeader:string,
feedbackMessage:string,
name: string,
email: string,
phone: string,
responseRequired: boolean
}

export interface FeedbackRequestObject{
variables: FeedbackRequestItem
}

export interface FeedbackRequestItem {
engagement: FeedbackRequestKV,
citizen_comments:FeedbackRequestKV,
service_channel:FeedbackRequestKV,
response: FeedbackRequestKV,
citizen_name: FeedbackRequestKV,
citizen_contact: FeedbackRequestKV,
entity_key: FeedbackRequestKV,
service_date:FeedbackRequestKV,
submit_date_time:FeedbackRequestKV
}

export interface FeedbackResponseObject{
response_code: number
}

export interface FeedbackRequestKV{
value?: string,
type?:string
}


11 changes: 11 additions & 0 deletions appointment-frontend/src/services/feedback.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Axios, { AxiosResponse } from 'axios'
import { FeedbackRequestObject, FeedbackResponseObject } from '@/models/feedback'
import ConfigHelper from '@/utils/config-helper'
import { addAxiosInterceptors } from '@/utils/interceptors'
const axios = addAxiosInterceptors(Axios.create())

export default class FeedbackService {
public static async submitFeedback (feedbackBody: FeedbackRequestObject): Promise<AxiosResponse<any>> {
return axios.post(`${ConfigHelper.getFeedbackURL()}/feedback`, feedbackBody)
}
}
8 changes: 8 additions & 0 deletions appointment-frontend/src/store/modules/appointment.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Action, Module, Mutation, VuexModule } from 'vuex-module-decorators'
import { FeedbackRequestObject, FeedbackResponseObject } from '@/models/feedback'
import { Appointment } from '@/models/appointment'
import AppointmentService from '@/services/appointment.services'
import CommonUtils from '@/utils/common-util'
import FeedbackService from '@/services/feedback.service'
import OfficeService from '@/services/office.services'

@Module({
Expand Down Expand Up @@ -57,4 +59,10 @@ export default class AppointmentModule extends VuexModule {
const response = await AppointmentService.deleteAppointment(appointmentId)
return response || {}
}

@Action({ rawError: true })
public async submitFeedback (feedbackRequest: FeedbackRequestObject) {
const response = await FeedbackService.submitFeedback(feedbackRequest)
return response || {}
}
}
3 changes: 3 additions & 0 deletions appointment-frontend/src/utils/config-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export default class ConfigHelper {
return ConfigHelper.getValue('VUE_APP_ROOT_API')
// return process.env.VUE_APP_ROOT_API
}
static getFeedbackURL () {
return ConfigHelper.getValue('VUE_APP_FEEDBACK_API')
}

static getValue (key: String) {
// @ts-ignore
Expand Down
Empty file added feedback-api/.dockerignore
Empty file.
1 change: 1 addition & 0 deletions feedback-api/.s2i/environment
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
APP_CONFIG=gunicorn_config.py
45 changes: 45 additions & 0 deletions feedback-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
FROM python:3.8.5-buster
#FROM python:.6-stretch

#RUN echo "deb http://ftp.debian.org/debian stretch main contrib" > /etc/apt/sources.list

# todo: Revert this entire pull request when libcairo2 >= 1.14.2 is available from the debian
# jessie repo. This is a temporary fix for https://github.com/Kozea/WeasyPrint/issues/233

# reconfigure Debian to allow installs from both stretch (testing) repo and jessie (stable) repo
# install all the dependencies except libcairo2 from jessie, then install libcairo2 from stretch

#RUN apt-get -y update \
# && apt-get install -y \
# fonts-font-awesome \
# libffi-dev \
# libgdk-pixbuf2.0-0 \
# python-dev \
# python-lxml \
# shared-mime-info \
# && apt-get install -y ttf-mscorefonts-installer \
# libpango1.0-0 \
# libcairo2 \
# libpangocairo-1.0-0 \
# && apt-get -y clean




RUN apt-get -y update && apt-get install -y build-essential python3-dev python3-pip python3-setuptools python3-wheel python3-cffi libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info


COPY . /app
WORKDIR /app

RUN python3 -m pip install -r requirements.txt
RUN python3 setup.py install


EXPOSE 5001

ENV NUM_WORKERS=3
ENV TIMEOUT=120

#CMD ["gunicorn", "--bind", "0.0.0.0:5001", "--timeout", "$TIMEOUT", "--workers", "$NUM_WORKERS", "wsgi:app"]
CMD gunicorn --bind 0.0.0.0:5001 --timeout $TIMEOUT --workers $NUM_WORKERS wsgi:application
13 changes: 13 additions & 0 deletions feedback-api/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright © 2018 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.
7 changes: 7 additions & 0 deletions feedback-api/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include requirements/prod.txt
include config.py
include logging.conf
include LICENSE
include README.md
include src/api/static/images/*.png
include src/api/static/images/*.jpg
90 changes: 90 additions & 0 deletions feedback-api/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
.PHONY: license
.PHONY: setup
.PHONY: ci cd
.PHONY: run

MKFILE_PATH:=$(abspath $(lastword $(MAKEFILE_LIST)))
CURRENT_ABS_DIR:=$(patsubst %/,%,$(dir $(MKFILE_PATH)))

PROJECT_NAME:=pay_api

#################################################################################
# COMMANDS -- Setup #
#################################################################################
setup: install install-dev ## Setup the project

clean: clean-build clean-pyc clean-test ## Clean the project
rm -rf venv/

clean-build: ## Clean build files
rm -fr build/
rm -fr dist/
rm -fr .eggs/
find . -name '*.egg-info' -exec rm -fr {} +
find . -name '*.egg' -exec rm -fr {} +

clean-pyc: ## Clean cache files
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
find . -name '__pycache__' -exec rm -fr {} +

clean-test: ## clean test files
find . -name '.pytest_cache' -exec rm -fr {} +
rm -fr .tox/
rm -f .coverage
rm -fr htmlcov/

install: clean ## Install python virtrual environment
test -f venv/bin/activate || python3 -m venv $(CURRENT_ABS_DIR)/venv ;\
. venv/bin/activate ;\
pip install --upgrade pip ;\
pip install-Ur requirements.txt ;\
touch venv/bin/activate # update so it's as new as requirements/prod.txt

install-dev: ## Install local application
. venv/bin/activate && pip install -e .

#################################################################################
# COMMANDS - CI #
#################################################################################
ci: lint flake8 test ## CI flow

lint: ## Linting with pylint
. venv/bin/activate && pylint --rcfile=setup.cfg src/$(PROJECT_NAME)

flake8: ## Linting with flake8
. venv/bin/activate && flake8 src/$(PROJECT_NAME) tests

test: ## Unit testing
. venv/bin/activate && pytest

mac-cov: test ## Run the coverage report and display in a browser window (mac)
@open -a "Google Chrome" htmlcov/index.html

#################################################################################
# COMMANDS - CD #
#################################################################################
cd: build ## CD flow

build: ## Build the docker container
docker build -t $(PROJECT_NAME) .

build-nc: ## Build the docker container without caching
docker build --no-cache -t $(PROJECT_NAME) .

#################################################################################
# COMMANDS - Local #
#################################################################################
run: ## Run the project in local
. venv/bin/activate && python -m flask run -p 5000

#################################################################################
# Self Documenting Commands #
#################################################################################
.PHONY: help

.DEFAULT_GOAL := help

help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
5 changes: 5 additions & 0 deletions feedback-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Feedback API

Service BC Feedback API.

78 changes: 78 additions & 0 deletions feedback-api/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# 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.
"""All of the configuration for the service is captured here. All items are loaded, or have Constants defined here that are loaded into the Flask configuration. All modules and lookups get their configuration from the Flask config, rather than reading environment variables directly or by accessing this configuration directly.
"""

import os
import sys

from dotenv import find_dotenv, load_dotenv

# this will load all the envars from a .env file located in the project root (api)
load_dotenv(find_dotenv())

CONFIGURATION = {
'development': 'config.DevConfig',
'testing': 'config.TestConfig',
'production': 'config.ProdConfig',
'default': 'config.ProdConfig'
}


def get_named_config(config_name: str = 'production'):
"""Return the configuration object based on the name

:raise: KeyError: if an unknown configuration is requested
"""
if config_name in ['production', 'staging', 'default']:
config = ProdConfig()
elif config_name == 'testing':
config = TestConfig()
elif config_name == 'development':
config = DevConfig()
else:
raise KeyError(f"Unknown configuration '{config_name}'")
return config


class _Config(object): # pylint: disable=too-few-public-methods
"""Base class configuration that should set reasonable defaults for all the other configurations. """
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

FEEDBACK_CAMUNDA_URL = os.getenv('FEEDBACK_CAMUNDA_URL')
FEEDBACK_AUTH_URL = os.getenv('FEEDBACK_AUTH_URL')
FEEDBACK_AUTH_CLIENT_ID = os.getenv('FEEDBACK_AUTH_CLIENT_ID')
FEEDBACK_AUTH_CLIENT_SECRET = os.getenv('FEEDBACK_AUTH_CLIENT_SECRET')

TESTING = False
DEBUG = True


class DevConfig(_Config): # pylint: disable=too-few-public-methods
TESTING = False
DEBUG = True


class TestConfig(_Config): # pylint: disable=too-few-public-methods
"""In support of testing only used by the py.test suite."""

DEBUG = True
TESTING = True


class ProdConfig(_Config): # pylint: disable=too-few-public-methods
"""Production environment configuration."""

TESTING = False
DEBUG = False
5 changes: 5 additions & 0 deletions feedback-api/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

echo "Waiting for postgres..."

gunicorn -b 0.0.0.0:5000 wsgi:application
25 changes: 25 additions & 0 deletions feedback-api/gunicorn_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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.
"""The configuration for gunicorn, which picks up the
runtime options from environment variables
"""

import os


workers = int(os.environ.get('GUNICORN_PROCESSES', '1')) # pylint: disable=invalid-name
threads = int(os.environ.get('GUNICORN_THREADS', '1')) # pylint: disable=invalid-name

forwarded_allow_ips = '*' # pylint: disable=invalid-name
secure_scheme_headers = {'X-Forwarded-Proto': 'https'} # pylint: disable=invalid-name
Loading