Skip to content

Commit

Permalink
update: update branch with upstream master branch (#1097)
Browse files Browse the repository at this point in the history
* fix: FORMS-891 vuetify traditional chinese support (#1072)

Co-authored-by: Walter Moar <[email protected]>

* fix: filter out draft submissions on the submission page search

* fix: remove boolean check for filterformSubmissionStatusCode props

* fix: urgent timeout increase to fix outage (#1084)

* Fix/urgent timeout increase (#1085)

* fix: urgent timeout increase to fix outage

* fix: database view performance (#1091)

* fix: simplification of user form access view (#1087)

* fix: database view performance (#1090)

* fix: simplification of user form access view

* fix: remove the sorting in user_form_access_vw

---------

Co-authored-by: Walter Moar <[email protected]>

* fix: FORMS-893 semver vuln and endpoint bug (#1094)

* FORMS-881 - Not allow to save drafts if form validation fails (#1048)

* fix: not allow to save drafts if form validation fails

* fix: make validation run on render for drafts. remove disable save draft button on validation fails

* update: add countdown timer to token expiration warning dialog

- add a countdown timer to the token expiration warning dialog
- wrote unit tests for the frontend changes
- added multi lang to the new components created

* feat: FORMS-882 add submissionId to exports

Co-authored-by: Walter Moar <[email protected]>

* fix: FORMS-899 revert timeout and simplify views (#1093)

* fix: FORMS-899 remove sorting in views

* fix: FORMS-899 revert frontend timeout change

---------

Co-authored-by: Walter Moar <[email protected]>

---------

Co-authored-by: bcgov-citz-ccft <[email protected]>
Co-authored-by: Walter Moar <[email protected]>
Co-authored-by: bcvesalink <[email protected]>
  • Loading branch information
4 people authored Oct 20, 2023
1 parent e14f09f commit 9210ffb
Show file tree
Hide file tree
Showing 12 changed files with 461 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default {
this.$vuetify.lang.current =
lang.keyword == 'zh'
? 'zhHans'
: lang.keyword == 'zh-TW'
: lang.keyword == 'zhTW'
? 'zhHant'
: lang.keyword;
this.setMultiLanguage(lang.keyword);
Expand Down
4 changes: 4 additions & 0 deletions app/frontend/src/components/designer/FormViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,10 @@ export default {
this.block = e;
},
formChange(e) {
// if draft check validation on render
if (this.submissionRecord.draft) {
this.$refs.chefForm.formio.checkValidity(null, true, null, false);
}
if (e.changed != undefined && !e.changed.flags.fromSubmission) {
this.formDataEntered = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This directory contains the translation files for languages that are supported
by CHEFS, but not supported by Vuetify.
176 changes: 176 additions & 0 deletions app/src/db/migrations/20231017192656_037-user-form-permissions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Having performance problems and these views seem to be a cause of it.
// 1. Remove the join of "role" in user_form_permissions_vw.
// 2. Remove the join of "role" in user_form_roles_vw.
// 3. Simplify the EXISTS SELECT in user_form_permissions_vw.
// 4. Simplify the EXISTS SELECT in user_form_roles_vw.
// 5. Remove the sorting in the user_form_access_vw.

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return Promise.resolve()
.then(() => knex.schema.dropViewIfExists('user_form_access_vw'))
.then(() => knex.schema.dropViewIfExists('user_form_permissions_vw'))
.then(() => knex.schema.dropViewIfExists('user_form_roles_vw'))
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw
AS SELECT fru."userId",
fru."formId",
array_agg(DISTINCT fru.role) AS roles
FROM form_role_user fru
GROUP BY fru."userId", fru."formId"
UNION
SELECT u2.id AS "userId",
f2.id AS "formId",
'{}'::character varying[] AS roles
FROM form_vw f2,
"user" u2
WHERE NOT EXISTS (
SELECT 1 FROM form_role_user fru2
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`)
)
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_permissions_vw
AS SELECT fru."userId",
fru."formId",
array_agg(DISTINCT p.code) AS permissions
FROM form_role_user fru
JOIN role_permission rp ON fru.role::text = rp.role::text
JOIN permission p ON rp.permission::text = p.code::text
GROUP BY fru."userId", fru."formId"
UNION
SELECT u2.id AS "userId",
f2.id AS "formId",
'{submission_create,form_read}'::character varying[] AS permissions
FROM form_vw f2,
"user" u2
WHERE NOT EXISTS (
SELECT 1 FROM form_role_user fru2
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`)
)
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw
AS SELECT r."userId",
u."idpUserId",
u.username,
u."fullName",
u."firstName",
u."lastName",
u.email,
r."formId",
f.name AS "formName",
f.labels,
u."idpCode" AS "user_idpCode",
f."identityProviders",
f."identityProviders" AS form_login_required,
f.idps,
f.active,
f."formVersionId",
f.version,
r.roles,
p.permissions,
f.published,
f."versionUpdatedAt",
f.description AS "formDescription"
FROM "user" u
JOIN user_form_roles_vw r ON u.id = r."userId"
JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId"
JOIN form_vw f ON f.id = p."formId";`)
);
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return Promise.resolve()
.then(() => knex.schema.dropViewIfExists('user_form_access_vw'))
.then(() => knex.schema.dropViewIfExists('user_form_permissions_vw'))
.then(() => knex.schema.dropViewIfExists('user_form_roles_vw'))
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw
AS SELECT fru."userId",
fru."formId",
array_agg(DISTINCT r.code) AS roles
FROM form_role_user fru
JOIN role r ON fru.role::text = r.code::text
GROUP BY fru."userId", fru."formId"
UNION
SELECT u2.id AS "userId",
f2.id AS "formId",
'{}'::character varying[] AS roles
FROM form_vw f2,
"user" u2
WHERE NOT (EXISTS ( SELECT fru2.id,
fru2.role,
fru2."formId",
fru2."userId",
fru2."createdBy",
fru2."createdAt",
fru2."updatedBy",
fru2."updatedAt"
FROM form_role_user fru2
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`)
)
.then(() =>
knex.schema.raw(`
CREATE OR REPLACE VIEW public.user_form_permissions_vw
AS SELECT fru."userId",
fru."formId",
array_agg(DISTINCT p.code) AS permissions
FROM form_role_user fru
JOIN role r ON fru.role::text = r.code::text
JOIN role_permission rp ON r.code::text = rp.role::text
JOIN permission p ON rp.permission::text = p.code::text
GROUP BY fru."userId", fru."formId"
UNION
SELECT u2.id AS "userId",
f2.id AS "formId",
'{submission_create,form_read}'::character varying[] AS permissions
FROM form_vw f2,
"user" u2
WHERE NOT (EXISTS ( SELECT fru2.id,
fru2.role,
fru2."formId",
fru2."userId",
fru2."createdBy",
fru2."createdAt",
fru2."updatedBy",
fru2."updatedAt"
FROM form_role_user fru2
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`)
)
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw
AS SELECT r."userId",
u."idpUserId",
u.username,
u."fullName",
u."firstName",
u."lastName",
u.email,
r."formId",
f.name AS "formName",
f.labels,
u."idpCode" AS "user_idpCode",
f."identityProviders",
f."identityProviders" AS form_login_required,
f.idps,
f.active,
f."formVersionId",
f.version,
r.roles,
p.permissions,
f.published,
f."versionUpdatedAt",
f.description AS "formDescription"
FROM "user" u
JOIN user_form_roles_vw r ON u.id = r."userId"
JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId"
JOIN form_vw f ON f.id = p."formId"
ORDER BY (lower(u."lastName"::text)), (lower(u."firstName"::text)), (lower(f.name::text));`)
);
};
157 changes: 157 additions & 0 deletions app/src/db/migrations/20231019153505_038-view-simplification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Having performance problems and these views seem to be a cause of it.
// 1. Remove the sorting in the public_form_access_vw.
// 2. Remove the sorting in the form_vw.

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return Promise.resolve()
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.public_form_access_vw
AS SELECT NULL::text AS "userId",
NULL::text AS "idpUserId",
'public'::text AS username,
'public'::text AS "fullName",
NULL::text AS "firstName",
NULL::text AS "lastName",
NULL::text AS email,
f.id AS "formId",
f.name AS "formName",
f.labels,
f."identityProviders",
f.idps,
f.active,
f."formVersionId",
f.version,
'{}'::character varying[] AS roles,
'{submission_create,form_read}'::character varying[] AS permissions
FROM form_vw f
WHERE 'public'::text = ANY (f.idps::text[])`)
)
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.form_vw
AS SELECT DISTINCT ON ((lower(f.name::text)), fv.version, f.id) f.id,
f.name,
f.active,
f.description,
f.labels,
f."createdAt",
f."createdBy",
f."updatedAt",
f."updatedBy",
fv.id AS "formVersionId",
fv.version,
CASE
WHEN count(fip.code) = 0 THEN '{}'::character varying[]
ELSE array_agg(DISTINCT fip.code)
END AS "identityProviders",
CASE
WHEN count(ip.idp) = 0 THEN '{}'::character varying[]
ELSE array_agg(DISTINCT ip.idp)
END AS idps,
fv.published,
fv."updatedAt" AS "versionUpdatedAt",
f."allowSubmitterToUploadFile"
FROM form f
LEFT JOIN LATERAL ( SELECT v.id,
v."formId",
v.version,
v.schema,
v."createdBy",
v."createdAt",
v."updatedBy",
v."updatedAt",
v.published
FROM form_version v
WHERE v."formId" = f.id
ORDER BY (
CASE
WHEN v.published THEN 1
ELSE 0
END) DESC, v.version DESC
LIMIT 1) fv ON true
LEFT JOIN form_identity_provider fip ON f.id = fip."formId"
LEFT JOIN identity_provider ip ON fip.code::text = ip.code::text
GROUP BY f.id, f.name, f.active, f.description, f.labels, f."createdAt", f."createdBy", f."updatedAt", f."updatedBy", fv.id, fv.version, fv.published, fv."updatedAt"`)
);
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return Promise.resolve()
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.form_vw
AS SELECT DISTINCT ON ((lower(f.name::text)), fv.version, f.id) f.id,
f.name,
f.active,
f.description,
f.labels,
f."createdAt",
f."createdBy",
f."updatedAt",
f."updatedBy",
fv.id AS "formVersionId",
fv.version,
CASE
WHEN count(fip.code) = 0 THEN '{}'::character varying[]
ELSE array_agg(DISTINCT fip.code)
END AS "identityProviders",
CASE
WHEN count(ip.idp) = 0 THEN '{}'::character varying[]
ELSE array_agg(DISTINCT ip.idp)
END AS idps,
fv.published,
fv."updatedAt" AS "versionUpdatedAt",
f."allowSubmitterToUploadFile"
FROM form f
LEFT JOIN LATERAL ( SELECT v.id,
v."formId",
v.version,
v.schema,
v."createdBy",
v."createdAt",
v."updatedBy",
v."updatedAt",
v.published
FROM form_version v
WHERE v."formId" = f.id
ORDER BY (
CASE
WHEN v.published THEN 1
ELSE 0
END) DESC, v.version DESC
LIMIT 1) fv ON true
LEFT JOIN form_identity_provider fip ON f.id = fip."formId"
LEFT JOIN identity_provider ip ON fip.code::text = ip.code::text
GROUP BY f.id, f.name, f.active, f.description, f.labels, f."createdAt", f."createdBy", f."updatedAt", f."updatedBy", fv.id, fv.version, fv.published, fv."updatedAt"
ORDER BY (lower(f.name::text)), fv.version DESC, f.id;`)
)
.then(() =>
knex.schema.raw(`CREATE OR REPLACE VIEW public.public_form_access_vw
AS SELECT NULL::text AS "userId",
NULL::text AS "idpUserId",
'public'::text AS username,
'public'::text AS "fullName",
NULL::text AS "firstName",
NULL::text AS "lastName",
NULL::text AS email,
f.id AS "formId",
f.name AS "formName",
f.labels,
f."identityProviders",
f.idps,
f.active,
f."formVersionId",
f.version,
'{}'::character varying[] AS roles,
'{submission_create,form_read}'::character varying[] AS permissions
FROM form_vw f
WHERE 'public'::text = ANY (f.idps::text[])
ORDER BY (lower(f.name::text));`)
);
};
2 changes: 1 addition & 1 deletion app/src/forms/form/exportService.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ const service = {

_submissionsColumns: (form, params) => {
// Custom columns not defined - return default column selection behavior
let columns = ['confirmationId', 'formName', 'version', 'createdAt', 'fullName', 'username', 'email'];
let columns = ['submissionId', 'confirmationId', 'formName', 'version', 'createdAt', 'fullName', 'username', 'email'];
// if form has 'status updates' enabled in the form settings include these in export
if (form.enableStatusUpdates) {
columns = columns.concat(['status', 'assignee', 'assigneeEmail']);
Expand Down
Loading

0 comments on commit 9210ffb

Please sign in to comment.