From 2adec1bc344137ba2383b62820c70c30542658ec Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 18 Apr 2018 13:13:41 -0600 Subject: [PATCH 01/47] added deletion graph endpoints --- graph/mutators/user.js | 5 +- perms/constants/mutation.js | 2 +- perms/reducers/mutation.js | 1 + plugin-api/beta/server/getReactionConfig.js | 15 +--- plugins/talk-plugin-profile-data/package.json | 1 + .../server/connect.js | 88 ++++++++++++++++++- .../talk-plugin-profile-data/server/errors.js | 27 +++++- .../server/mutators.js | 64 ++++++++++++-- .../server/resolvers.js | 18 ++++ .../server/typeDefs.graphql | 38 ++++++++ 10 files changed, 235 insertions(+), 24 deletions(-) diff --git a/graph/mutators/user.js b/graph/mutators/user.js index 6c673111b..0343e1f2e 100644 --- a/graph/mutators/user.js +++ b/graph/mutators/user.js @@ -8,7 +8,7 @@ const { SET_USER_BAN_STATUS, SET_USER_SUSPENSION_STATUS, UPDATE_USER_ROLES, - DELETE_USER, + DELETE_OTHER_USER, } = require('../../perms/constants'); const setUserUsernameStatus = async (ctx, id, status) => { @@ -155,6 +155,7 @@ module.exports = ctx => { setUsername: () => Promise.reject(new ErrNotAuthorized()), stopIgnoringUser: () => Promise.reject(new ErrNotAuthorized()), del: () => Promise.reject(new ErrNotAuthorized()), + delSelf: () => Promise.reject(new ErrNotAuthorized()), }, }; @@ -191,7 +192,7 @@ module.exports = ctx => { setUserSuspensionStatus(ctx, id, until, message); } - if (ctx.user.can(DELETE_USER)) { + if (ctx.user.can(DELETE_OTHER_USER)) { mutators.User.del = id => delUser(ctx, id); } } diff --git a/perms/constants/mutation.js b/perms/constants/mutation.js index d2ebe73f1..dba126ceb 100644 --- a/perms/constants/mutation.js +++ b/perms/constants/mutation.js @@ -18,5 +18,5 @@ module.exports = { UPDATE_ASSET_SETTINGS: 'UPDATE_ASSET_SETTINGS', UPDATE_ASSET_STATUS: 'UPDATE_ASSET_STATUS', UPDATE_SETTINGS: 'UPDATE_SETTINGS', - DELETE_USER: 'DELETE_USER', + DELETE_OTHER_USER: 'DELETE_OTHER_USER', }; diff --git a/perms/reducers/mutation.js b/perms/reducers/mutation.js index 73ee7ef28..7e23b274b 100644 --- a/perms/reducers/mutation.js +++ b/perms/reducers/mutation.js @@ -36,6 +36,7 @@ module.exports = (user, perm) => { case types.UPDATE_USER_ROLES: case types.CREATE_TOKEN: case types.REVOKE_TOKEN: + case types.DELETE_OTHER_USER: return check(user, ['ADMIN']); default: diff --git a/plugin-api/beta/server/getReactionConfig.js b/plugin-api/beta/server/getReactionConfig.js index da075d76c..b6e0a5c1d 100644 --- a/plugin-api/beta/server/getReactionConfig.js +++ b/plugin-api/beta/server/getReactionConfig.js @@ -2,24 +2,11 @@ const { SEARCH_OTHER_USERS } = require('../../../perms/constants'); const { ErrNotFound, ErrAlreadyExists } = require('../../../errors'); const pluralize = require('pluralize'); const sc = require('snake-case'); -// const { CREATE_MONGO_INDEXES } = require('../../../config'); function getReactionConfig(reaction) { + // Ensure that the reaction is a lowercase string. reaction = reaction.toLowerCase(); - // if (CREATE_MONGO_INDEXES) { - // // Create the index on the comment model based on the reaction config. - // CommentModel.collection.createIndex( - // { - // created_at: 1, - // [`action_counts.${sc(reaction)}`]: 1, - // }, - // { - // background: true, - // } - // ); - // } - const reactionPlural = pluralize(reaction); const Reaction = reaction.charAt(0).toUpperCase() + reaction.slice(1); const REACTION = reaction.toUpperCase(); diff --git a/plugins/talk-plugin-profile-data/package.json b/plugins/talk-plugin-profile-data/package.json index ed5a29050..4329aba7e 100644 --- a/plugins/talk-plugin-profile-data/package.json +++ b/plugins/talk-plugin-profile-data/package.json @@ -7,6 +7,7 @@ "private": false, "dependencies": { "archiver": "^2.1.1", + "cron": "^1.3.0", "csv-stringify": "^3.0.0" } } diff --git a/plugins/talk-plugin-profile-data/server/connect.js b/plugins/talk-plugin-profile-data/server/connect.js index f09b2dc7b..eab76828f 100644 --- a/plugins/talk-plugin-profile-data/server/connect.js +++ b/plugins/talk-plugin-profile-data/server/connect.js @@ -1,7 +1,13 @@ const path = require('path'); +const moment = require('moment'); +const { CronJob } = require('cron'); module.exports = connectors => { - const { services: { Mailer } } = connectors; + const { + services: { Mailer }, + models: { User }, + graph: { Context }, + } = connectors; // Setup the mail templates. ['txt', 'html'].forEach(format => { @@ -11,4 +17,84 @@ module.exports = connectors => { format ); }); + + // Setup the cron job that will scan for accounts to delete every 30 minutes. + new CronJob({ + cronTime: '0,30 * * * *', + timeZone: 'America/New_York', + start: true, + runOnInit: true, + onTick: async () => { + // Create the context we'll use to perform user deletions. + const ctx = Context.forSystem(); + + // rescheduledDeletionDate is the date in the future that we'll set the + // user's account to be deleted on if this delete fails. + const rescheduledDeletionDate = moment() + .add(1, 'hours') + .toDate(); + + try { + // Keep running for each user we can pull. + while (true) { + // We'll find any user that has an account deletion date before now + // and update the user such that their deletion time is 1 hour from + // now. This will ensure that only one instance can pull the same + // user at a time, and if the delete fails, it will be retried an + // hour from now. If the deletion was successful, well, it can't be + // retried because the reference to the scheduledDeletionDate will + // get deleted along with the user. + const user = await User.findOneAndUpdate( + { + 'metadata.scheduledDeletionDate': { $lte: new Date() }, + }, + { + $set: { + 'metadata.scheduledDeletionDate': rescheduledDeletionDate, + }, + } + ); + if (!user) { + // There are no more users that meet the search criteria! We're + // done! + ctx.log.info('no more users are scheduled for deletion'); + break; + } + + ctx.log.info( + { + userID: user.id, + scheduledDeletionDate: user.metadata.scheduledDeletionDate, + }, + 'starting user delete' + ); + + // Delete the user using the existing graph call. + const { data, errors } = await ctx.graphql( + ` + mutation DeleteUser($user_id: ID!) { + delUser(id: $user_id) { + errors { + translation_key + } + } + } + `, + { user_id: user.id } + ); + if (errors) { + throw errors; + } + + if (data.errors) { + throw data.errors; + } + + ctx.log.info({ userID: user.id }, 'user was deleted successfully'); + } + } catch (err) { + ctx.log.error({ err }, 'could not handle user deletions'); + } + }, + }); }; diff --git a/plugins/talk-plugin-profile-data/server/errors.js b/plugins/talk-plugin-profile-data/server/errors.js index 6261ebe89..f205c1f6e 100644 --- a/plugins/talk-plugin-profile-data/server/errors.js +++ b/plugins/talk-plugin-profile-data/server/errors.js @@ -15,4 +15,29 @@ class ErrDownloadToken extends TalkError { } } -module.exports = { ErrDownloadToken }; +// ErrDeletionAlreadyScheduled is returned when a user requests that their +// account get deleted when their account is already scheduled for deletion. +class ErrDeletionAlreadyScheduled extends TalkError { + constructor() { + super('Deletion is already scheduled', { + translation_key: 'DELETION_ALREADY_SCHEDULED', + status: 400, + }); + } +} +// ErrDeletionNotScheduled is returned when a user requests that their +// account deletion to be canceled when it was not scheduled for deletion. +class ErrDeletionNotScheduled extends TalkError { + constructor() { + super('Deletion was not scheduled', { + translation_key: 'DELETION_NOT_SCHEDULED', + status: 400, + }); + } +} + +module.exports = { + ErrDownloadToken, + ErrDeletionAlreadyScheduled, + ErrDeletionNotScheduled, +}; diff --git a/plugins/talk-plugin-profile-data/server/mutators.js b/plugins/talk-plugin-profile-data/server/mutators.js index 5a897a2e1..dafc7dc42 100644 --- a/plugins/talk-plugin-profile-data/server/mutators.js +++ b/plugins/talk-plugin-profile-data/server/mutators.js @@ -1,6 +1,12 @@ +const { get } = require('lodash'); const moment = require('moment'); const uuid = require('uuid/v4'); const { DOWNLOAD_LINK_SUBJECT } = require('./constants'); +const { + ErrDeletionAlreadyScheduled, + ErrDeletionNotScheduled, +} = require('./errors'); +const { ErrNotAuthorized } = require('errors'); async function sendDownloadLink({ user, @@ -66,8 +72,56 @@ async function sendDownloadLink({ ); } -module.exports = ctx => ({ - User: { - requestDownloadLink: () => sendDownloadLink(ctx), - }, -}); +// requestDeletion will schedule the current user to have their account deleted +// by setting the `scheduledDeletionDate` on the user 12 hours from now. +async function requestDeletion({ user, connectors: { models: { User } } }) { + // Ensure the user doesn't already have a deletion scheduled. + if (get(user, 'metadata.scheduledDeletionDate')) { + throw new ErrDeletionAlreadyScheduled(); + } + + // Get the date in the future 12 hours from now. + const scheduledDeletionDate = moment() + .add(12, 'hours') + .toDate(); + + // Amend the scheduledDeletionDate on the user. + await User.update( + { id: user.id }, + { $set: { 'metadata.scheduledDeletionDate': scheduledDeletionDate } } + ); + + return scheduledDeletionDate; +} + +// cancelDeletion will unset the scheduled deletion date on the user account +// that is used to indicate that the user was scheduled for deletion. +async function cancelDeletion({ user, connectors: { models: { User } } }) { + // Ensure the user has a deletion scheduled. + if (!get(user, 'metadata.scheduledDeletionDate', null)) { + throw new ErrDeletionNotScheduled(); + } + + // Amend the scheduledDeletionDate on the user. + await User.update( + { id: user.id }, + { $unset: { 'metadata.scheduledDeletionDate': 1 } } + ); +} + +module.exports = ctx => + ctx.user + ? { + User: { + requestDownloadLink: () => sendDownloadLink(ctx), + requestDeletion: () => requestDeletion(ctx), + cancelDeletion: () => cancelDeletion(ctx), + }, + } + : { + User: { + requestDownloadLink: () => Promise.reject(new ErrNotAuthorized()), + requestDeletion: () => Promise.reject(new ErrNotAuthorized()), + cancelDeletion: () => Promise.reject(new ErrNotAuthorized()), + }, + }; diff --git a/plugins/talk-plugin-profile-data/server/resolvers.js b/plugins/talk-plugin-profile-data/server/resolvers.js index 691907f8c..a90c617e2 100644 --- a/plugins/talk-plugin-profile-data/server/resolvers.js +++ b/plugins/talk-plugin-profile-data/server/resolvers.js @@ -5,6 +5,12 @@ module.exports = { requestDownloadLink: async (_, args, { mutators: { User } }) => { await User.requestDownloadLink(); }, + requestAccountDeletion: async (_, args, { mutators: { User } }) => ({ + scheduledDeletionDate: await User.requestDeletion(), + }), + cancelAccountDeletion: async (_, args, { mutators: { User } }) => { + await User.cancelDeletion(); + }, }, User: { lastAccountDownload: (user, args, { user: currentUser }) => { @@ -16,5 +22,17 @@ module.exports = { return get(user, 'metadata.lastAccountDownload', null); }, + scheduledDeletionDate: (user, args, { user: currentUser }) => { + // If the current user is not the requesting user, and the user is not + // an admin or a moderator, return nothing. + if ( + user.id !== currentUser.id && + !['ADMIN', 'MODERATOR'].includes(user.role) + ) { + return null; + } + + return get(user, 'metadata.scheduledDeletionDate', null); + }, }, }; diff --git a/plugins/talk-plugin-profile-data/server/typeDefs.graphql b/plugins/talk-plugin-profile-data/server/typeDefs.graphql index 0029111c3..c785fb2cc 100644 --- a/plugins/talk-plugin-profile-data/server/typeDefs.graphql +++ b/plugins/talk-plugin-profile-data/server/typeDefs.graphql @@ -3,17 +3,55 @@ type User { # lastAccountDownload is the date that the user last requested a comment # download. lastAccountDownload: Date + + # scheduledDeletionDate is the data for which the user account will be deleted + # after. The account may be deleted up to half an hour after this date because + # the job responsible for deleting the scheduled account will only run once + # every half hour. + scheduledDeletionDate: Date } +# RequestDownloadLinkResponse contains the account download errors relating to +# the request for an account download. type RequestDownloadLinkResponse implements Response { # An array of errors relating to the mutation that occurred. errors: [UserError!] } +# RequestAccountDeletionResponse contains the account deletion schedule errors +# relating to schedulding an account for deletion. +type RequestAccountDeletionResponse implements Response { + + # scheduledDeletionDate is the data for which the user account will be deleted + # after. The account may be deleted up to half an hour after this date because + # the job responsible for deleting the scheduled account will only run once + # every half hour. + scheduledDeletionDate: Date + + # An array of errors relating to the mutation that occurred. + errors: [UserError!] +} + +# CancelAccountDeletionResponse contains the account deletion errors relating to +# canceling an account deletion that was scheduled. +type CancelAccountDeletionResponse implements Response { + + # An array of errors relating to the mutation that occurred. + errors: [UserError!] +} + type RootMutation { # requestDownloadLink will request a download link be sent to the primary # users email address. requestDownloadLink: RequestDownloadLinkResponse + + # requestAccountDeletion requests that the current account get deleted. The + # mutation will return the date that the account is scheduled to be deleted. + requestAccountDeletion: RequestAccountDeletionResponse + + # cancelAccountDeletion will cancel a pending account deletion that was + # previously scheduled. + cancelAccountDeletion: CancelAccountDeletionResponse } From 8e34fd1925fe23c745de480c773aa4bdab11af80 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 18 Apr 2018 17:22:39 -0600 Subject: [PATCH 02/47] implemented tombstoning --- .../src/tabs/stream/components/Comment.js | 11 +++- .../stream/components/CommentTombstone.js | 2 + client/coral-framework/utils/index.js | 8 +++ graph/mutators/user.js | 53 +++++++++++-------- graph/resolvers/comment.js | 6 ++- graph/typeDefs.graphql | 5 +- locales/en.yml | 1 + models/schema/comment.js | 8 ++- perms/constants/query.js | 1 + perms/reducers/query.js | 1 + services/migration/helpers.js | 10 +++- 11 files changed, 75 insertions(+), 31 deletions(-) diff --git a/client/coral-embed-stream/src/tabs/stream/components/Comment.js b/client/coral-embed-stream/src/tabs/stream/components/Comment.js index 5df119fbc..e60756f39 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/Comment.js +++ b/client/coral-embed-stream/src/tabs/stream/components/Comment.js @@ -27,6 +27,7 @@ import { getActionSummary, iPerformedThisAction, isCommentActive, + isCommentDeleted, getShallowChanges, } from 'coral-framework/utils'; import t from 'coral-framework/services/i18n'; @@ -742,8 +743,14 @@ export default class Comment extends React.Component { return (
- {this.renderComment()} - {activeReplyBox === comment.id && this.renderReplyBox()} + {isCommentDeleted(comment) ? ( + + ) : ( +
+ {this.renderComment()} + {activeReplyBox === comment.id && this.renderReplyBox()} +
+ )} {this.renderRepliesContainer()}
); diff --git a/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js b/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js index a10369850..95184dffd 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js +++ b/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js @@ -13,6 +13,8 @@ class CommentTombstone extends React.Component { return t('framework.comment_is_ignored'); case 'reject': return t('framework.comment_is_rejected'); + case 'deleted': + return t('framework.comment_is_deleted'); default: return t('framework.comment_is_hidden'); } diff --git a/client/coral-framework/utils/index.js b/client/coral-framework/utils/index.js index 66792b9b3..f69e83bdc 100644 --- a/client/coral-framework/utils/index.js +++ b/client/coral-framework/utils/index.js @@ -1,6 +1,7 @@ import { gql } from 'react-apollo'; import t from 'coral-framework/services/i18n'; import union from 'lodash/union'; +import get from 'lodash/get'; import { capitalize } from 'coral-framework/helpers/strings'; import assignWith from 'lodash/assignWith'; import mapValues from 'lodash/mapValues'; @@ -221,6 +222,13 @@ export function isCommentActive(commentStatus) { return ['NONE', 'ACCEPTED'].indexOf(commentStatus) >= 0; } +export function isCommentDeleted(comment) { + return ( + get(comment, 'body', null) === null || + get(comment, 'deleted_at', null) !== null + ); +} + export function getShallowChanges(a, b) { return union(Object.keys(a), Object.keys(b)).filter(key => a[key] !== b[key]); } diff --git a/graph/mutators/user.js b/graph/mutators/user.js index 0343e1f2e..f5bf3c930 100644 --- a/graph/mutators/user.js +++ b/graph/mutators/user.js @@ -92,7 +92,7 @@ const delUser = async (ctx, id) => { updateBatchSize: 10000, }); - // Remove all actions against comments. + // Remove all actions against this users comments. await transformSingleWithCursor( Action.collection.find({ user_id: user.id, item_type: 'COMMENTS' }), actionDecrTransformer, @@ -111,34 +111,41 @@ const delUser = async (ctx, id) => { .setOptions({ multi: true }) .remove(); - // Removes all the user's reply counts on each of the comments that they - // have commented on. + // For each comment that the user has authored, purge the comment data from it + // and unset their id from those comments. await transformSingleWithCursor( - Comment.collection.aggregate([ - { $match: { author_id: user.id } }, - { - $group: { - _id: '$parent_id', - count: { $sum: 1 }, - }, - }, - ]), - ({ _id: parent_id, count }) => ({ - query: { id: parent_id }, - update: { - $inc: { - reply_count: -1 * count, - }, + Comment.collection.find({ author_id: user.id }), + ({ + id, + asset_id, + status, + parent_id, + reply_count, + created_at, + updated_at, + }) => ({ + query: { id }, + replace: { + id, + body: null, + body_history: [], + asset_id, + author_id: null, + status_history: [], + status, + parent_id, + reply_count, + action_counts: {}, + tags: [], + metadata: {}, + deleted_at: new Date(), + created_at, + updated_at, }, }), Comment ); - // Remove all the user's comments. - await Comment.where({ author_id: user.id }) - .setOptions({ multi: true }) - .remove(); - // Remove the user. await user.remove(); }; diff --git a/graph/resolvers/comment.js b/graph/resolvers/comment.js index 064835f8f..e562c062c 100644 --- a/graph/resolvers/comment.js +++ b/graph/resolvers/comment.js @@ -4,6 +4,7 @@ const { SEARCH_ACTIONS, SEARCH_COMMENT_STATUS_HISTORY, VIEW_BODY_HISTORY, + VIEW_COMMENT_DELETED_AT, } = require('../../perms/constants'); const { decorateWithTags, @@ -23,7 +24,9 @@ const Comment = { return Comments.get.load(parent_id); }, user({ author_id }, _, { loaders: { Users } }) { - return Users.getByID.load(author_id); + if (author_id) { + return Users.getByID.load(author_id); + } }, replies({ id, asset_id, reply_count }, { query }, { loaders: { Comments } }) { // Don't bother looking up replies if there aren't any there! @@ -83,6 +86,7 @@ decorateWithTags(Comment); decorateWithPermissionCheck(Comment, { actions: [SEARCH_ACTIONS], status_history: [SEARCH_COMMENT_STATUS_HISTORY], + deleted_at: [VIEW_COMMENT_DELETED_AT], }); // Protect privileged fields. diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index f94322344..9a03e2729 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -503,7 +503,7 @@ type Comment { id: ID! # The actual comment data. - body: String! + body: String # The body history of the comment. Requires the `ADMIN` or `MODERATOR` role or # the author. @@ -537,6 +537,9 @@ type Comment { # The status history of the comment. Requires the `ADMIN` or `MODERATOR` role. status_history: [CommentStatusHistory!] + # The date that the comment was deleted at if it was. + deleted_at: Date + # The time when the comment was created created_at: Date! diff --git a/locales/en.yml b/locales/en.yml index 50845b96f..f4c477710 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -258,6 +258,7 @@ en: comment: comment comment_is_ignored: "This comment is hidden because you ignored this user." comment_is_rejected: "You have rejected this comment." + comment_is_deleted: "This comment was deleted." comment_is_hidden: "This comment is not available." comments: comments configure_stream: "Configure" diff --git a/models/schema/comment.js b/models/schema/comment.js index 6ef5434d5..985f5c399 100644 --- a/models/schema/comment.js +++ b/models/schema/comment.js @@ -58,8 +58,6 @@ const Comment = new Schema( }, body: { type: String, - required: [true, 'The body is required.'], - minlength: 2, }, body_history: [BodyHistoryItemSchema], asset_id: String, @@ -89,6 +87,12 @@ const Comment = new Schema( // Tags are added by the self or by administrators. tags: [TagLinkSchema], + // deleted_at stores the date that the given comment was deleted. + deleted_at: { + type: Date, + default: null, + }, + // Additional metadata stored on the field. metadata: { default: {}, diff --git a/perms/constants/query.js b/perms/constants/query.js index 197c5d9f9..0c7f4024d 100644 --- a/perms/constants/query.js +++ b/perms/constants/query.js @@ -11,4 +11,5 @@ module.exports = { VIEW_USER_ROLE: 'VIEW_USER_ROLE', VIEW_USER_EMAIL: 'VIEW_USER_EMAIL', VIEW_BODY_HISTORY: 'VIEW_BODY_HISTORY', + VIEW_COMMENT_DELETED_AT: 'VIEW_COMMENT_DELETED_AT', }; diff --git a/perms/reducers/query.js b/perms/reducers/query.js index ed507139d..5c8b17307 100644 --- a/perms/reducers/query.js +++ b/perms/reducers/query.js @@ -14,6 +14,7 @@ module.exports = (user, perm) => { case types.VIEW_USER_ROLE: case types.VIEW_USER_EMAIL: case types.VIEW_BODY_HISTORY: + case types.VIEW_COMMENT_DELETED_AT: return check(user, ['ADMIN', 'MODERATOR']); case types.LIST_OWN_TOKENS: return check(user, ['ADMIN']); diff --git a/services/migration/helpers.js b/services/migration/helpers.js index 5eb33aadf..49acc78aa 100644 --- a/services/migration/helpers.js +++ b/services/migration/helpers.js @@ -10,8 +10,14 @@ const processUpdates = async (model, updates) => { // Create a new batch operation. const bulk = model.collection.initializeUnorderedBulkOp(); - for (const { query, update } of updates) { - bulk.find(query).updateOne(update); + for (const { query, update, replace } of updates) { + if (update) { + bulk.find(query).updateOne(update); + } else if (replace) { + bulk.find(query).replaceOne(replace); + } else { + throw new Error('invalid update object provided'); + } } // Execute the bulk update operation. From 68461308c68c1cedd3810bc6336daa9c65dd95b2 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 19 Apr 2018 13:37:14 -0600 Subject: [PATCH 03/47] pull ignored users from db --- graph/mutators/user.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/graph/mutators/user.js b/graph/mutators/user.js index f5bf3c930..68112e732 100644 --- a/graph/mutators/user.js +++ b/graph/mutators/user.js @@ -111,6 +111,15 @@ const delUser = async (ctx, id) => { .setOptions({ multi: true }) .remove(); + // Remove the user from all other user's ignore lists. + await User.update( + { ignoresUsers: user.id }, + { + $pull: { ignoresUsers: user.id }, + }, + { multi: true } + ); + // For each comment that the user has authored, purge the comment data from it // and unset their id from those comments. await transformSingleWithCursor( From 720089d3c2377ee3c84ab11a0fd1b5cb55c404d8 Mon Sep 17 00:00:00 2001 From: okbel Date: Mon, 30 Apr 2018 23:45:13 -0300 Subject: [PATCH 04/47] Initial Delete --- plugins/talk-plugin-auth/client/index.js | 2 + .../components/DeleteMyAccount.css | 13 +++++ .../components/DeleteMyAccount.js | 57 +++++++++++++++++++ .../components/DeleteMyAccountDialog.css | 0 .../components/DeleteMyAccountDialog.js | 10 ++++ 5 files changed, 82 insertions(+) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js diff --git a/plugins/talk-plugin-auth/client/index.js b/plugins/talk-plugin-auth/client/index.js index 13abce1d9..fd6843958 100644 --- a/plugins/talk-plugin-auth/client/index.js +++ b/plugins/talk-plugin-auth/client/index.js @@ -4,6 +4,7 @@ import SetUsernameDialog from './stream/containers/SetUsernameDialog'; import translations from './translations.yml'; import Login from './login/containers/Main'; import reducer from './login/reducer'; +import DeleteMyAccount from './profile-settings/components/DeleteMyAccount'; export default { reducer, @@ -11,5 +12,6 @@ export default { slots: { stream: [UserBox, SignInButton, SetUsernameDialog], login: [Login], + profileSettings: [DeleteMyAccount], }, }; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css new file mode 100644 index 000000000..2fe139d52 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css @@ -0,0 +1,13 @@ +.button { + color: #787D80; + border-radius: 2px; + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js new file mode 100644 index 000000000..4b48e15ce --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js @@ -0,0 +1,57 @@ +import React from 'react'; +import cn from 'classnames'; +import styles from './DeleteMyAccount.css'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import DeleteMyAccountDialog from './DeleteMyAccountDialog'; + +const initialState = { showDialog: false }; + +class DeleteMyAccount extends React.Component { + state = initialState; + + showDialog = () => { + this.setState({ + showDialog: true, + }); + }; + + closeDialog = () => { + this.setState({ + showDialog: false, + }); + }; + + render() { + return ( +
+ +

+ Delete My Account +

+

+ Deleting your account will permanently erase your profile and remove + all your comments from this site. +

+ +
+ ); + } +} + +export default DeleteMyAccount; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js new file mode 100644 index 000000000..2f64a3e2e --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -0,0 +1,10 @@ +import React from 'react'; +import { Dialog } from 'plugin-api/beta/client/components/ui'; + +class DeleteMyAccount extends React.Component { + render() { + return Holaa; + } +} + +export default DeleteMyAccount; From 876eb1e413d0048996388ad72d54aae52f7a482a Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 00:17:57 -0300 Subject: [PATCH 05/47] wip --- .../components/DeleteMyAccount.js | 2 +- .../components/DeleteMyAccountDialog.css | 95 +++++++++++++++++++ .../components/DeleteMyAccountDialog.js | 67 ++++++++++++- .../components/StepProgress.css | 9 ++ .../components/StepProgress.js | 17 ++++ 5 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js index 4b48e15ce..95b11ab49 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js @@ -24,7 +24,7 @@ class DeleteMyAccount extends React.Component { render() { return (
- +

i.itemIcon { + font-size: 1.3em; + } +} + + + + + +/** Step **/ + diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js index 2f64a3e2e..fd0b1e255 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -1,10 +1,69 @@ import React from 'react'; -import { Dialog } from 'plugin-api/beta/client/components/ui'; +import cn from 'classnames'; +import PropTypes from 'prop-types'; +import styles from './DeleteMyAccountDialog.css'; +import { Button, Dialog, Icon } from 'plugin-api/beta/client/components/ui'; +import StepProgress from './StepProgress'; + +const initialState = { step: 0 }; + +class DeleteMyAccountDialog extends React.Component { + state = initialState; + + goToNextStep = () => { + this.setState(state => ({ + step: state.step + 1, + })); + }; + + clear = () => { + this.setState(initialState); + }; -class DeleteMyAccount extends React.Component { render() { - return Holaa; + return ( + + + × + +

Delete My Account

+ +
+

+ You are attempting to delete your account. This means: +

+
    +
  • + + + All of your comments are removed from this site + +
  • +
  • + + + All of your comments are deleted from our database + +
  • +
  • + + + Your username and email address are removed from our system + +
  • +
+
+
+ + +
+
+ ); } } -export default DeleteMyAccount; +DeleteMyAccountDialog.propTypes = { + closeDialog: PropTypes.func.isRequired, +}; + +export default DeleteMyAccountDialog; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css new file mode 100644 index 000000000..90a8a558c --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css @@ -0,0 +1,9 @@ +.step { + &.current { + color: rgba(0, 205, 115, 0.3); + } + + &.completed { + color: #00CD73; + } +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js new file mode 100644 index 000000000..c0c2d9712 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js @@ -0,0 +1,17 @@ +import React from 'react'; +import styles from './StepProgress.css'; +import { Icon } from 'plugin-api/beta/client/components/ui'; + +class StepProgress extends React.Component { + render() { + return ( +
+ + + +
+ ); + } +} + +export default StepProgress; From 867523140c3f70a9cf2161113948f90559f1665c Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 14:09:43 -0300 Subject: [PATCH 06/47] Adding StepProgress component, and all the steps --- .../components/DeleteMyAccountDialog.css | 60 +----------------- .../components/DeleteMyAccountDialog.js | 51 ++++++---------- .../components/DeleteMyAccountFinalStep.js | 40 ++++++++++++ .../components/DeleteMyAccountStep.css | 61 +++++++++++++++++++ .../components/DeleteMyAccountStep0.js | 43 +++++++++++++ .../components/DeleteMyAccountStep1.js | 30 +++++++++ .../components/DeleteMyAccountStep2.js | 27 ++++++++ .../components/DeleteMyAccountStep3.js | 31 ++++++++++ .../components/StepProgress.css | 23 +++++++ .../components/StepProgress.js | 39 ++++++++++-- 10 files changed, 312 insertions(+), 93 deletions(-) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css index 802b63197..db44ebf6d 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css @@ -1,7 +1,7 @@ .dialog { border: none; box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); - width: 320px; + width: 380px; top: 10px; font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif; font-size: 14px; @@ -26,7 +26,7 @@ } .title { - font-size: 1.3em; + font-size: 1.2em; margin-bottom: 8px; } @@ -36,60 +36,4 @@ margin: 0; } -.button { - color: #787D80; - border-radius: 2px; - background-color: transparent; - height: 30px; - font-size: 0.9em; - line-height: normal; - - &:hover { - background-color: #eaeaea; - } - - &.cancel { - background-color: transparent; - color: #787D80; - } - - &.proceed { - background-color: #3498DB; - color: white; - } -} - -.actions { - text-align: right; -} - -.list { - padding: 0; - margin: 10px 0; - list-style: none; -} - -.item { - display: flex; - margin-bottom: 10px; - - .itemIcon { - flex-grow: 0; - } - - .text { - flex-grow: 1; - padding-left: 10px; - } - - > i.itemIcon { - font-size: 1.3em; - } -} - - - - - -/** Step **/ diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js index fd0b1e255..599816e2d 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -1,9 +1,13 @@ import React from 'react'; -import cn from 'classnames'; import PropTypes from 'prop-types'; import styles from './DeleteMyAccountDialog.css'; -import { Button, Dialog, Icon } from 'plugin-api/beta/client/components/ui'; +import { Dialog } from 'plugin-api/beta/client/components/ui'; import StepProgress from './StepProgress'; +import DeleteMyAccountStep0 from './DeleteMyAccountStep0'; +import DeleteMyAccountStep1 from './DeleteMyAccountStep1'; +import DeleteMyAccountStep2 from './DeleteMyAccountStep2'; +import DeleteMyAccountStep3 from './DeleteMyAccountStep3'; +import DeleteMyAccountFinalStep from './DeleteMyAccountFinalStep'; const initialState = { step: 0 }; @@ -21,6 +25,7 @@ class DeleteMyAccountDialog extends React.Component { }; render() { + const { step } = this.state; return ( @@ -28,35 +33,19 @@ class DeleteMyAccountDialog extends React.Component {

Delete My Account

-
-

- You are attempting to delete your account. This means: -

-
    -
  • - - - All of your comments are removed from this site - -
  • -
  • - - - All of your comments are deleted from our database - -
  • -
  • - - - Your username and email address are removed from our system - -
  • -
-
-
- - -
+ {step === 0 && ( + + )} + {step === 1 && ( + + )} + {step === 2 && ( + + )} + {step === 3 && ( + + )} + {step === 4 && }
); } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js new file mode 100644 index 000000000..004270f4d --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js @@ -0,0 +1,40 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button, Icon } from 'plugin-api/beta/client/components/ui'; +import styles from './DeleteMyAccountStep.css'; + +const DeleteMyAccountFinalStep = () => ( +
+

+ Your request has been submitted and confirmation has been sent to the + email address associated with your account. +

+ Your account is scheduled to be deleted at: + + Account Deletion Date and Time + +

+ Changed your mind? Simply sign in to your account again + before this time and click “ + Cancel Account Deletion Request. + ” +

+

+ Tell us why. Wed like to know why you chose to delete + your account. Send us feedback on our comment system by emailing. +

+
+ + + Note: You will be immediately signed out of your account. + +
+
+); + +export default DeleteMyAccountFinalStep; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css new file mode 100644 index 000000000..8984bf7ac --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css @@ -0,0 +1,61 @@ +.list { + padding: 0; + margin: 20px 0; + list-style: none; +} + +.item { + display: flex; + margin-bottom: 20px; + + .itemIcon { + flex-grow: 0; + } + + .text { + flex-grow: 1; + padding-left: 10px; + } + + > i.itemIcon { + font-size: 1.3em; + } +} + +.button { + color: #787D80; + border-radius: 2px; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } + + &.cancel { + background-color: transparent; + color: #787D80; + } + + &.proceed { + background-color: #3498DB; + color: white; + } +} + +.actions { + text-align: right; +} + +.title { + font-size: 1.2em; + margin-bottom: 8px; +} + +.description { + font-size: 1em; + line-height: 20px; + margin: 0; +} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js new file mode 100644 index 000000000..ddddf7141 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js @@ -0,0 +1,43 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button, Icon } from 'plugin-api/beta/client/components/ui'; +import styles from './DeleteMyAccountStep.css'; + +const DeleteMyAccountStep0 = () => ( +
+

+ You are attempting to delete your account. This means: +

+
    +
  • + + + All of your comments are removed from this site + +
  • +
  • + + + All of your comments are deleted from our database + +
  • +
  • + + + Your username and email address are removed from our system + +
  • +
+
+ + +
+
+); + +export default DeleteMyAccountStep0; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js new file mode 100644 index 000000000..602bb33b7 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js @@ -0,0 +1,30 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import styles from './DeleteMyAccountStep.css'; + +const DeleteMyAccountStep1 = () => ( +
+

When will my account be deleted?

+

+ Your account will be deleted 24 hours after your request has been + submitted. +

+

Can I still write comments until my account is deleted?

+

+ No. Once youve requested account deletion, you can no longer write + comments, reply to comments, or select reactions. +

+
+ + +
+
+); + +export default DeleteMyAccountStep1; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js new file mode 100644 index 000000000..7b069ca3d --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js @@ -0,0 +1,27 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import styles from './DeleteMyAccountStep.css'; + +const DeleteMyAccountStep1 = () => ( +
+

+ Before your account is deleted, we recommend you download your comment + history for your records. After your account is deleted, you will be + unable to request your comment history. +

+

To download your comment history go to:

+ My Profile Download My Comment History +
+ + +
+
+); + +export default DeleteMyAccountStep1; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js new file mode 100644 index 000000000..bf3dea674 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js @@ -0,0 +1,31 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import styles from './DeleteMyAccountStep.css'; + +const DeleteMyAccountStep1 = () => ( +
+

Are you sure you want to delete your account?

+

+ To confirm you would like to delete your account please type in the + following phrase into the text box below: +

+ +
+ + +
+
+); + +export default DeleteMyAccountStep1; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css index 90a8a558c..68fab06a9 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css @@ -1,4 +1,9 @@ .step { + color: #BBBEBF; + background-color: white; + padding: 6px; + z-index: 10; + &.current { color: rgba(0, 205, 115, 0.3); } @@ -6,4 +11,22 @@ &.completed { color: #00CD73; } +} + +.line { + position: absolute; + border: solid 2px #BBBEBF; + width: 100%; + box-sizing: border-box; + margin: 0; + padding: 0; +} + +.container { + display: flex; + position: relative; + justify-content: space-between; + align-items: center; + height: 50px; + margin: 0 20px; } \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js index c0c2d9712..e11bf46d5 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js @@ -1,17 +1,48 @@ import React from 'react'; +import cn from 'classnames'; +import PropTypes from 'prop-types'; import styles from './StepProgress.css'; import { Icon } from 'plugin-api/beta/client/components/ui'; +const CheckItem = ({ current = false, completed = false }) => ( + + + +); + +CheckItem.propTypes = { + current: PropTypes.bool.isRequired, + completed: PropTypes.bool.isRequired, +}; + +const Line = () =>
; + class StepProgress extends React.Component { render() { + const { currentStep, totalSteps } = this.props; return ( -
- - - +
+ {Array.from({ length: totalSteps }).map((_, i) => ( + + ))} +
); } } +StepProgress.propTypes = { + currentStep: PropTypes.number.isRequired, + totalSteps: PropTypes.number.isRequired, +}; + export default StepProgress; From f4cb16e56eb7bdf681f68f35c2af3a853ca1e625 Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 14:14:43 -0300 Subject: [PATCH 07/47] styles wip --- .../profile-settings/components/DeleteMyAccountStep0.js | 4 ++-- .../profile-settings/components/DeleteMyAccountStep1.js | 4 ++-- .../profile-settings/components/DeleteMyAccountStep2.js | 4 ++-- .../profile-settings/components/DeleteMyAccountStep3.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js index ddddf7141..f81d912ea 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js @@ -3,7 +3,7 @@ import cn from 'classnames'; import { Button, Icon } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep0 = () => ( +const DeleteMyAccountStep0 = props => (

You are attempting to delete your account. This means: @@ -32,7 +32,7 @@ const DeleteMyAccountStep0 = () => ( diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js index 602bb33b7..d3b399f44 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js @@ -3,7 +3,7 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep1 = () => ( +const DeleteMyAccountStep1 = props => (

When will my account be deleted?

@@ -19,7 +19,7 @@ const DeleteMyAccountStep1 = () => ( diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js index 7b069ca3d..47c89e4c1 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js @@ -3,7 +3,7 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep1 = () => ( +const DeleteMyAccountStep1 = props => (

Before your account is deleted, we recommend you download your comment @@ -16,7 +16,7 @@ const DeleteMyAccountStep1 = () => ( diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js index bf3dea674..534ea9db8 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js @@ -3,7 +3,7 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep1 = () => ( +const DeleteMyAccountStep1 = props => (

Are you sure you want to delete your account?

@@ -20,7 +20,7 @@ const DeleteMyAccountStep1 = () => ( From 3bb91f683320f706af312edb7863258c35dbdabd Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 15:43:10 -0300 Subject: [PATCH 08/47] Adding withRequestAccountDeletion, withRequestDownloadLink, withCancelAccountDeletion --- client/coral-framework/graphql/fragments.js | 5 +- client/coral-framework/graphql/mutations.js | 51 +++++++++++++++++++ .../components/DeleteMyAccountDialog.css | 4 +- .../components/DeleteMyAccountFinalStep.js | 24 ++++++--- .../components/DeleteMyAccountStep.css | 47 +++++++++++++++++ .../components/DeleteMyAccountStep1.js | 6 ++- .../components/DeleteMyAccountStep2.js | 8 ++- .../components/DeleteMyAccountStep3.js | 6 ++- 8 files changed, 134 insertions(+), 17 deletions(-) diff --git a/client/coral-framework/graphql/fragments.js b/client/coral-framework/graphql/fragments.js index a62fd6d92..f30cb1e63 100644 --- a/client/coral-framework/graphql/fragments.js +++ b/client/coral-framework/graphql/fragments.js @@ -25,6 +25,9 @@ export default { 'UnsuspendUserResponse', 'UpdateAssetSettingsResponse', 'UpdateAssetStatusResponse', - 'UpdateSettingsResponse' + 'UpdateSettingsResponse', + 'RequestAccountDeletionResponse', + 'RequestDownloadLinkResponse', + 'CancelAccountDeletionResponse' ), }; diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index bd31be630..bf412b189 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -623,6 +623,57 @@ export const withUpdateSettings = withMutation( } ); +export const withRequestAccountDeletion = withMutation( + gql` + mutation RequestAccountDeletion { + requestAccountDeletion { + ...RequestAccountDeletionResponse + } + } + `, + { + props: ({ mutate }) => ({ + requestAccountDeletion: () => { + return mutate(); + }, + }), + } +); + +export const withRequestDownloadLink = withMutation( + gql` + mutation RequestDownloadLink { + requestDownloadLink { + ...RequestDownloadLinkResponse + } + } + `, + { + props: ({ mutate }) => ({ + requestDownloadLink: () => { + return mutate(); + }, + }), + } +); + +export const withCancelAccountDeletion = withMutation( + gql` + mutation RequestDownloadLink { + cancelAccountDeletion { + ...CancelAccountDeletionResponse + } + } + `, + { + props: ({ mutate }) => ({ + cancelAccountDeletion: () => { + return mutate(); + }, + }), + } +); + export const withUpdateAssetSettings = withMutation( gql` mutation UpdateAssetSettings($id: ID!, $input: AssetSettingsInput!) { diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css index db44ebf6d..44dcad0cf 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css @@ -34,6 +34,4 @@ font-size: 1em; line-height: 20px; margin: 0; -} - - +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js index 004270f4d..22cf476e5 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js @@ -9,30 +9,40 @@ const DeleteMyAccountFinalStep = () => ( Your request has been submitted and confirmation has been sent to the email address associated with your account.

- Your account is scheduled to be deleted at: - - Account Deletion Date and Time - + +
+ + Your account is scheduled to be deleted at: + + + + Account Deletion Date and Time + +
+

Changed your mind? Simply sign in to your account again before this time and click “ Cancel Account Deletion Request.

+

Tell us why. Wed like to know why you chose to delete your account. Send us feedback on our comment system by emailing.

-
+ +
- + Note: You will be immediately signed out of your account. - +
); diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css index 8984bf7ac..98b73f376 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css @@ -43,10 +43,22 @@ background-color: #3498DB; color: white; } + + &.danger { + background-color: #FA4643; + color: white; + } } .actions { text-align: right; + padding-top: 20px; + + &.columnView { + display: flex; + flex-direction: column; + align-items: center; + } } .title { @@ -58,4 +70,39 @@ font-size: 1em; line-height: 20px; margin: 0; + margin-bottom: 15px; +} + +.box { + display: flex; + flex-direction: column; + margin-bottom: 15px; +} + +.note { + margin: 10px 0; +} + +.subTitle { + font-size: 1em; + margin-bottom: 8px; +} + +.textBox { + background-color: #F1F2F2; + border: none; + width: 100%; + padding: 15px; + box-sizing: border-box; + color: #3B4A53; + font-size: 1em; +} + +.block { + display: block; + margin-top: 2px; +} + +.step { + padding-top: 20px; } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js index d3b399f44..1d26190bc 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js @@ -5,12 +5,14 @@ import styles from './DeleteMyAccountStep.css'; const DeleteMyAccountStep1 = props => (
-

When will my account be deleted?

+

When will my account be deleted?

Your account will be deleted 24 hours after your request has been submitted.

-

Can I still write comments until my account is deleted?

+

+ Can I still write comments until my account is deleted?{' '} +

No. Once youve requested account deletion, you can no longer write comments, reply to comments, or select reactions. diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js index 47c89e4c1..3337c0b94 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js @@ -10,8 +10,12 @@ const DeleteMyAccountStep1 = props => ( history for your records. After your account is deleted, you will be unable to request your comment history.

-

To download your comment history go to:

- My Profile Download My Comment History +

+ To download your comment history go to: + + My Profile {`>`} Download My Comment History + +

+ {scheduledDeletionDate ? ( + + ) : ( + + )}
); } @@ -63,6 +98,7 @@ DeleteMyAccount.propTypes = { requestAccountDeletion: PropTypes.func.isRequired, cancelAccountDeletion: PropTypes.func.isRequired, notify: PropTypes.func.isRequired, + root: PropTypes.object.isRequired, }; export default DeleteMyAccount; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js index 599816e2d..7c7c47d0b 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -24,28 +24,45 @@ class DeleteMyAccountDialog extends React.Component { this.setState(initialState); }; + cancel = () => { + this.clear(); + this.closeDialog(); + }; + render() { const { step } = this.state; return ( - + ×

Delete My Account

{step === 0 && ( - + )} {step === 1 && ( - + )} {step === 2 && ( - + )} {step === 3 && ( - + )} - {step === 4 && } + {step === 4 && }
); } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js index 22cf476e5..764dae302 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js @@ -1,9 +1,10 @@ import React from 'react'; import cn from 'classnames'; +import PropTypes from 'prop-types'; import { Button, Icon } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountFinalStep = () => ( +const DeleteMyAccountFinalStep = props => (

Your request has been submitted and confirmation has been sent to the @@ -35,7 +36,7 @@ const DeleteMyAccountFinalStep = () => (

); +DeleteMyAccountFinalStep.propTypes = { + finish: PropTypes.func.isRequired, +}; + export default DeleteMyAccountFinalStep; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js index f81d912ea..901466d3b 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button, Icon } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; @@ -29,7 +30,12 @@ const DeleteMyAccountStep0 = props => (
- +
); +DeleteMyAccountStep0.propTypes = { + goToNextStep: PropTypes.func.isRequired, + cancel: PropTypes.func.isRequired, +}; + export default DeleteMyAccountStep0; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js index 1d26190bc..e74611b05 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; @@ -18,7 +19,12 @@ const DeleteMyAccountStep1 = props => ( comments, reply to comments, or select reactions.

- +
); +DeleteMyAccountStep1.propTypes = { + goToNextStep: PropTypes.func.isRequired, + cancel: PropTypes.func.isRequired, +}; + export default DeleteMyAccountStep1; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js index 3337c0b94..8ef14445e 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js @@ -1,9 +1,10 @@ import React from 'react'; +import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep1 = props => ( +const DeleteMyAccountStep2 = props => (

Before your account is deleted, we recommend you download your comment @@ -17,7 +18,12 @@ const DeleteMyAccountStep1 = props => (

- +
); -export default DeleteMyAccountStep1; +DeleteMyAccountStep2.propTypes = { + goToNextStep: PropTypes.func.isRequired, + cancel: PropTypes.func.isRequired, +}; + +export default DeleteMyAccountStep2; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js index 8cff542c1..f91ca42c7 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js @@ -1,9 +1,10 @@ import React from 'react'; +import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep1 = props => ( +const DeleteMyAccountStep3 = props => (

Are you sure you want to delete your account? @@ -19,7 +20,12 @@ const DeleteMyAccountStep1 = props => ( value="delete" />
- +
); -export default DeleteMyAccountStep1; +DeleteMyAccountStep3.propTypes = { + goToNextStep: PropTypes.func.isRequired, + cancel: PropTypes.func.isRequired, +}; + +export default DeleteMyAccountStep3; diff --git a/plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js b/plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js index b88780f1f..a9c033853 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js +++ b/plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js @@ -12,7 +12,7 @@ const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); const withData = withFragments({ root: gql` - fragment TalkIgnoreUser_IgnoredUserSection_root on RootQuery { + fragment Talk_DeleteMyAccount_root on RootQuery { me { scheduledDeletionDate } From 5eead8b7ee0edb3545b9940284252085bbaa0d97 Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 16:32:42 -0300 Subject: [PATCH 11/47] Adding AccountDeletionRequestedSign.js --- .../AccountDeletionRequestedSign.css | 23 ++++++ .../AccountDeletionRequestedSign.js | 26 +++++++ .../components/DeleteMyAccountDialog.js | 2 + .../components/DeleteMyAccountFinalStep.js | 4 +- .../components/DeleteMyAccountStep.css | 7 ++ .../components/DeleteMyAccountStep3.js | 72 +++++++++++-------- 6 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css new file mode 100644 index 000000000..413a3852b --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css @@ -0,0 +1,23 @@ +.container { + border : solid 1px #F26563; + border-radius: 2px; + color: #3B4A53; +} + +.button { + color: #787D80; + border-radius: 2px; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } + + &.secondary { + background-color: #787D80; + color: white; + } +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js new file mode 100644 index 000000000..7d1941fa7 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js @@ -0,0 +1,26 @@ +import React from 'react'; +import cn from 'classnames'; +import { Button, Icon } from 'plugin-api/beta/client/components/ui'; +import styles from './AccountDeletionRequestedSign.css'; + +class AccountDeletionRequestedSign extends React.Component { + render() { + return ( +
+

+ Account Deletion Requested +

+

+ A request to delete your account was received on. If you would like to + continue leaving comments, replies or reactions, you may cancel your + request to delete your account below before +

+ +
+ ); + } +} + +export default AccountDeletionRequestedSign; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js index 7c7c47d0b..4e3a1aa99 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -60,6 +60,7 @@ class DeleteMyAccountDialog extends React.Component { )} {step === 4 && } @@ -70,6 +71,7 @@ class DeleteMyAccountDialog extends React.Component { DeleteMyAccountDialog.propTypes = { closeDialog: PropTypes.func.isRequired, + requestAccountDeletion: PropTypes.func.isRequired, }; export default DeleteMyAccountDialog; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js index 764dae302..ccbbf61fa 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js @@ -11,12 +11,12 @@ const DeleteMyAccountFinalStep = props => ( email address associated with your account.

-
+
Your account is scheduled to be deleted at: - + Account Deletion Date and Time
diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css index 98b73f376..53d8ecef8 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css @@ -106,3 +106,10 @@ .step { padding-top: 20px; } + +.scheduledDeletion { + i.timeIcon { + font-size: 1.2em; + padding: 4px; + } +} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js index f91ca42c7..54f49f375 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js @@ -4,40 +4,50 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -const DeleteMyAccountStep3 = props => ( -
-

- Are you sure you want to delete your account? -

-

- To confirm you would like to delete your account please type in the - following phrase into the text box below: -

- -
- - -
-
-); +class DeleteMyAccountStep3 extends React.Component { + deleteAndContinue = () => { + this.props.requestAccountDeletion(); + this.props.goToNextStep(); + }; + + render() { + return ( +
+

+ Are you sure you want to delete your account? +

+

+ To confirm you would like to delete your account please type in the + following phrase into the text box below: +

+ +
+ + +
+
+ ); + } +} DeleteMyAccountStep3.propTypes = { goToNextStep: PropTypes.func.isRequired, + requestAccountDeletion: PropTypes.func.isRequired, cancel: PropTypes.func.isRequired, }; From ff7ee2aefc61522cbef173e4e5d3a31fcf7ff3fa Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 17:18:58 -0300 Subject: [PATCH 12/47] Updating cache --- client/coral-framework/graphql/mutations.js | 58 ++++++++++++++++++- locales/en.yml | 1 + plugins/talk-plugin-auth/client/index.js | 8 ++- .../AccountDeletionRequestedSign.css | 23 -------- .../AccountDeletionRequestedSign.js | 26 --------- .../components/DeleteMyAccount.css | 10 ++++ .../components/DeleteMyAccount.js | 17 +++++- .../components/DeleteMyAccountDialog.js | 5 +- .../components/DeleteMyAccountStep3.js | 2 +- .../AccountDeletionRequestedSign.css | 44 ++++++++++++++ .../AccountDeletionRequestedSign.js | 55 ++++++++++++++++++ .../AccountDeletionRequestedSign.js | 25 ++++++++ 12 files changed, 216 insertions(+), 58 deletions(-) delete mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css delete mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js create mode 100644 plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css create mode 100644 plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js create mode 100644 plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index bf412b189..89ffd1130 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -634,7 +634,32 @@ export const withRequestAccountDeletion = withMutation( { props: ({ mutate }) => ({ requestAccountDeletion: () => { - return mutate(); + return mutate({ + variables: {}, + update: proxy => { + const CancelAccountDeletionQuery = gql` + query Talk_CancelAccountDeletion { + me { + id + scheduledDeletionDate + } + } + `; + + const prev = proxy.readQuery({ query: CancelAccountDeletionQuery }); + + const data = update(prev, { + me: { + scheduledDeletionDate: { $set: new Date() }, + }, + }); + + proxy.writeQuery({ + query: CancelAccountDeletionQuery, + data, + }); + }, + }); }, }), } @@ -651,7 +676,9 @@ export const withRequestDownloadLink = withMutation( { props: ({ mutate }) => ({ requestDownloadLink: () => { - return mutate(); + return mutate({ + variables: {}, + }); }, }), } @@ -668,7 +695,32 @@ export const withCancelAccountDeletion = withMutation( { props: ({ mutate }) => ({ cancelAccountDeletion: () => { - return mutate(); + return mutate({ + variables: {}, + update: proxy => { + const CancelAccountDeletionQuery = gql` + query Talk_CancelAccountDeletion { + me { + id + scheduledDeletionDate + } + } + `; + + const prev = proxy.readQuery({ query: CancelAccountDeletionQuery }); + + const data = update(prev, { + me: { + scheduledDeletionDate: { $set: null }, + }, + }); + + proxy.writeQuery({ + query: CancelAccountDeletionQuery, + data, + }); + }, + }); }, }), } diff --git a/locales/en.yml b/locales/en.yml index 04fbc0bcb..5806976a4 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -246,6 +246,7 @@ en: ALREADY_EXISTS: "Resource already exists" INVALID_ASSET_URL: "Assert URL is invalid" CANNOT_IGNORE_STAFF: "Cannot ignore Staff members." + DELETION_NOT_SCHEDULED: "Deletion was not scheduled" email: "Not a valid E-Mail" confirm_password: "Passwords don't match. Please check again" network_error: "Failed to connect to server. Check your internet connection and try again." diff --git a/plugins/talk-plugin-auth/client/index.js b/plugins/talk-plugin-auth/client/index.js index b432b05b2..98da589f8 100644 --- a/plugins/talk-plugin-auth/client/index.js +++ b/plugins/talk-plugin-auth/client/index.js @@ -5,12 +5,18 @@ import translations from './translations.yml'; import Login from './login/containers/Main'; import reducer from './login/reducer'; import DeleteMyAccount from './profile-settings/containers/DeleteMyAccount'; +import AccountDeletionRequestedSign from './stream/containers/AccountDeletionRequestedSign'; export default { reducer, translations, slots: { - stream: [UserBox, SignInButton, SetUsernameDialog], + stream: [ + AccountDeletionRequestedSign, + UserBox, + SignInButton, + SetUsernameDialog, + ], login: [Login], profileSettings: [DeleteMyAccount], }, diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css deleted file mode 100644 index 413a3852b..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.css +++ /dev/null @@ -1,23 +0,0 @@ -.container { - border : solid 1px #F26563; - border-radius: 2px; - color: #3B4A53; -} - -.button { - color: #787D80; - border-radius: 2px; - background-color: transparent; - height: 30px; - font-size: 0.9em; - line-height: normal; - - &:hover { - background-color: #eaeaea; - } - - &.secondary { - background-color: #787D80; - color: white; - } -} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js deleted file mode 100644 index 7d1941fa7..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/AccountDeletionRequestedSign.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import cn from 'classnames'; -import { Button, Icon } from 'plugin-api/beta/client/components/ui'; -import styles from './AccountDeletionRequestedSign.css'; - -class AccountDeletionRequestedSign extends React.Component { - render() { - return ( -
-

- Account Deletion Requested -

-

- A request to delete your account was received on. If you would like to - continue leaving comments, replies or reactions, you may cancel your - request to delete your account below before -

- -
- ); - } -} - -export default AccountDeletionRequestedSign; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css index 2fe139d52..e524d990a 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css @@ -10,4 +10,14 @@ &:hover { background-color: #eaeaea; } + + &.secondary { + background-color: #787D80; + color: white; + } + + > i { + font-size: 1.2em; + vertical-align: middle; + } } \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js index 0fc06f326..9bc5573a1 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import cn from 'classnames'; +import moment from 'moment'; import styles from './DeleteMyAccount.css'; import { Button } from 'plugin-api/beta/client/components/ui'; import DeleteMyAccountDialog from './DeleteMyAccountDialog'; @@ -52,6 +53,7 @@ class DeleteMyAccount extends React.Component {

Delete My Account

+

+ Deleting your account will permanently erase your profile and remove + all your comments from this site. +

{scheduledDeletionDate && `You have already submitted a request to delete your account. - Your account will be deleted on ${scheduledDeletionDate}. You may + Your account will be deleted on ${moment( + scheduledDeletionDate + ).format('MMM Do YYYY, h:mm:ss a')}. You may cancel the request until that time`}

{scheduledDeletionDate ? ( diff --git a/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css b/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css new file mode 100644 index 000000000..0dada08b5 --- /dev/null +++ b/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css @@ -0,0 +1,44 @@ +.container { + border: 1px solid #f26563; + border-radius: 2px; + color: #3b4a53; + padding: 20px 10px; + background-color: rgba(242, 101, 99, 0.1); + margin: 20px 0; +} + +.button { + color: #787D80; + border-radius: 2px; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } + + &.secondary { + background-color: #787D80; + color: white; + } +} + +.title { + margin: 0; + i.icon { + font-size: 1em; + padding: 4px; + } +} + +.description { + margin: 0; + padding-left: 22px; + padding-bottom: 15px; +} + +.actions { + text-align: center; +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js new file mode 100644 index 000000000..a26d28d21 --- /dev/null +++ b/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js @@ -0,0 +1,55 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import { Button, Icon } from 'plugin-api/beta/client/components/ui'; +import styles from './AccountDeletionRequestedSign.css'; +import { getErrorMessages } from 'coral-framework/utils'; + +class AccountDeletionRequestedSign extends React.Component { + cancelAccountDeletion = async () => { + const { cancelAccountDeletion, notify } = this.props; + try { + await cancelAccountDeletion(); + notify( + 'success', + 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.' + ); + } catch (err) { + notify('error', getErrorMessages(err)); + } + }; + + render() { + return ( +
+

+ Account Deletion + Requested +

+

+ A request to delete your account was received on. +

+

+ If you would like to continue leaving comments, replies or reactions, + you may cancel your request to delete your account below before +

+
+ +
+
+ ); + } +} + +AccountDeletionRequestedSign.propTypes = { + cancelAccountDeletion: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, + root: PropTypes.object.isRequired, +}; + +export default AccountDeletionRequestedSign; diff --git a/plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js b/plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js new file mode 100644 index 000000000..d842ec43f --- /dev/null +++ b/plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js @@ -0,0 +1,25 @@ +import { compose, gql } from 'react-apollo'; +import { bindActionCreators } from 'redux'; +import { connect, withFragments, excludeIf } from 'plugin-api/beta/client/hocs'; +import AccountDeletionRequestedSign from '../components/AccountDeletionRequestedSign'; +import { notify } from 'coral-framework/actions/notification'; +import { withCancelAccountDeletion } from 'plugin-api/beta/client/hocs'; + +const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); + +const withData = withFragments({ + root: gql` + fragment Talk_AccountDeletionRequestedSignIn_root on RootQuery { + me { + scheduledDeletionDate + } + } + `, +}); + +export default compose( + connect(null, mapDispatchToProps), + withCancelAccountDeletion, + withData, + excludeIf(props => !props.root.me.scheduledDeletionDate) +)(AccountDeletionRequestedSign); From 49fcc1ea43ab948480ed70919ef60110f57fe97c Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 17:30:57 -0300 Subject: [PATCH 13/47] Adding missing slot --- client/coral-embed-stream/src/tabs/stream/containers/Stream.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js index 0a7a1951c..17d3132ea 100644 --- a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js @@ -372,6 +372,7 @@ const slots = [ 'streamTabsPrepend', 'streamTabPanes', 'streamFilter', + 'stream', ]; const fragments = { From d5fa7455e5d905aff4126d7fa6b2902ee6fd547e Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 1 May 2018 17:55:01 -0300 Subject: [PATCH 14/47] Adding InputField --- .../client/components/ErrorMessage.css | 8 + .../client/components/ErrorMessage.js | 17 ++ .../client/components/InputField.css | 80 +++++++ .../client/components/InputField.js | 94 ++++++++ .../components/ChangePassword.css | 87 +++++++ .../components/ChangePassword.js | 223 ++++++++++++++++++ .../components/ChangeUsername.css | 122 ++++++++++ .../components/ChangeUsername.js | 188 +++++++++++++++ .../components/ChangeUsernameDialog.css | 84 +++++++ .../components/ChangeUsernameDialog.js | 117 +++++++++ .../components/DeleteMyAccountDialog.js | 15 +- .../components/DeleteMyAccountStep3.js | 48 +++- .../components/ErrorMessage.css | 8 + .../components/ErrorMessage.js | 17 ++ .../components/InputField.css | 80 +++++++ .../profile-settings/components/InputField.js | 94 ++++++++ .../containers/ChangePassword.js | 12 + .../containers/ChangeUsername.js | 12 + 18 files changed, 1302 insertions(+), 4 deletions(-) create mode 100644 plugins/talk-plugin-auth/client/components/ErrorMessage.css create mode 100644 plugins/talk-plugin-auth/client/components/ErrorMessage.js create mode 100644 plugins/talk-plugin-auth/client/components/InputField.css create mode 100644 plugins/talk-plugin-auth/client/components/InputField.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/InputField.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/InputField.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/containers/ChangePassword.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js diff --git a/plugins/talk-plugin-auth/client/components/ErrorMessage.css b/plugins/talk-plugin-auth/client/components/ErrorMessage.css new file mode 100644 index 000000000..039ffae30 --- /dev/null +++ b/plugins/talk-plugin-auth/client/components/ErrorMessage.css @@ -0,0 +1,8 @@ +.errorMsg { + color: #FA4643; + font-size: 0.9em; +} + +.warningIcon { + color: #FA4643; +} diff --git a/plugins/talk-plugin-auth/client/components/ErrorMessage.js b/plugins/talk-plugin-auth/client/components/ErrorMessage.js new file mode 100644 index 000000000..f39a8fc08 --- /dev/null +++ b/plugins/talk-plugin-auth/client/components/ErrorMessage.js @@ -0,0 +1,17 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styles from './ErrorMessage.css'; +import { Icon } from 'plugin-api/beta/client/components/ui'; + +const ErrorMessage = ({ children }) => ( +
+ + {children} +
+); + +ErrorMessage.propTypes = { + children: PropTypes.node, +}; + +export default ErrorMessage; diff --git a/plugins/talk-plugin-auth/client/components/InputField.css b/plugins/talk-plugin-auth/client/components/InputField.css new file mode 100644 index 000000000..3442befde --- /dev/null +++ b/plugins/talk-plugin-auth/client/components/InputField.css @@ -0,0 +1,80 @@ + +.detailItem { + margin-bottom: 12px; +} + +.detailItemContainer { + display: flex; +} + +.columnDisplay { + flex-direction: column; + + .detailItemMessage { + padding: 4px 0 0; + } +} + +.detailItemContent { + border: solid 1px #787D80; + border-radius: 2px; + background-color: white; + height: 30px; + display: inline-block; + width: 230px; + display: flex; + box-sizing: border-box; + + > .detailIcon { + font-size: 1.2em; + padding: 0 5px; + color: #787D80; + line-height: 30px; + } + + &.error { + border: solid 2px #FA4643; + } + + &.disabled { + background-color: #E0E0E0; + } +} + +.detailLabel { + color: #4C4C4D; + font-size: 1em; + display: block; + margin-bottom: 4px; +} + +.detailValue { + background: transparent; + border: none; + font-size: 1em; + color: #000; + outline: none; + flex: 1; + height: 100%; + box-sizing: border-box; +} + +.detailItemMessage { + flex-grow: 1; + display: flex; + align-items: center; + padding-left: 6px; + padding-top: 16px; + + .warningIcon, .checkIcon { + font-size: 17px; + } +} + +.checkIcon { + color: #00CD73; +} + +.warningIcon { + color: #FA4643; +} diff --git a/plugins/talk-plugin-auth/client/components/InputField.js b/plugins/talk-plugin-auth/client/components/InputField.js new file mode 100644 index 000000000..26937d5b9 --- /dev/null +++ b/plugins/talk-plugin-auth/client/components/InputField.js @@ -0,0 +1,94 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import styles from './InputField.css'; +import ErrorMessage from './ErrorMessage'; +import { Icon } from 'plugin-api/beta/client/components/ui'; + +const InputField = ({ + id = '', + label = '', + type = 'text', + name = '', + onChange = () => {}, + showError = true, + hasError = false, + errorMsg = '', + children, + columnDisplay = false, + showSuccess = false, + validationType = '', + icon = '', + value = '', + defaultValue = '', + disabled = false, +}) => { + const inputValue = { + ...(value ? { value } : {}), + ...(defaultValue ? { defaultValue } : {}), + }; + + return ( +
+
+ {label && ( + + )} +
+ {icon && } + +
+
+ {!hasError && + showSuccess && + value && } + {hasError && showError && {errorMsg}} +
+
+ {children} +
+ ); +}; + +InputField.propTypes = { + id: PropTypes.string, + disabled: PropTypes.bool, + label: PropTypes.string, + type: PropTypes.string, + name: PropTypes.string.isRequired, + onChange: PropTypes.func, + value: PropTypes.string, + defaultValue: PropTypes.string, + icon: PropTypes.string, + showError: PropTypes.bool, + hasError: PropTypes.bool, + errorMsg: PropTypes.string, + children: PropTypes.node, + columnDisplay: PropTypes.bool, + showSuccess: PropTypes.bool, + validationType: PropTypes.string, +}; + +export default InputField; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css new file mode 100644 index 000000000..6c7f9ae41 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css @@ -0,0 +1,87 @@ +.container { + position: relative; + color: #202020; + padding: 10px; + border-radius: 2px; + border: solid 1px transparent; + box-sizing: border-box; + justify-content: space-between; + + &.editing { + border-color: #979797; + background-color: #EDEDED; + } +} + +.actions { + position: absolute; + top: 10px; + right: 10px; + display: flex; + flex-direction: column; + align-items: center; +} + +.title { + color: #202020; + margin: 0 0 20px; +} + +.detailBottomBox { + display: block; + padding-top: 4px; + text-align: right; + width: 280px; +} + +.detailLink { + color: #00538A; + text-decoration: none; + font-size: 0.9em; + &:hover { + cursor: pointer; + } +} + +.button { + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; +} + +.saveButton { + background-color: #3498DB; + border-color: #3498DB; + color: white; + + > i { + font-size: 17px; + } + + &:hover { + background-color: #399ee2; + color: white; + } + + &:disabled { + border-color: #e0e0e0; + + &:hover { + background-color: #e0e0e0; + color: #4f5c67; + cursor: default; + } + } +} + +.cancelButton { + color:#787D80; + margin-top: 6px; + font-size: 0.9em; + + &:hover { + cursor: pointer; + } +} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js new file mode 100644 index 000000000..90940728d --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js @@ -0,0 +1,223 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import styles from './ChangePassword.css'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import validate from 'coral-framework/helpers/validate'; +import errorMsj from 'coral-framework/helpers/error'; +import isEqual from 'lodash/isEqual'; +import { t } from 'plugin-api/beta/client/services'; +import InputField from './InputField'; +import { getErrorMessages } from 'coral-framework/utils'; + +const initialState = { + editing: false, + showErrors: true, + errors: {}, + formData: {}, +}; + +class ChangePassword extends React.Component { + state = initialState; + validKeys = ['oldPassword', 'newPassword', 'confirmNewPassword']; + + onChange = e => { + const { name, value, type } = e.target; + this.setState( + state => ({ + formData: { + ...state.formData, + [name]: value, + }, + }), + () => { + this.fieldValidation(value, type, name); + + // Perform equality validation if password fields have changed + if (name === 'newPassword' || name === 'confirmNewPassword') { + this.equalityValidation('newPassword', 'confirmNewPassword'); + } + } + ); + }; + + equalityValidation = (field, field2) => { + const cond = this.state.formData[field] === this.state.formData[field2]; + if (!cond) { + this.addError({ + [field2]: t('talk-plugin-auth.change_password.passwords_dont_match'), + }); + } else { + this.removeError(field2); + } + return cond; + }; + + fieldValidation = (value, type, name) => { + if (!value.length) { + this.addError({ + [name]: t('talk-plugin-auth.change_password.required_field'), + }); + } else if (!validate[type](value)) { + this.addError({ [name]: errorMsj[type] }); + } else { + this.removeError(name); + } + }; + + hasError = err => { + return Object.keys(this.state.errors).indexOf(err) !== -1; + }; + + addError = err => { + this.setState(({ errors }) => ({ + errors: { ...errors, ...err }, + })); + }; + + removeError = errKey => { + this.setState(state => { + const { [errKey]: _, ...errors } = state.errors; + return { + errors, + }; + }); + }; + + enableEditing = () => { + this.setState({ + editing: true, + }); + }; + + isSubmitBlocked = () => { + const formHasErrors = !!Object.keys(this.state.errors).length; + const formIncomplete = !isEqual( + Object.keys(this.state.formData), + this.validKeys + ); + return formHasErrors || formIncomplete; + }; + + clearForm = () => { + this.setState(initialState); + }; + + onSave = async () => { + const { oldPassword, newPassword } = this.state.formData; + + try { + await this.props.changePassword({ + oldPassword, + newPassword, + }); + this.props.notify( + 'success', + t('talk-plugin-auth.change_password.changed_password_msg') + ); + } catch (err) { + this.props.notify('error', getErrorMessages(err)); + } + + this.clearForm(); + this.disableEditing(); + }; + + disableEditing = () => { + this.setState({ + editing: false, + }); + }; + + cancel = () => { + this.clearForm(); + this.disableEditing(); + }; + + render() { + const { editing, errors } = this.state; + + return ( +
+

+ {t('talk-plugin-auth.change_password.change_password')} +

+ {editing && ( +
+ + + + {t('talk-plugin-auth.change_password.forgot_password')} + + + + + + + )} + {editing ? ( +
+ + + {t('talk-plugin-auth.change_password.cancel')} + +
+ ) : ( +
+ +
+ )} +
+ ); + } +} + +ChangePassword.propTypes = { + changePassword: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, +}; + +export default ChangePassword; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css new file mode 100644 index 000000000..5b4631ecf --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css @@ -0,0 +1,122 @@ +.container { + margin-bottom: 20px; + display: flex; + position: relative; + color: #202020; + padding: 10px; + border-radius: 2px; + box-sizing: border-box; + justify-content: space-between; + + &.editing { + background-color: #EDEDED; + } +} + +.content { + flex-grow: 1; +} + +.actions { + flex-grow: 0; + display: flex; + flex-direction: column; + align-items: center; +} + +.email { + margin: 0; +} + +.username { + margin-bottom: 4px; +} + +.button { + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; +} + +.saveButton { + background-color: #3498DB; + border-color: #3498DB; + color: white; + + > i { + font-size: 17px; + } + + &:hover { + background-color: #399ee2; + color: white; + } + + &:disabled { + border-color: #e0e0e0; + + &:hover { + background-color: #e0e0e0; + color: #4f5c67; + cursor: default; + } + } +} + +.cancelButton { + color:#787D80; + margin-top: 6px; + font-size: 0.9em; + + &:hover { + cursor: pointer; + } +} + +.detailLabel { + border: solid 1px #787D80; + border-radius: 2px; + background-color: white; + height: 30px; + display: inline-block; + width: 230px; + display: flex; + + > .detailLabelIcon { + font-size: 1.2em; + padding: 0 5px; + color: #787D80; + line-height: 30px; + } + + &.disabled { + background-color: #E0E0E0; + } +} + +.detailValue { + background: transparent; + border: none; + font-size: 1em; + color: #000; + height: 30px; + outline: none; + flex: 1; +} + +.bottomText { + color: #474747; + font-size: 0.9em; +} + +.detailList { + list-style: none; + margin: 0; + padding: 0; +} + +.detailItem { + margin-bottom: 12px; +} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js new file mode 100644 index 000000000..8188bdfbe --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -0,0 +1,188 @@ +import React from 'react'; +import cn from 'classnames'; +import PropTypes from 'prop-types'; +import styles from './ChangeUsername.css'; +import { Button } from 'plugin-api/beta/client/components/ui'; +import ChangeUsernameDialog from './ChangeUsernameDialog'; +import { t } from 'plugin-api/beta/client/services'; +import InputField from './InputField'; +import { getErrorMessages } from 'coral-framework/utils'; +import { canUsernameBeUpdated } from 'coral-framework/utils/user'; + +const initialState = { + editing: false, + showDialog: false, + formData: {}, +}; + +class ChangeUsername extends React.Component { + state = initialState; + + clearForm = () => { + this.setState(initialState); + }; + + enableEditing = () => { + this.setState({ + editing: true, + }); + }; + + disableEditing = () => { + this.setState({ + editing: false, + }); + }; + + cancel = () => { + this.clearForm(); + this.disableEditing(); + }; + + showDialog = () => { + this.setState({ + showDialog: true, + }); + }; + + onSave = async () => { + this.showDialog(); + }; + + saveChanges = async () => { + const { newUsername } = this.state.formData; + const { changeUsername } = this.props; + + try { + await changeUsername(newUsername); + this.props.notify( + 'success', + t('talk-plugin-auth.change_username.changed_username_success_msg') + ); + } catch (err) { + this.props.notify('error', getErrorMessages(err)); + } + + this.clearForm(); + this.disableEditing(); + }; + + onChange = e => { + const { name, value } = e.target; + + this.setState(state => ({ + formData: { + ...state.formData, + [name]: value, + }, + })); + }; + + closeDialog = () => { + this.setState({ + showDialog: false, + }); + }; + + render() { + const { + username, + emailAddress, + root: { me: { state: { status } } }, + notify, + } = this.props; + const { editing, formData, showDialog } = this.state; + + return ( +
+ + + {editing ? ( +
+
+ + + {t('talk-plugin-auth.change_username.change_username_note')} + + + +
+
+ ) : ( +
+

{username}

+ {emailAddress ? ( +

{emailAddress}

+ ) : null} +
+ )} + {editing ? ( +
+ + + {t('talk-plugin-auth.change_username.cancel')} + +
+ ) : ( +
+ +
+ )} +
+ ); + } +} + +ChangeUsername.propTypes = { + root: PropTypes.object.isRequired, + changeUsername: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, + username: PropTypes.string, + emailAddress: PropTypes.string, +}; + +export default ChangeUsername; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css new file mode 100644 index 000000000..af681d596 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css @@ -0,0 +1,84 @@ +.dialog { + border: none; + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); + width: 320px; + top: 10px; + font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif; + font-size: 14px; + border-radius: 4px; + padding: 12px 20px; +} + +.close { + font-size: 20px; + line-height: 14px; + top: 10px; + right: 10px; + position: absolute; + display: block; + font-weight: bold; + color: #363636; + cursor: pointer; + + &:hover { + color: #6b6b6b; + } +} + +.title { + font-size: 1.3em; + margin-bottom: 8px; +} + +.description { + font-size: 1em; + line-height: 20px; + margin: 0; +} + +.item { + display: block; + color: #4C4C4D; + font-size: 1em; + margin-bottom: 2px; +} + +.bottomNote { + font-size: 0.9em; + line-height: 20px; + padding-top: 10px; + display: block; +} + +.bottomActions { + text-align: right; +} + +.usernamesChange { + margin: 18px 0; +} + +.cancel { + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } +} + +.confirmChanges { + background-color: #3498DB; + border-color: #3498DB; + color: white; + height: 30px; + font-size: 0.9em; + + &:hover { + background-color: #3ba3ec; + color: white; + } +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js new file mode 100644 index 000000000..321b36926 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -0,0 +1,117 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cn from 'classnames'; +import styles from './ChangeUsernameDialog.css'; +import InputField from './InputField'; +import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; +import { t } from 'plugin-api/beta/client/services'; + +class ChangeUsernameDialog extends React.Component { + state = { + showError: false, + }; + + showError = () => { + this.setState({ + showError: true, + }); + }; + + confirmChanges = async () => { + if (this.formHasError()) { + this.showError(); + return; + } + + if (!this.props.canUsernameBeUpdated) { + this.props.notify( + 'error', + t('talk-plugin-auth.change_username.change_username_attempt') + ); + return; + } + + await this.props.saveChanges(); + this.props.closeDialog(); + }; + + formHasError = () => + this.props.formData.confirmNewUsername !== this.props.formData.newUsername; + + render() { + return ( + + + × + +

+ {t('talk-plugin-auth.change_username.confirm_username_change')} +

+
+

+ {t('talk-plugin-auth.change_username.description')} +

+
+ + {t('talk-plugin-auth.change_username.old_username')}:{' '} + {this.props.username} + + + {t('talk-plugin-auth.change_username.new_username')}:{' '} + {this.props.formData.newUsername} + +
+
+ + + {t('talk-plugin-auth.change_username.bottom_note')} + + +
+
+ + +
+
+
+ ); + } +} + +ChangeUsernameDialog.propTypes = { + saveChanges: PropTypes.func, + closeDialog: PropTypes.func, + showDialog: PropTypes.bool, + onChange: PropTypes.func, + username: PropTypes.string, + formData: PropTypes.object, + canUsernameBeUpdated: PropTypes.bool.isRequired, + notify: PropTypes.func.isRequired, +}; + +export default ChangeUsernameDialog; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js index b9a1bfc9d..35069384c 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js @@ -9,7 +9,7 @@ import DeleteMyAccountStep2 from './DeleteMyAccountStep2'; import DeleteMyAccountStep3 from './DeleteMyAccountStep3'; import DeleteMyAccountFinalStep from './DeleteMyAccountFinalStep'; -const initialState = { step: 0 }; +const initialState = { step: 0, formData: {} }; class DeleteMyAccountDialog extends React.Component { state = initialState; @@ -29,6 +29,17 @@ class DeleteMyAccountDialog extends React.Component { this.props.closeDialog(); }; + onChange = e => { + const { name, value } = e.target; + + this.setState(state => ({ + formData: { + ...state.formData, + [name]: value, + }, + })); + }; + render() { const { step } = this.state; return ( @@ -58,9 +69,11 @@ class DeleteMyAccountDialog extends React.Component { )} {step === 3 && ( )} {step === 4 && } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js index 63a00243b..45dca8f97 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js @@ -3,13 +3,41 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; +import InputField from '../../components/InputField'; + +const initialState = { + showError: false, +}; class DeleteMyAccountStep3 extends React.Component { - deleteAndContinue = () => { - this.props.requestAccountDeletion(); + state = initialState; + phrase = 'delete'; + + showError = () => { + this.setState({ + showError: true, + }); + }; + + clear = () => { + this.setState(initialState); + }; + + deleteAndContinue = async () => { + if (this.formHasError()) { + this.showError(); + return; + } + + await this.props.requestAccountDeletion(); + this.clear(); this.props.goToNextStep(); }; + formHasError = () => + !this.props.formData.confirmPhrase || + this.props.formData.confirmPhrase !== this.phrase; + render() { return (
@@ -24,7 +52,19 @@ class DeleteMyAccountStep3 extends React.Component { className={styles.textBox} disabled={true} readOnly={true} - value="delete" + value={this.phrase} + /> +
- - {t('talk-plugin-auth.change_password.cancel')} - -
- ) : ( -
- -
- )} - - ); - } -} - -ChangePassword.propTypes = { - changePassword: PropTypes.func.isRequired, - notify: PropTypes.func.isRequired, -}; - -export default ChangePassword; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css deleted file mode 100644 index 5b4631ecf..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css +++ /dev/null @@ -1,122 +0,0 @@ -.container { - margin-bottom: 20px; - display: flex; - position: relative; - color: #202020; - padding: 10px; - border-radius: 2px; - box-sizing: border-box; - justify-content: space-between; - - &.editing { - background-color: #EDEDED; - } -} - -.content { - flex-grow: 1; -} - -.actions { - flex-grow: 0; - display: flex; - flex-direction: column; - align-items: center; -} - -.email { - margin: 0; -} - -.username { - margin-bottom: 4px; -} - -.button { - border: 1px solid #787d80; - background-color: transparent; - height: 30px; - font-size: 0.9em; - line-height: normal; -} - -.saveButton { - background-color: #3498DB; - border-color: #3498DB; - color: white; - - > i { - font-size: 17px; - } - - &:hover { - background-color: #399ee2; - color: white; - } - - &:disabled { - border-color: #e0e0e0; - - &:hover { - background-color: #e0e0e0; - color: #4f5c67; - cursor: default; - } - } -} - -.cancelButton { - color:#787D80; - margin-top: 6px; - font-size: 0.9em; - - &:hover { - cursor: pointer; - } -} - -.detailLabel { - border: solid 1px #787D80; - border-radius: 2px; - background-color: white; - height: 30px; - display: inline-block; - width: 230px; - display: flex; - - > .detailLabelIcon { - font-size: 1.2em; - padding: 0 5px; - color: #787D80; - line-height: 30px; - } - - &.disabled { - background-color: #E0E0E0; - } -} - -.detailValue { - background: transparent; - border: none; - font-size: 1em; - color: #000; - height: 30px; - outline: none; - flex: 1; -} - -.bottomText { - color: #474747; - font-size: 0.9em; -} - -.detailList { - list-style: none; - margin: 0; - padding: 0; -} - -.detailItem { - margin-bottom: 12px; -} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js deleted file mode 100644 index 8188bdfbe..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ /dev/null @@ -1,188 +0,0 @@ -import React from 'react'; -import cn from 'classnames'; -import PropTypes from 'prop-types'; -import styles from './ChangeUsername.css'; -import { Button } from 'plugin-api/beta/client/components/ui'; -import ChangeUsernameDialog from './ChangeUsernameDialog'; -import { t } from 'plugin-api/beta/client/services'; -import InputField from './InputField'; -import { getErrorMessages } from 'coral-framework/utils'; -import { canUsernameBeUpdated } from 'coral-framework/utils/user'; - -const initialState = { - editing: false, - showDialog: false, - formData: {}, -}; - -class ChangeUsername extends React.Component { - state = initialState; - - clearForm = () => { - this.setState(initialState); - }; - - enableEditing = () => { - this.setState({ - editing: true, - }); - }; - - disableEditing = () => { - this.setState({ - editing: false, - }); - }; - - cancel = () => { - this.clearForm(); - this.disableEditing(); - }; - - showDialog = () => { - this.setState({ - showDialog: true, - }); - }; - - onSave = async () => { - this.showDialog(); - }; - - saveChanges = async () => { - const { newUsername } = this.state.formData; - const { changeUsername } = this.props; - - try { - await changeUsername(newUsername); - this.props.notify( - 'success', - t('talk-plugin-auth.change_username.changed_username_success_msg') - ); - } catch (err) { - this.props.notify('error', getErrorMessages(err)); - } - - this.clearForm(); - this.disableEditing(); - }; - - onChange = e => { - const { name, value } = e.target; - - this.setState(state => ({ - formData: { - ...state.formData, - [name]: value, - }, - })); - }; - - closeDialog = () => { - this.setState({ - showDialog: false, - }); - }; - - render() { - const { - username, - emailAddress, - root: { me: { state: { status } } }, - notify, - } = this.props; - const { editing, formData, showDialog } = this.state; - - return ( -
- - - {editing ? ( -
-
- - - {t('talk-plugin-auth.change_username.change_username_note')} - - - -
-
- ) : ( -
-

{username}

- {emailAddress ? ( -

{emailAddress}

- ) : null} -
- )} - {editing ? ( -
- - - {t('talk-plugin-auth.change_username.cancel')} - -
- ) : ( -
- -
- )} -
- ); - } -} - -ChangeUsername.propTypes = { - root: PropTypes.object.isRequired, - changeUsername: PropTypes.func.isRequired, - notify: PropTypes.func.isRequired, - username: PropTypes.string, - emailAddress: PropTypes.string, -}; - -export default ChangeUsername; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css deleted file mode 100644 index af681d596..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css +++ /dev/null @@ -1,84 +0,0 @@ -.dialog { - border: none; - box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); - width: 320px; - top: 10px; - font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif; - font-size: 14px; - border-radius: 4px; - padding: 12px 20px; -} - -.close { - font-size: 20px; - line-height: 14px; - top: 10px; - right: 10px; - position: absolute; - display: block; - font-weight: bold; - color: #363636; - cursor: pointer; - - &:hover { - color: #6b6b6b; - } -} - -.title { - font-size: 1.3em; - margin-bottom: 8px; -} - -.description { - font-size: 1em; - line-height: 20px; - margin: 0; -} - -.item { - display: block; - color: #4C4C4D; - font-size: 1em; - margin-bottom: 2px; -} - -.bottomNote { - font-size: 0.9em; - line-height: 20px; - padding-top: 10px; - display: block; -} - -.bottomActions { - text-align: right; -} - -.usernamesChange { - margin: 18px 0; -} - -.cancel { - border: 1px solid #787d80; - background-color: transparent; - height: 30px; - font-size: 0.9em; - line-height: normal; - - &:hover { - background-color: #eaeaea; - } -} - -.confirmChanges { - background-color: #3498DB; - border-color: #3498DB; - color: white; - height: 30px; - font-size: 0.9em; - - &:hover { - background-color: #3ba3ec; - color: white; - } -} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js deleted file mode 100644 index 321b36926..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js +++ /dev/null @@ -1,117 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import cn from 'classnames'; -import styles from './ChangeUsernameDialog.css'; -import InputField from './InputField'; -import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; -import { t } from 'plugin-api/beta/client/services'; - -class ChangeUsernameDialog extends React.Component { - state = { - showError: false, - }; - - showError = () => { - this.setState({ - showError: true, - }); - }; - - confirmChanges = async () => { - if (this.formHasError()) { - this.showError(); - return; - } - - if (!this.props.canUsernameBeUpdated) { - this.props.notify( - 'error', - t('talk-plugin-auth.change_username.change_username_attempt') - ); - return; - } - - await this.props.saveChanges(); - this.props.closeDialog(); - }; - - formHasError = () => - this.props.formData.confirmNewUsername !== this.props.formData.newUsername; - - render() { - return ( - - - × - -

- {t('talk-plugin-auth.change_username.confirm_username_change')} -

-
-

- {t('talk-plugin-auth.change_username.description')} -

-
- - {t('talk-plugin-auth.change_username.old_username')}:{' '} - {this.props.username} - - - {t('talk-plugin-auth.change_username.new_username')}:{' '} - {this.props.formData.newUsername} - -
-
- - - {t('talk-plugin-auth.change_username.bottom_note')} - - -
-
- - -
-
-
- ); - } -} - -ChangeUsernameDialog.propTypes = { - saveChanges: PropTypes.func, - closeDialog: PropTypes.func, - showDialog: PropTypes.bool, - onChange: PropTypes.func, - username: PropTypes.string, - formData: PropTypes.object, - canUsernameBeUpdated: PropTypes.bool.isRequired, - notify: PropTypes.func.isRequired, -}; - -export default ChangeUsernameDialog; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css b/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css deleted file mode 100644 index abcf692fe..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css +++ /dev/null @@ -1,8 +0,0 @@ -.errorMsg { - color: #FA4643; - font-size: 0.9em; -} - -.warningIcon { - color: #FA4643; -} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.js b/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.js deleted file mode 100644 index f39a8fc08..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import styles from './ErrorMessage.css'; -import { Icon } from 'plugin-api/beta/client/components/ui'; - -const ErrorMessage = ({ children }) => ( -
- - {children} -
-); - -ErrorMessage.propTypes = { - children: PropTypes.node, -}; - -export default ErrorMessage; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css deleted file mode 100644 index cd6015e47..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css +++ /dev/null @@ -1,80 +0,0 @@ - -.detailItem { - margin-bottom: 12px; -} - -.detailItemContainer { - display: flex; -} - -.columnDisplay { - flex-direction: column; - - .detailItemMessage { - padding: 4px 0 0; - } -} - -.detailItemContent { - border: solid 1px #787D80; - border-radius: 2px; - background-color: white; - height: 30px; - display: inline-block; - width: 230px; - display: flex; - box-sizing: border-box; - - > .detailIcon { - font-size: 1.2em; - padding: 0 5px; - color: #787D80; - line-height: 30px; - } - - &.error { - border: solid 2px #FA4643; - } - - &.disabled { - background-color: #E0E0E0; - } -} - -.detailLabel { - color: #4C4C4D; - font-size: 1em; - display: block; - margin-bottom: 4px; -} - -.detailValue { - background: transparent; - border: none; - font-size: 1em; - color: #000; - outline: none; - flex: 1; - height: 100%; - box-sizing: border-box; -} - -.detailItemMessage { - flex-grow: 1; - display: flex; - align-items: center; - padding-left: 6px; - padding-top: 16px; - - .warningIcon, .checkIcon { - font-size: 17px; - } -} - -.checkIcon { - color: #00CD73; -} - -.warningIcon { - color: #FA4643; -} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js deleted file mode 100644 index 34c314c20..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import cn from 'classnames'; -import styles from './InputField.css'; -import ErrorMessage from './ErrorMessage'; -import { Icon } from 'plugin-api/beta/client/components/ui'; - -const InputField = ({ - id = '', - label = '', - type = 'text', - name = '', - onChange = () => {}, - showError = true, - hasError = false, - errorMsg = '', - children, - columnDisplay = false, - showSuccess = false, - validationType = '', - icon = '', - value = '', - defaultValue = '', - disabled = false, -}) => { - const inputValue = { - ...(value ? { value } : {}), - ...(defaultValue ? { defaultValue } : {}), - }; - - return ( -
-
- {label && ( - - )} -
- {icon && } - -
-
- {!hasError && - showSuccess && - value && } - {hasError && showError && {errorMsg}} -
-
- {children} -
- ); -}; - -InputField.propTypes = { - id: PropTypes.string, - disabled: PropTypes.bool, - label: PropTypes.string, - type: PropTypes.string, - name: PropTypes.string.isRequired, - onChange: PropTypes.func, - value: PropTypes.string, - defaultValue: PropTypes.string, - icon: PropTypes.string, - showError: PropTypes.bool, - hasError: PropTypes.bool, - errorMsg: PropTypes.string, - children: PropTypes.node, - columnDisplay: PropTypes.bool, - showSuccess: PropTypes.bool, - validationType: PropTypes.string, -}; - -export default InputField; diff --git a/plugins/talk-plugin-auth/client/profile-settings/containers/ChangePassword.js b/plugins/talk-plugin-auth/client/profile-settings/containers/ChangePassword.js deleted file mode 100644 index 1322a2940..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/containers/ChangePassword.js +++ /dev/null @@ -1,12 +0,0 @@ -import { compose } from 'react-apollo'; -import { bindActionCreators } from 'redux'; -import { connect } from 'plugin-api/beta/client/hocs'; -import ChangePassword from '../components/ChangePassword'; -import { notify } from 'coral-framework/actions/notification'; -import { withChangePassword } from 'plugin-api/beta/client/hocs'; - -const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); - -export default compose(connect(null, mapDispatchToProps), withChangePassword)( - ChangePassword -); diff --git a/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js deleted file mode 100644 index 87e1e18b5..000000000 --- a/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js +++ /dev/null @@ -1,12 +0,0 @@ -import { compose } from 'react-apollo'; -import { bindActionCreators } from 'redux'; -import { connect } from 'plugin-api/beta/client/hocs'; -import ChangeUsername from '../components/ChangeUsername'; -import { notify } from 'coral-framework/actions/notification'; -import { withChangeUsername } from 'plugin-api/beta/client/hocs'; - -const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); - -export default compose(connect(null, mapDispatchToProps), withChangeUsername)( - ChangeUsername -); diff --git a/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.css similarity index 100% rename from plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.css rename to plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.css diff --git a/plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js similarity index 100% rename from plugins/talk-plugin-auth/client/stream/components/AccountDeletionRequestedSign.js rename to plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.css similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.css rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.css diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccount.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.css similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.css rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.css diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountDialog.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountFinalStep.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep.css similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep.css rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep.css diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep0.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep1.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep2.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/DeleteMyAccountStep3.js rename to plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js diff --git a/plugins/talk-plugin-auth/client/components/ErrorMessage.css b/plugins/talk-plugin-profile-data/client/components/ErrorMessage.css similarity index 100% rename from plugins/talk-plugin-auth/client/components/ErrorMessage.css rename to plugins/talk-plugin-profile-data/client/components/ErrorMessage.css diff --git a/plugins/talk-plugin-auth/client/components/ErrorMessage.js b/plugins/talk-plugin-profile-data/client/components/ErrorMessage.js similarity index 100% rename from plugins/talk-plugin-auth/client/components/ErrorMessage.js rename to plugins/talk-plugin-profile-data/client/components/ErrorMessage.js diff --git a/plugins/talk-plugin-auth/client/components/InputField.css b/plugins/talk-plugin-profile-data/client/components/InputField.css similarity index 100% rename from plugins/talk-plugin-auth/client/components/InputField.css rename to plugins/talk-plugin-profile-data/client/components/InputField.css diff --git a/plugins/talk-plugin-auth/client/components/InputField.js b/plugins/talk-plugin-profile-data/client/components/InputField.js similarity index 100% rename from plugins/talk-plugin-auth/client/components/InputField.js rename to plugins/talk-plugin-profile-data/client/components/InputField.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css b/plugins/talk-plugin-profile-data/client/components/StepProgress.css similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.css rename to plugins/talk-plugin-profile-data/client/components/StepProgress.css diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js b/plugins/talk-plugin-profile-data/client/components/StepProgress.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/components/StepProgress.js rename to plugins/talk-plugin-profile-data/client/components/StepProgress.js diff --git a/plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js similarity index 100% rename from plugins/talk-plugin-auth/client/stream/containers/AccountDeletionRequestedSign.js rename to plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js similarity index 100% rename from plugins/talk-plugin-auth/client/profile-settings/containers/DeleteMyAccount.js rename to plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js diff --git a/plugins/talk-plugin-profile-data/client/index.js b/plugins/talk-plugin-profile-data/client/index.js index fee9f2129..91664ac23 100644 --- a/plugins/talk-plugin-profile-data/client/index.js +++ b/plugins/talk-plugin-profile-data/client/index.js @@ -1,10 +1,13 @@ import DownloadCommentHistory from './containers/DownloadCommentHistory'; +import DeleteMyAccount from './containers/DeleteMyAccount'; +import AccountDeletionRequestedSign from './AccountDeletionRequestedSign'; import translations from './translations.yml'; import graphql from './graphql'; export default { slots: { - profileSettings: [DownloadCommentHistory], + stream: [AccountDeletionRequestedSign], + profileSettings: [DownloadCommentHistory, DeleteMyAccount], }, translations, ...graphql, From 58cc078d256c8e6242f61490b888a99ae18c0549 Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 2 May 2018 14:03:21 -0300 Subject: [PATCH 18/47] Moving gdpr to `talk-plugin-profile-data` --- .../client/components/DeleteMyAccountStep3.js | 2 +- plugins/talk-plugin-profile-data/client/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js index 45dca8f97..3205cd225 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; -import InputField from '../../components/InputField'; +import InputField from './InputField'; const initialState = { showError: false, diff --git a/plugins/talk-plugin-profile-data/client/index.js b/plugins/talk-plugin-profile-data/client/index.js index 91664ac23..bbd30b660 100644 --- a/plugins/talk-plugin-profile-data/client/index.js +++ b/plugins/talk-plugin-profile-data/client/index.js @@ -1,6 +1,6 @@ import DownloadCommentHistory from './containers/DownloadCommentHistory'; import DeleteMyAccount from './containers/DeleteMyAccount'; -import AccountDeletionRequestedSign from './AccountDeletionRequestedSign'; +import AccountDeletionRequestedSign from './containers/AccountDeletionRequestedSign'; import translations from './translations.yml'; import graphql from './graphql'; From ccb62263c190432135a9878ea55de60415cee099 Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 2 May 2018 20:08:29 -0300 Subject: [PATCH 19/47] checking me null --- .../client/containers/AccountDeletionRequestedSign.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js index d842ec43f..9ac152743 100644 --- a/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js +++ b/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js @@ -21,5 +21,5 @@ export default compose( connect(null, mapDispatchToProps), withCancelAccountDeletion, withData, - excludeIf(props => !props.root.me.scheduledDeletionDate) + excludeIf(({ root: { me } }) => !me || !me.scheduledDeletionDate) )(AccountDeletionRequestedSign); From fff6e1c2317e581befdb1c252fde1ba56022ef5f Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 3 May 2018 10:24:43 -0300 Subject: [PATCH 20/47] Review changes --- client/coral-framework/graphql/mutations.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index 19d133872..cc6b35fa6 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -1,6 +1,7 @@ import { gql } from 'react-apollo'; import withMutation from '../hocs/withMutation'; import update from 'immutability-helper'; +import moment from 'moment'; function convertItemType(item_type) { switch (item_type) { @@ -658,7 +659,7 @@ export const withRequestAccountDeletion = withMutation( return mutate({ variables: {}, update: proxy => { - const CancelAccountDeletionQuery = gql` + const RequestAccountDeletionQuery = gql` query Talk_CancelAccountDeletion { me { id @@ -667,16 +668,22 @@ export const withRequestAccountDeletion = withMutation( } `; - const prev = proxy.readQuery({ query: CancelAccountDeletionQuery }); + const prev = proxy.readQuery({ + query: RequestAccountDeletionQuery, + }); + + const scheduledDeletionDate = moment() + .add(12, 'hours') + .toDate(); const data = update(prev, { me: { - scheduledDeletionDate: { $set: new Date() }, + scheduledDeletionDate: { $set: scheduledDeletionDate }, }, }); proxy.writeQuery({ - query: CancelAccountDeletionQuery, + query: RequestAccountDeletionQuery, data, }); }, From a42135c3bb6067e44264833283bf0219c6b5e822 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 3 May 2018 08:39:34 -0600 Subject: [PATCH 21/47] merge bug --- .../server/mutators.js | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/plugins/talk-plugin-profile-data/server/mutators.js b/plugins/talk-plugin-profile-data/server/mutators.js index b1756a34b..d3785c951 100644 --- a/plugins/talk-plugin-profile-data/server/mutators.js +++ b/plugins/talk-plugin-profile-data/server/mutators.js @@ -129,6 +129,17 @@ async function cancelDeletion({ user, connectors: { models: { User } } }) { ); } +// downloadUser will return the download file url that can be used to directly +// download the archive. +async function downloadUser(ctx, userID) { + if (ctx.user.role !== 'ADMIN') { + throw new ErrNotAuthorized(); + } + + const { downloadFileURL } = await generateDownloadLinks(ctx, userID); + return downloadFileURL; +} + module.exports = ctx => ctx.user ? { @@ -136,6 +147,7 @@ module.exports = ctx => requestDownloadLink: () => sendDownloadLink(ctx), requestDeletion: () => requestDeletion(ctx), cancelDeletion: () => cancelDeletion(ctx), + download: userID => downloadUser(ctx, userID), }, } : { @@ -143,22 +155,6 @@ module.exports = ctx => requestDownloadLink: () => Promise.reject(new ErrNotAuthorized()), requestDeletion: () => Promise.reject(new ErrNotAuthorized()), cancelDeletion: () => Promise.reject(new ErrNotAuthorized()), + download: () => Promise.reject(new ErrNotAuthorized()), }, }; -// downloadUser will return the download file url that can be used to directly -// download the archive. -async function downloadUser(ctx, userID) { - const { downloadFileURL } = await generateDownloadLinks(ctx, userID); - return downloadFileURL; -} - -module.exports = ctx => ({ - User: { - requestDownloadLink: () => sendDownloadLink(ctx), - download: - // Only ADMIN users can execute an account download. - ctx.user && ctx.user.role === 'ADMIN' - ? userID => downloadUser(ctx, userID) - : () => Promise.reject(new ErrNotAuthorized()), - }, -}); From 225a04fed1473c60e98e37d68a67de4556da2f94 Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Thu, 3 May 2018 10:53:16 -0400 Subject: [PATCH 22/47] Copy fixes --- .../client/components/DeleteMyAccountFinalStep.js | 9 ++------- .../client/components/DeleteMyAccountStep1.js | 2 +- .../client/components/DeleteMyAccountStep3.js | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js index ccbbf61fa..4cda90347 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js @@ -22,10 +22,8 @@ const DeleteMyAccountFinalStep = props => (

- Changed your mind? Simply sign in to your account again - before this time and click “ - Cancel Account Deletion Request. - ” + Changed your mind? Simply go to your account again before + this time and click “Cancel Account Deletion Request.

@@ -41,9 +39,6 @@ const DeleteMyAccountFinalStep = props => ( > Done - - Note: You will be immediately signed out of your account. -

); diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js index e74611b05..ace020c65 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js @@ -15,7 +15,7 @@ const DeleteMyAccountStep1 = props => ( Can I still write comments until my account is deleted?{' '}

- No. Once youve requested account deletion, you can no longer write + No. Once you have requested account deletion, you can no longer write comments, reply to comments, or select reactions.

diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js index 3205cd225..4c87bbcf2 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js @@ -56,7 +56,7 @@ class DeleteMyAccountStep3 extends React.Component { /> Date: Thu, 3 May 2018 08:59:26 -0600 Subject: [PATCH 23/47] moved hoc's into plugin --- client/coral-framework/graphql/mutations.js | 110 ------------------ plugin-api/beta/client/hocs/index.js | 3 - .../AccountDeletionRequestedSign.js | 2 +- .../client/containers/DeleteMyAccount.js | 2 +- .../client/mutations.js | 104 ++++++++++++++++- 5 files changed, 101 insertions(+), 120 deletions(-) diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index cc6b35fa6..228911d4a 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -1,7 +1,6 @@ import { gql } from 'react-apollo'; import withMutation from '../hocs/withMutation'; import update from 'immutability-helper'; -import moment from 'moment'; function convertItemType(item_type) { switch (item_type) { @@ -645,115 +644,6 @@ export const withChangePassword = withMutation( } ); -export const withRequestAccountDeletion = withMutation( - gql` - mutation RequestAccountDeletion { - requestAccountDeletion { - ...RequestAccountDeletionResponse - } - } - `, - { - props: ({ mutate }) => ({ - requestAccountDeletion: () => { - return mutate({ - variables: {}, - update: proxy => { - const RequestAccountDeletionQuery = gql` - query Talk_CancelAccountDeletion { - me { - id - scheduledDeletionDate - } - } - `; - - const prev = proxy.readQuery({ - query: RequestAccountDeletionQuery, - }); - - const scheduledDeletionDate = moment() - .add(12, 'hours') - .toDate(); - - const data = update(prev, { - me: { - scheduledDeletionDate: { $set: scheduledDeletionDate }, - }, - }); - - proxy.writeQuery({ - query: RequestAccountDeletionQuery, - data, - }); - }, - }); - }, - }), - } -); - -export const withRequestDownloadLink = withMutation( - gql` - mutation RequestDownloadLink { - requestDownloadLink { - ...RequestDownloadLinkResponse - } - } - `, - { - props: ({ mutate }) => ({ - requestDownloadLink: () => { - return mutate({ - variables: {}, - }); - }, - }), - } -); - -export const withCancelAccountDeletion = withMutation( - gql` - mutation RequestDownloadLink { - cancelAccountDeletion { - ...CancelAccountDeletionResponse - } - } - `, - { - props: ({ mutate }) => ({ - cancelAccountDeletion: () => { - return mutate({ - variables: {}, - update: proxy => { - const CancelAccountDeletionQuery = gql` - query Talk_CancelAccountDeletion { - me { - id - scheduledDeletionDate - } - } - `; - - const prev = proxy.readQuery({ query: CancelAccountDeletionQuery }); - - const data = update(prev, { - me: { - scheduledDeletionDate: { $set: null }, - }, - }); - - proxy.writeQuery({ - query: CancelAccountDeletionQuery, - data, - }); - }, - }); - }, - }), - } -); - export const withUpdateAssetSettings = withMutation( gql` mutation UpdateAssetSettings($id: ID!, $input: AssetSettingsInput!) { diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index e86c96606..d7ca5fce9 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -25,9 +25,6 @@ export { withUnbanUser, withStopIgnoringUser, withSetCommentStatus, - withRequestAccountDeletion, - withRequestDownloadLink, - withCancelAccountDeletion, withChangePassword, withChangeUsername, } from 'coral-framework/graphql/mutations'; diff --git a/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js index 9ac152743..9866045a3 100644 --- a/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js +++ b/plugins/talk-plugin-profile-data/client/containers/AccountDeletionRequestedSign.js @@ -3,7 +3,7 @@ import { bindActionCreators } from 'redux'; import { connect, withFragments, excludeIf } from 'plugin-api/beta/client/hocs'; import AccountDeletionRequestedSign from '../components/AccountDeletionRequestedSign'; import { notify } from 'coral-framework/actions/notification'; -import { withCancelAccountDeletion } from 'plugin-api/beta/client/hocs'; +import { withCancelAccountDeletion } from '../mutations'; const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); diff --git a/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js index a9c033853..84d0b9a5c 100644 --- a/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js +++ b/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js @@ -6,7 +6,7 @@ import { notify } from 'coral-framework/actions/notification'; import { withRequestAccountDeletion, withCancelAccountDeletion, -} from 'plugin-api/beta/client/hocs'; +} from '../mutations'; const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); diff --git a/plugins/talk-plugin-profile-data/client/mutations.js b/plugins/talk-plugin-profile-data/client/mutations.js index a370c9ff0..d39802808 100644 --- a/plugins/talk-plugin-profile-data/client/mutations.js +++ b/plugins/talk-plugin-profile-data/client/mutations.js @@ -1,19 +1,113 @@ import { withMutation } from 'plugin-api/beta/client/hocs'; import { gql } from 'react-apollo'; +import update from 'immutability-helper'; +import moment from 'moment'; export const withRequestDownloadLink = withMutation( gql` - mutation DownloadCommentHistory { + mutation RequestDownloadLink { requestDownloadLink { - errors { - translation_key - } + ...RequestDownloadLinkResponse } } `, { props: ({ mutate }) => ({ - requestDownloadLink: () => mutate({ variables: {} }), + requestDownloadLink: () => { + return mutate({ + variables: {}, + }); + }, + }), + } +); + +export const withRequestAccountDeletion = withMutation( + gql` + mutation RequestAccountDeletion { + requestAccountDeletion { + ...RequestAccountDeletionResponse + } + } + `, + { + props: ({ mutate }) => ({ + requestAccountDeletion: () => { + return mutate({ + variables: {}, + update: proxy => { + const RequestAccountDeletionQuery = gql` + query Talk_CancelAccountDeletion { + me { + id + scheduledDeletionDate + } + } + `; + + const prev = proxy.readQuery({ + query: RequestAccountDeletionQuery, + }); + + const scheduledDeletionDate = moment() + .add(12, 'hours') + .toDate(); + + const data = update(prev, { + me: { + scheduledDeletionDate: { $set: scheduledDeletionDate }, + }, + }); + + proxy.writeQuery({ + query: RequestAccountDeletionQuery, + data, + }); + }, + }); + }, + }), + } +); + +export const withCancelAccountDeletion = withMutation( + gql` + mutation RequestDownloadLink { + cancelAccountDeletion { + ...CancelAccountDeletionResponse + } + } + `, + { + props: ({ mutate }) => ({ + cancelAccountDeletion: () => { + return mutate({ + variables: {}, + update: proxy => { + const CancelAccountDeletionQuery = gql` + query Talk_CancelAccountDeletion { + me { + id + scheduledDeletionDate + } + } + `; + + const prev = proxy.readQuery({ query: CancelAccountDeletionQuery }); + + const data = update(prev, { + me: { + scheduledDeletionDate: { $set: null }, + }, + }); + + proxy.writeQuery({ + query: CancelAccountDeletionQuery, + data, + }); + }, + }); + }, }), } ); From ee0f734705b1c423088457b85b0ecd7073667fea Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 3 May 2018 09:13:44 -0600 Subject: [PATCH 24/47] cleaned up download mutations --- client/coral-framework/graphql/fragments.js | 3 --- plugin-api/beta/client/utils/index.js | 1 + .../components/DownloadCommentHistory.js | 22 ++++++++++++++----- .../containers/DownloadCommentHistory.js | 9 +++++++- .../client/graphql.js | 10 ++++++++- .../client/mutations.js | 6 +---- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/client/coral-framework/graphql/fragments.js b/client/coral-framework/graphql/fragments.js index 94021d133..c5704f719 100644 --- a/client/coral-framework/graphql/fragments.js +++ b/client/coral-framework/graphql/fragments.js @@ -26,9 +26,6 @@ export default { 'UpdateAssetSettingsResponse', 'UpdateAssetStatusResponse', 'UpdateSettingsResponse', - 'RequestAccountDeletionResponse', - 'RequestDownloadLinkResponse', - 'CancelAccountDeletionResponse', 'ChangePasswordResponse' ), }; diff --git a/plugin-api/beta/client/utils/index.js b/plugin-api/beta/client/utils/index.js index 3fe742569..aeb9841f9 100644 --- a/plugin-api/beta/client/utils/index.js +++ b/plugin-api/beta/client/utils/index.js @@ -8,4 +8,5 @@ export { getErrorMessages, getDefinitionName, getShallowChanges, + createDefaultResponseFragments, } from 'coral-framework/utils'; diff --git a/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js b/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js index 06fa1fa89..398e2a640 100644 --- a/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js +++ b/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { t } from 'plugin-api/beta/client/services'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DownloadCommentHistory.css'; +import { getErrorMessages } from 'coral-framework/utils'; export const readableDuration = durAsHours => { const durAsDays = Math.ceil(durAsHours / 24); @@ -19,14 +20,25 @@ export const readableDuration = durAsHours => { class DownloadCommentHistory extends Component { static propTypes = { requestDownloadLink: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, root: PropTypes.object.isRequired, }; + requestDownloadLink = async () => { + const { requestDownloadLink, notify } = this.props; + try { + await requestDownloadLink(); + notify( + 'success', + 'Account Download Preparing - Check your email shortly for a download link' + ); + } catch (err) { + notify('error', getErrorMessages(err)); + } + }; + render() { - const { - root: { me: { lastAccountDownload } }, - requestDownloadLink, - } = this.props; + const { root: { me: { lastAccountDownload } } } = this.props; const now = new Date(); const lastAccountDownloadDate = @@ -52,7 +64,7 @@ class DownloadCommentHistory extends Component {

)} {canRequestDownload ? ( -
diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js index 9bc5573a1..28ead86de 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js @@ -6,6 +6,7 @@ import styles from './DeleteMyAccount.css'; import { Button } from 'plugin-api/beta/client/components/ui'; import DeleteMyAccountDialog from './DeleteMyAccountDialog'; import { getErrorMessages } from 'coral-framework/utils'; +import { t } from 'plugin-api/beta/client/services'; const initialState = { showDialog: false }; @@ -30,7 +31,7 @@ class DeleteMyAccount extends React.Component { await cancelAccountDeletion(); notify( 'success', - 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.' + t('talk-plugin-profile-data.delete_request.account_deletion_requested') ); } catch (err) { notify('error', getErrorMessages(err)); @@ -41,7 +42,10 @@ class DeleteMyAccount extends React.Component { const { requestAccountDeletion, notify } = this.props; try { await requestAccountDeletion(); - notify('success', 'Account Deletion Requested'); + notify( + 'success', + t('talk-plugin-profile-data.delete_request.account_deletion_requested') + ); } catch (err) { notify('error', getErrorMessages(err)); } @@ -62,7 +66,7 @@ class DeleteMyAccount extends React.Component { 'talk-plugin-auth--delete-my-account-description' )} > - Delete My Account + {t('talk-plugin-profile-data.delete_request.delete_my_account')}

- Deleting your account will permanently erase your profile and remove - all your comments from this site. + {t( + 'talk-plugin-profile-data.delete_request.delete_my_account_description' + )}

{scheduledDeletionDate && - `You have already submitted a request to delete your account. - Your account will be deleted on ${moment( - scheduledDeletionDate - ).format('MMM Do YYYY, h:mm:ss a')}. You may - cancel the request until that time`} + t( + 'talk-plugin-profile-data.delete_request.already_submitted_request_description', + moment(scheduledDeletionDate).format('MMM Do YYYY, h:mm:ss a') + )}

{scheduledDeletionDate ? ( ) : ( )}
diff --git a/plugins/talk-plugin-profile-data/client/translations.yml b/plugins/talk-plugin-profile-data/client/translations.yml index ee6dc4e51..e0b275224 100644 --- a/plugins/talk-plugin-profile-data/client/translations.yml +++ b/plugins/talk-plugin-profile-data/client/translations.yml @@ -10,3 +10,13 @@ en: days: "{0} days" hour: "{0} hour" day: "{0} day" + delete_request: + account_deletion_cancelled: 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.' + account_deletion_requested: 'Account Deletion Requested' + received_on: "A request to delete your account was received on " + cancel_request_description: "If you would like to continue leaving comments, replies or reactions, you may cancel your request to delete your account below" + before: "before" + cancel_account_deletion_request: "Cancel Account Deletion Request" + delete_my_account: "Delete My Account" + delete_my_account_description: "Deleting your account will permanently erase your profile and remove all your comments from this site." + already_submitted_request_description: "You have already submitted a request to delete your account. Your account will be deleted on {0}. You may cancel the request until that time" \ No newline at end of file From 0caa82c1c4ba14783808fc8a5741803f0da3048b Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Thu, 3 May 2018 11:59:27 -0400 Subject: [PATCH 29/47] Typo --- .../client/components/DeleteMyAccountFinalStep.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js index d3604d1ae..ebf7200b6 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js @@ -30,8 +30,8 @@ const DeleteMyAccountFinalStep = props => (

- Tell us why. Wed like to know why you chose to delete - your account. Send us feedback on our comment system by emailing. + Tell us why. We would like to know why you chose to + delete your account. Send us feedback on our comment system by emailing.

From 6485b1f080e4c0b81d05ddf5c9ed1e9df000c262 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 3 May 2018 10:02:33 -0600 Subject: [PATCH 30/47] added email to final step --- .../src/routes/Configure/components/OrganizationSettings.js | 2 +- .../client/components/DeleteMyAccount.js | 6 +++++- .../client/components/DeleteMyAccountDialog.js | 4 +++- .../client/components/DeleteMyAccountFinalStep.js | 6 +++++- .../client/containers/DeleteMyAccount.js | 3 +++ plugins/talk-plugin-profile-data/client/mutations.js | 1 - 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/client/coral-admin/src/routes/Configure/components/OrganizationSettings.js b/client/coral-admin/src/routes/Configure/components/OrganizationSettings.js index f3daeffc2..3505ef7b5 100644 --- a/client/coral-admin/src/routes/Configure/components/OrganizationSettings.js +++ b/client/coral-admin/src/routes/Configure/components/OrganizationSettings.js @@ -57,7 +57,7 @@ class OrganizationSettings extends React.Component { } const updater = { organizationContactEmail: { $set: email } }; - const errorUpdater = { organizationEmail: { $set: error } }; + const errorUpdater = { organizationContactEmail: { $set: error } }; this.props.updatePending({ updater, errorUpdater }); }; diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js index 982437de0..dc95c4b9e 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js @@ -48,7 +48,10 @@ class DeleteMyAccount extends React.Component { }; render() { - const { me: { scheduledDeletionDate } } = this.props.root; + const { + me: { scheduledDeletionDate }, + settings: { organizationContactEmail }, + } = this.props.root; return (

@@ -81,6 +81,7 @@ class DeleteMyAccountDialog extends React.Component { {step === 4 && ( )} @@ -94,6 +95,7 @@ DeleteMyAccountDialog.propTypes = { closeDialog: PropTypes.func.isRequired, requestAccountDeletion: PropTypes.func.isRequired, scheduledDeletionDate: PropTypes.string, + organizationContactEmail: PropTypes.string.isRequired, }; export default DeleteMyAccountDialog; diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js index ebf7200b6..75a0b3aeb 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountFinalStep.js @@ -31,7 +31,10 @@ const DeleteMyAccountFinalStep = props => (

Tell us why. We would like to know why you chose to - delete your account. Send us feedback on our comment system by emailing. + delete your account. Send us feedback on our comment system by emailing{' '} + + {props.organizationContactEmail} + .

@@ -49,6 +52,7 @@ const DeleteMyAccountFinalStep = props => ( DeleteMyAccountFinalStep.propTypes = { finish: PropTypes.func.isRequired, scheduledDeletionDate: PropTypes.string.isRequired, + organizationContactEmail: PropTypes.string.isRequired, }; export default DeleteMyAccountFinalStep; diff --git a/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js index 84d0b9a5c..0a81107f5 100644 --- a/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js +++ b/plugins/talk-plugin-profile-data/client/containers/DeleteMyAccount.js @@ -16,6 +16,9 @@ const withData = withFragments({ me { scheduledDeletionDate } + settings { + organizationContactEmail + } } `, }); diff --git a/plugins/talk-plugin-profile-data/client/mutations.js b/plugins/talk-plugin-profile-data/client/mutations.js index d2a8881b8..c7ca68950 100644 --- a/plugins/talk-plugin-profile-data/client/mutations.js +++ b/plugins/talk-plugin-profile-data/client/mutations.js @@ -32,7 +32,6 @@ export const withRequestAccountDeletion = withMutation( return mutate({ variables: {}, update: proxy => { - debugger; const RequestAccountDeletionQuery = gql` query Talk_CancelAccountDeletion { me { From 375f1bb6b1ab2413977ee7bcd711705db39e509c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 3 May 2018 10:07:27 -0600 Subject: [PATCH 31/47] copy fixes --- .../AccountDeletionRequestedSign.js | 4 +-- .../client/components/DeleteMyAccount.js | 26 +++++++++---------- .../components/DeleteMyAccountFinalStep.js | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js index 31f65ffa7..f1d85e4e6 100644 --- a/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js +++ b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js @@ -24,11 +24,11 @@ class AccountDeletionRequestedSign extends React.Component { const { me: { scheduledDeletionDate } } = this.props.root; const deletionScheduledFor = moment(scheduledDeletionDate).format( - 'MMM Do YYYY, h:mm:ss a' + 'MMM Do YYYY, h:mm a' ); const deletionScheduledOn = moment(scheduledDeletionDate) .subtract(24, 'hours') - .format('MMM Do YYYY, h:mm:ss a'); + .format('MMM Do YYYY, h:mm a'); return (
diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js index dc95c4b9e..1c7c12d16 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccount.js @@ -78,19 +78,19 @@ class DeleteMyAccount extends React.Component { Deleting your account will permanently erase your profile and remove all your comments from this site.

-

- {scheduledDeletionDate && - `You have already submitted a request to delete your account. - Your account will be deleted on ${moment( - scheduledDeletionDate - ).format('MMM Do YYYY, h:mm:ss a')}. You may - cancel the request until that time`} -

+ {scheduledDeletionDate && ( +

+ You have already submitted a request to delete your account. Your + account will be deleted on{' '} + {moment(scheduledDeletionDate).format('MMM Do YYYY, h:mm a')}. You + may cancel the request until that time. +

+ )} {scheduledDeletionDate ? (
From f6d3f4cb14a8ebb24657bc686068222c550f3fb2 Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 3 May 2018 13:32:52 -0300 Subject: [PATCH 32/47] translations --- .../components/DeleteMyAccountDialog.js | 5 ++- .../components/DeleteMyAccountFinalStep.js | 31 +++++++++++++------ .../client/components/DeleteMyAccountStep0.js | 13 ++++---- .../client/components/DeleteMyAccountStep1.js | 21 +++++++------ .../client/components/DeleteMyAccountStep2.js | 13 ++++---- .../client/components/DeleteMyAccountStep3.js | 18 ++++++----- .../components/DownloadCommentHistory.js | 5 +-- .../client/translations.yml | 30 +++++++++++++++++- 8 files changed, 91 insertions(+), 45 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js index 35069384c..f6ab9c2ce 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountDialog.js @@ -8,6 +8,7 @@ import DeleteMyAccountStep1 from './DeleteMyAccountStep1'; import DeleteMyAccountStep2 from './DeleteMyAccountStep2'; import DeleteMyAccountStep3 from './DeleteMyAccountStep3'; import DeleteMyAccountFinalStep from './DeleteMyAccountFinalStep'; +import { t } from 'plugin-api/beta/client/services'; const initialState = { step: 0, formData: {} }; @@ -47,7 +48,9 @@ class DeleteMyAccountDialog extends React.Component { × -

Delete My Account

+

+ {t('talk-plugin-profile-data.delete_request.delete_my_account')} +

{step === 0 && ( (

- Your request has been submitted and confirmation has been sent to the - email address associated with your account. + {t( + 'talk-plugin-profile-data.delete_request.your_request_submitted_description' + )}

- Your account is scheduled to be deleted at: + {t( + 'talk-plugin-profile-data.delete_request.your_account_deletion_scheduled' + )} - Account Deletion Date and Time + {0}

- Changed your mind? Simply go to your account again before - this time and click “Cancel Account Deletion Request.” + + {' '} + {t('talk-plugin-profile-data.delete_request.changed_your_mind')} + {' '} + {t('talk-plugin-profile-data.delete_request.simply_go_to')} “ + {t( + 'talk-plugin-profile-data.delete_request.cancel_account_deletion_request' + )}. +

- Tell us why. Wed like to know why you chose to delete - your account. Send us feedback on our comment system by emailing. + + {t('talk-plugin-profile-data.delete_request.tell_us_why')}. + {' '} + {t('talk-plugin-profile-data.delete_request.feedback_copy')}

@@ -37,7 +50,7 @@ const DeleteMyAccountFinalStep = props => ( onClick={props.finish} full > - Done + {t('talk-plugin-profile-data.delete_request.done')}
diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js index 901466d3b..468c96e94 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep0.js @@ -3,29 +3,30 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button, Icon } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; +import { t } from 'plugin-api/beta/client/services'; const DeleteMyAccountStep0 = props => (

- You are attempting to delete your account. This means: + {t('talk-plugin-profile-data.delete_request.you_are_attempting')}

  • - All of your comments are removed from this site + {t('talk-plugin-profile-data.delete_request.item_1')}
  • - All of your comments are deleted from our database + {t('talk-plugin-profile-data.delete_request.item_2')}
  • - Your username and email address are removed from our system + {t('talk-plugin-profile-data.delete_request.item_3')}
@@ -34,13 +35,13 @@ const DeleteMyAccountStep0 = props => ( className={cn(styles.button, styles.cancel)} onClick={props.cancel} > - Cancel + {t('talk-plugin-profile-data.delete_request.cancel')}
diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js index ace020c65..7408df688 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js @@ -3,33 +3,34 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; +import { t } from 'plugin-api/beta/client/services'; const DeleteMyAccountStep1 = props => (
-

When will my account be deleted?

-

- Your account will be deleted 24 hours after your request has been - submitted. -

- Can I still write comments until my account is deleted?{' '} + {t('talk-plugin-profile-data.delete_request.step1.subtitle')}

- No. Once you have requested account deletion, you can no longer write - comments, reply to comments, or select reactions. + {t('talk-plugin-profile-data.delete_request.step1.description')} +

+

+ {t('talk-plugin-profile-data.delete_request.step1.subtitle_2')} +

+

+ {t('talk-plugin-profile-data.delete_request.step1.description_2')}

diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js index 8ef14445e..8976c7dcd 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep2.js @@ -3,18 +3,17 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; +import { t } from 'plugin-api/beta/client/services'; const DeleteMyAccountStep2 = props => (

- Before your account is deleted, we recommend you download your comment - history for your records. After your account is deleted, you will be - unable to request your comment history. + {t('talk-plugin-profile-data.delete_request.step2.description')}

- To download your comment history go to: + {t('talk-plugin-profile-data.delete_request.step2.to_download')} - My Profile {`>`} Download My Comment History + {t('talk-plugin-profile-data.delete_request.step2.path')}

@@ -22,13 +21,13 @@ const DeleteMyAccountStep2 = props => ( className={cn(styles.button, styles.cancel)} onClick={props.cancel} > - Cancel + {t('talk-plugin-profile-data.delete_request.step2.cancel')}
diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js index 4c87bbcf2..dfbe9bf1f 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep3.js @@ -4,6 +4,7 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; import InputField from './InputField'; +import { t } from 'plugin-api/beta/client/services'; const initialState = { showError: false, @@ -42,11 +43,10 @@ class DeleteMyAccountStep3 extends React.Component { return (

- Are you sure you want to delete your account? + {t('talk-plugin-profile-data.delete_request.step3.subtitle')}

- To confirm you would like to delete your account please type in the - following phrase into the text box below: + {t('talk-plugin-profile-data.delete_request.step3.description')}

@@ -71,13 +75,13 @@ class DeleteMyAccountStep3 extends React.Component { className={cn(styles.button, styles.cancel)} onClick={this.props.cancel} > - Cancel + {t('talk-plugin-profile-data.delete_request.cancel')}

diff --git a/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js b/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js index 398e2a640..feff6b582 100644 --- a/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js +++ b/plugins/talk-plugin-profile-data/client/components/DownloadCommentHistory.js @@ -28,10 +28,7 @@ class DownloadCommentHistory extends Component { const { requestDownloadLink, notify } = this.props; try { await requestDownloadLink(); - notify( - 'success', - 'Account Download Preparing - Check your email shortly for a download link' - ); + notify('success', t('download_request.download_preparing')); } catch (err) { notify('error', getErrorMessages(err)); } diff --git a/plugins/talk-plugin-profile-data/client/translations.yml b/plugins/talk-plugin-profile-data/client/translations.yml index e0b275224..839154446 100644 --- a/plugins/talk-plugin-profile-data/client/translations.yml +++ b/plugins/talk-plugin-profile-data/client/translations.yml @@ -10,6 +10,7 @@ en: days: "{0} days" hour: "{0} hour" day: "{0} day" + download_preparing: "Account Download Preparing - Check your email shortly for a download link" delete_request: account_deletion_cancelled: 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.' account_deletion_requested: 'Account Deletion Requested' @@ -19,4 +20,31 @@ en: cancel_account_deletion_request: "Cancel Account Deletion Request" delete_my_account: "Delete My Account" delete_my_account_description: "Deleting your account will permanently erase your profile and remove all your comments from this site." - already_submitted_request_description: "You have already submitted a request to delete your account. Your account will be deleted on {0}. You may cancel the request until that time" \ No newline at end of file + already_submitted_request_description: "You have already submitted a request to delete your account. Your account will be deleted on {0}. You may cancel the request until that time" + your_request_submitted_description: "Your request has been submitted and confirmation has been sent to the email address associated with your account." + your_account_deletion_scheduled: "Your account is scheduled to be deleted at:" + changed_your_mind: "Changed your mind?" + simply_go_to: "Simply go to your account again before this time and click" + tell_us_why: "Tell us why" + feedback_copy: "We'd like to know why you chose to delete your account. Send us feedback on our comment system by emailing." + done: "Done" + cancel: "Cancel" + proceed: "Proceed" + input_is_not_correct: "The input is not correct" + you_are_attempting: "You are attempting to delete your account. This means:" + item_1: "All of your comments are removed from this site" + item_2: "All of your comments are deleted from our database" + item_3: "Your username and email address are removed from our system" + step1: + subtitle: "When will my account be deleted?" + description: "Your account will be deleted 24 hours after your request has been submitted." + subtitle_2: "Can I still write comments until my account is deleted?" + description_2: "No. Once you have requested account deletion, you can no longer write comments, reply to comments, or select reactions." + step2: + description: "Before your account is deleted, we recommend you download your comment history for your records. After your account is deleted, you will be unable to request your comment history." + to_download: "To download your comment history go to:" + path: "My Profile > Download My Comment History" + step3: + subtitle: "Are you sure you want to delete your account?" + description: "To confirm you would like to delete your account please type in the following phrase into the text box below:" + type_to_confirm: "Type phrase below to confirm" From 287cff289b8b66b121b99d7418bccf963843ce72 Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Thu, 3 May 2018 13:04:05 -0400 Subject: [PATCH 33/47] Update copy to reflect ability to take action up until account is deleted --- plugins/talk-plugin-profile-data/client/translations.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/talk-plugin-profile-data/client/translations.yml b/plugins/talk-plugin-profile-data/client/translations.yml index 2a0c9e334..c5fbb8485 100644 --- a/plugins/talk-plugin-profile-data/client/translations.yml +++ b/plugins/talk-plugin-profile-data/client/translations.yml @@ -12,10 +12,10 @@ en: day: "{0} day" download_preparing: "Account Download Preparing - Check your email shortly for a download link" delete_request: - account_deletion_cancelled: 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.' + account_deletion_cancelled: 'Account Deletion Request Cancelled - Your request to delete your account has been cancelled."' account_deletion_requested: 'Account Deletion Requested' received_on: "A request to delete your account was received on " - cancel_request_description: "If you would like to continue leaving comments, replies or reactions, you may cancel your request to delete your account below" + cancel_request_description: "If you would like to reactivate your account, you may cancel your request to delete your account below" before: "before" cancel_account_deletion_request: "Cancel Account Deletion Request" delete_my_account: "Delete My Account" @@ -40,7 +40,7 @@ en: subtitle: "When will my account be deleted?" description: "Your account will be deleted 24 hours after your request has been submitted." subtitle_2: "Can I still write comments until my account is deleted?" - description_2: "No. Once you have requested account deletion, you can no longer write comments, reply to comments, or select reactions." + description_2: "Yes, you can still comment, reply, and react to comments until the 24 hours expires." step_2: description: "Before your account is deleted, we recommend you download your comment history for your records. After your account is deleted, you will be unable to request your comment history." to_download: "To download your comment history go to:" From 06b08756e7b89fa7f8accea5bebc118026bb3b8a Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 3 May 2018 11:36:07 -0600 Subject: [PATCH 34/47] added durations to configuration file --- .../AccountDeletionRequestedSign.js | 3 ++- .../client/components/DeleteMyAccountStep1.js | 5 ++-- .../components/DownloadCommentHistory.js | 6 +++-- .../client/translations.yml | 6 ++--- plugins/talk-plugin-profile-data/config.json | 4 +++ .../server/mutators.js | 26 +++++++++++++------ 6 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 plugins/talk-plugin-profile-data/config.json diff --git a/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js index 60e4d4bc6..e0d5ab255 100644 --- a/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js +++ b/plugins/talk-plugin-profile-data/client/components/AccountDeletionRequestedSign.js @@ -6,6 +6,7 @@ import moment from 'moment'; import { Button, Icon } from 'plugin-api/beta/client/components/ui'; import styles from './AccountDeletionRequestedSign.css'; import { getErrorMessages } from 'coral-framework/utils'; +import { scheduledDeletionDelayHours } from '../../config.json'; class AccountDeletionRequestedSign extends React.Component { cancelAccountDeletion = async () => { @@ -25,7 +26,7 @@ class AccountDeletionRequestedSign extends React.Component { 'MMM Do YYYY, h:mm a' ); const deletionScheduledOn = moment(scheduledDeletionDate) - .subtract(24, 'hours') + .subtract(scheduledDeletionDelayHours, 'hours') .format('MMM Do YYYY, h:mm a'); return ( diff --git a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js index dc137e41e..491c962cf 100644 --- a/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js +++ b/plugins/talk-plugin-profile-data/client/components/DeleteMyAccountStep1.js @@ -4,16 +4,17 @@ import cn from 'classnames'; import { Button } from 'plugin-api/beta/client/components/ui'; import styles from './DeleteMyAccountStep.css'; import { t } from 'plugin-api/beta/client/services'; +import { scheduledDeletionDelayHours } from '../../config.json'; const DeleteMyAccountStep1 = props => (

{t('delete_request.step_1.subtitle')}

- {t('delete_request.step_1.description')} + {t('delete_request.step_1.description', scheduledDeletionDelayHours)}

{t('delete_request.step_1.subtitle_2')}

- {t('delete_request.step_1.description_2')} + {t('delete_request.step_1.description_2', scheduledDeletionDelayHours)}