-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Setup routing, queries, and permissions for /:flow/feeback
#3158
Changes from all commits
418cd82
d7d08eb
386c755
8fbe1d6
7f48039
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import Box from "@mui/material/Box"; | ||
import Button from "@mui/material/Button"; | ||
import gql from "graphql-tag"; | ||
import { client } from "lib/graphql"; | ||
import React from "react"; | ||
import { Feedback } from "routes/feedback"; | ||
|
||
interface Props { | ||
feedback: Feedback[]; | ||
} | ||
|
||
const GET_FEEDBACK_BY_ID_QUERY = gql` | ||
query GetFeedbackById($feedbackId: Int!) { | ||
feedback: feedback_summary(where: { feedback_id: { _eq: $feedbackId } }) { | ||
address | ||
createdAt: created_at | ||
device | ||
feedbackId: feedback_id | ||
feedbackType: feedback_type | ||
helpDefinition: help_definition | ||
helpSources: help_sources | ||
helpText: help_text | ||
intersectingConstraints: intersecting_constraints | ||
nodeData: node_data | ||
nodeId: node_id | ||
nodeText: node_text | ||
nodeTitle: node_title | ||
nodeType: node_type | ||
projectType: project_type | ||
serviceSlug: service_slug | ||
teamSlug: team_slug | ||
status | ||
uprn | ||
userComment: user_comment | ||
userContext: user_context | ||
} | ||
} | ||
`; | ||
|
||
const getDetailedFeedback = async (feedbackId: number) => { | ||
const { | ||
data: { | ||
feedback: [detailedFeedback], | ||
}, | ||
} = await client.query({ | ||
query: GET_FEEDBACK_BY_ID_QUERY, | ||
variables: { feedbackId }, | ||
}); | ||
console.log(detailedFeedback); | ||
}; | ||
|
||
export const FeedbackPage: React.FC<Props> = ({ feedback }) => { | ||
return ( | ||
<Box sx={{ fontSize: 12, overflowY: "auto" }}> | ||
{feedback.map((item) => ( | ||
<React.Fragment key={item.id}> | ||
<Box component="pre">{JSON.stringify(item, null, 4)}</Box> | ||
<Button onClick={() => getDetailedFeedback(item.id)}> | ||
Log out detailed info | ||
</Button> | ||
</React.Fragment> | ||
))} | ||
</Box> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { ComponentType } from "@opensystemslab/planx-core/types"; | ||
import { FeedbackCategory } from "components/Feedback"; | ||
import { Sentiment } from "components/Feedback/MoreInfoFeedback"; | ||
import gql from "graphql-tag"; | ||
import { compose, mount, NotFoundError, route, withData } from "navi"; | ||
import { FeedbackPage } from "pages/FlowEditor/components/Flow/FeedbackPage"; | ||
import { useStore } from "pages/FlowEditor/lib/store"; | ||
import React from "react"; | ||
|
||
import { client } from "../lib/graphql"; | ||
import { makeTitle } from "./utils"; | ||
|
||
type FeedbackType = Sentiment & FeedbackCategory; | ||
|
||
export interface Feedback { | ||
id: number; | ||
type: FeedbackType; | ||
nodeTitle: string | null; | ||
nodeType: keyof typeof ComponentType | null; | ||
userComment: string | null; | ||
userContext: string | null; | ||
createdAt: string; | ||
} | ||
|
||
const feedbackRoutes = compose( | ||
withData((req) => ({ | ||
mountpath: req.mountpath, | ||
})), | ||
|
||
mount({ | ||
"/": route(async (req) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's the |
||
const { team: teamSlug, flow: flowSlug } = req.params; | ||
|
||
const isAuthorised = useStore.getState().canUserEditTeam(teamSlug); | ||
if (!isAuthorised) | ||
throw new NotFoundError( | ||
`User does not have access to ${req.originalUrl}`, | ||
); | ||
|
||
const { | ||
data: { feedback }, | ||
} = await client.query<{ feedback: Feedback[] }>({ | ||
query: gql` | ||
query GetFeebackForFlow($teamSlug: String!, $flowSlug: String!) { | ||
feedback: feedback_summary( | ||
order_by: { created_at: asc } | ||
where: { | ||
team_slug: { _eq: $teamSlug } | ||
service_slug: { _eq: $flowSlug } | ||
} | ||
) { | ||
id: feedback_id | ||
type: feedback_type | ||
nodeTitle: node_title | ||
nodeType: node_type | ||
userComment: user_comment | ||
userContext: user_context | ||
createdAt: created_at | ||
} | ||
} | ||
`, | ||
variables: { teamSlug, flowSlug }, | ||
}); | ||
|
||
return { | ||
title: makeTitle("Flow Feedback"), | ||
view: <FeedbackPage feedback={feedback} />, | ||
}; | ||
}), | ||
}), | ||
); | ||
|
||
export default feedbackRoutes; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -268,6 +268,76 @@ | |
- table: | ||
name: feedback_summary | ||
schema: public | ||
object_relationships: | ||
- name: team | ||
using: | ||
manual_configuration: | ||
column_mapping: | ||
team_slug: slug | ||
insertion_order: null | ||
remote_table: | ||
name: teams | ||
schema: public | ||
Comment on lines
+271
to
+280
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This adds a relationship between This is required to correctly scope permissions - teamEditors can only access feedback for their own teams, platformAdmins can access everything. |
||
select_permissions: | ||
- role: platformAdmin | ||
permission: | ||
columns: | ||
- feedback_id | ||
- device | ||
- node_data | ||
- address | ||
- feedback_type | ||
- help_definition | ||
- help_sources | ||
- help_text | ||
- intersecting_constraints | ||
- node_id | ||
- node_text | ||
- node_title | ||
- node_type | ||
- project_type | ||
- service_slug | ||
- status | ||
- team_slug | ||
- uprn | ||
- user_comment | ||
- user_context | ||
- created_at | ||
filter: {} | ||
comment: "" | ||
- role: teamEditor | ||
permission: | ||
columns: | ||
- feedback_id | ||
- device | ||
- node_data | ||
- address | ||
- feedback_type | ||
- help_definition | ||
- help_sources | ||
- help_text | ||
- intersecting_constraints | ||
- node_id | ||
- node_text | ||
- node_title | ||
- node_type | ||
- project_type | ||
- service_slug | ||
- status | ||
- team_slug | ||
- uprn | ||
- user_comment | ||
- user_context | ||
- created_at | ||
filter: | ||
team: | ||
members: | ||
_and: | ||
- user_id: | ||
_eq: x-hasura-user-id | ||
- role: | ||
_eq: teamEditor | ||
Comment on lines
+332
to
+339
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Permission model copied from |
||
comment: "" | ||
- table: | ||
name: feedback_type_enum | ||
schema: public | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
DROP VIEW "public"."feedback_summary"; | ||
|
||
CREATE OR REPLACE VIEW "public"."feedback_summary" AS | ||
SELECT | ||
fb.id AS feedback_id, | ||
t.slug AS team, | ||
f.slug AS service_slug, | ||
fb.created_at, | ||
fb.node_id, | ||
fb.device, | ||
fb.user_context, | ||
fb.user_comment, | ||
fb.feedback_type, | ||
fb.status, | ||
fb.node_type, | ||
fb.node_data, | ||
COALESCE( | ||
fb.node_data ->> 'title', | ||
fb.node_data ->> 'text', | ||
fb.node_data ->> 'flagSet' | ||
) AS node_title, | ||
fb.node_data ->> 'description' AS node_text, | ||
fb.node_data ->> 'info' AS help_text, | ||
fb.node_data ->> 'policyRef' AS help_sources, | ||
fb.node_data ->> 'howMeasured' AS help_definition, | ||
COALESCE( | ||
fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'single_line_address', | ||
fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'title' | ||
) AS address, | ||
(fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'uprn') AS uprn, | ||
(fb.user_data -> 'passport' -> 'data' ->> 'proposal.projectType') AS project_type, | ||
(fb.user_data -> 'passport' -> 'data' ->> 'property.constraints.planning') AS intersecting_constraints | ||
FROM | ||
feedback fb | ||
LEFT JOIN | ||
flows f ON f.id = fb.flow_id | ||
LEFT JOIN | ||
teams t ON t.id = fb.team_id; | ||
|
||
GRANT SELECT ON public.feedback_summary TO metabase_read_only; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
DROP VIEW "public"."feedback_summary"; | ||
|
||
CREATE OR REPLACE VIEW "public"."feedback_summary" AS | ||
SELECT | ||
fb.id AS feedback_id, | ||
t.slug AS team_slug, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies for the churn in this view recently, I've renamed |
||
f.slug AS service_slug, | ||
fb.created_at, | ||
fb.node_id, | ||
fb.device, | ||
fb.user_context, | ||
fb.user_comment, | ||
fb.feedback_type, | ||
fb.status, | ||
fb.node_type, | ||
fb.node_data, | ||
COALESCE( | ||
fb.node_data ->> 'title', | ||
fb.node_data ->> 'text', | ||
fb.node_data ->> 'flagSet' | ||
) AS node_title, | ||
fb.node_data ->> 'description' AS node_text, | ||
fb.node_data ->> 'info' AS help_text, | ||
fb.node_data ->> 'policyRef' AS help_sources, | ||
fb.node_data ->> 'howMeasured' AS help_definition, | ||
COALESCE( | ||
fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'single_line_address', | ||
fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'title' | ||
) AS address, | ||
(fb.user_data -> 'passport' -> 'data' -> '_address' ->> 'uprn') AS uprn, | ||
(fb.user_data -> 'passport' -> 'data' ->> 'proposal.projectType') AS project_type, | ||
(fb.user_data -> 'passport' -> 'data' ->> 'property.constraints.planning') AS intersecting_constraints | ||
FROM | ||
feedback fb | ||
LEFT JOIN | ||
flows f ON f.id = fb.flow_id | ||
LEFT JOIN | ||
teams t ON t.id = fb.team_id; | ||
|
||
GRANT SELECT ON public.feedback_summary TO metabase_read_only; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change was required as the
/feedback
route (in its own file) ended with a/