diff --git a/jsapp/js/components/common/icon.scss b/jsapp/js/components/common/icon.scss index 27bf3670e0..ae08d867bf 100644 --- a/jsapp/js/components/common/icon.scss +++ b/jsapp/js/components/common/icon.scss @@ -43,6 +43,10 @@ $s-icon-xl: 28px; color: colors.$kobo-red; } +.k-icon.k-icon--color-blue { + color: colors.$kobo-blue; +} + .k-icon.k-icon--color-amber { color: colors.$kobo-amber; } diff --git a/jsapp/js/components/common/icon.tsx b/jsapp/js/components/common/icon.tsx index b8ce777d37..74625730c4 100644 --- a/jsapp/js/components/common/icon.tsx +++ b/jsapp/js/components/common/icon.tsx @@ -7,7 +7,7 @@ import './icon.scss'; * Check out `icon.scss` file for exact pixel values. */ export type IconSize = 'l' | 'm' | 's' | 'xl' | 'xs' | 'xxs'; -export type IconColor = 'red' | 'storm' | 'teal' | 'amber'; +export type IconColor = 'red' | 'storm' | 'teal' | 'amber' | 'blue'; const DefaultSize = 's'; diff --git a/jsapp/js/components/formLanding.js b/jsapp/js/components/formLanding.js index 71fceb78f6..3e93e12f7d 100644 --- a/jsapp/js/components/formLanding.js +++ b/jsapp/js/components/formLanding.js @@ -365,6 +365,12 @@ class FormLanding extends React.Component { kc_server.href = this.state.deployment__identifier; var kobocollect_url = kc_server.origin; + /* TODO + `deployment__identifier` has been removed from API response. + Stop reading `kc_server` from `deployment__identifier` and use `open_rosa_server` + property provided in `/environment` endpoint + */ + return ( diff --git a/jsapp/js/components/formSubScreens.js b/jsapp/js/components/formSubScreens.js index 4d348bc779..c95765e5bf 100644 --- a/jsapp/js/components/formSubScreens.js +++ b/jsapp/js/components/formSubScreens.js @@ -15,6 +15,8 @@ import RESTServices from './RESTServices'; import LoadingSpinner from 'js/components/common/loadingSpinner'; import {ROUTES} from 'js/router/routerConstants'; import {withRouter} from 'js/router/legacy'; +import sessionStore from 'js/stores/session'; +import TransferProjects from 'js/components/permissions/transferProjects/transferProjects.component'; const ConnectProjects = React.lazy(() => import( @@ -137,9 +139,12 @@ export class FormSubScreens extends React.Component { } renderSharing() { const uid = this.props.params.assetid || this.props.params.uid; + return ( + + ); } diff --git a/jsapp/js/components/modals/koboModal.scss b/jsapp/js/components/modals/koboModal.scss index 1123aa70c7..5c5070002d 100644 --- a/jsapp/js/components/modals/koboModal.scss +++ b/jsapp/js/components/modals/koboModal.scss @@ -65,12 +65,15 @@ $kobo-modal-header-icon-margin: sizes.$x10; padding: $kobo-modal-padding; border-radius: sizes.$x6 sizes.$x6 0 0; - &.kobo-modal__header--red{ + &.kobo-modal__header--red { background-color: color.change(colors.$kobo-red, $alpha: 0.1); } - &.kobo-modal__header--grey{ + &.kobo-modal__header--grey { background-color: colors.$kobo-gray-98; } + &.kobo-modal__header--white { + background-color: colors.$kobo-white; + } h1 { @include mixins.centerRowFlex; diff --git a/jsapp/js/components/modals/koboModalHeader.tsx b/jsapp/js/components/modals/koboModalHeader.tsx index dea0cc3f75..4059ced17d 100644 --- a/jsapp/js/components/modals/koboModalHeader.tsx +++ b/jsapp/js/components/modals/koboModalHeader.tsx @@ -8,7 +8,7 @@ bem.KoboModal__header = makeBem(bem.KoboModal, 'header', 'header'); bem.KoboModal__headerIcon = makeBem(bem.KoboModal, 'header-icon', 'span'); export type KoboModalHeaderIconColors = 'blue' | 'red' | 'storm'; -export type KoboModalHeaderBackgroundColors = 'red' | 'grey'; +export type KoboModalHeaderBackgroundColors = 'red' | 'grey' | 'white'; interface KoboModalHeaderProps { /** Optional icon displayed on the left of the title. */ diff --git a/jsapp/js/components/permissions/sharingForm.component.tsx b/jsapp/js/components/permissions/sharingForm.component.tsx index 91361e52f5..857750020d 100644 --- a/jsapp/js/components/permissions/sharingForm.component.tsx +++ b/jsapp/js/components/permissions/sharingForm.component.tsx @@ -12,6 +12,7 @@ import {replaceBracketsWithLink} from 'js/textUtils'; import {ANON_USERNAME, ANON_USERNAME_URL} from 'js/users/utils'; import {ASSET_TYPES} from 'js/constants'; import {ACCOUNT_ROUTES} from 'js/account/routes'; +import {TransferStatuses} from 'js/components/permissions/transferProjects/transferProjects.api'; import './sharingForm.scss'; // parts import CopyTeamPermissions from './copyTeamPermissions.component'; @@ -162,6 +163,41 @@ export default class SharingForm extends React.Component< } } + /** Check if the recipient of the transfer is the specified user */ + isPendingOwner(username: string) { + return this.state.asset?.project_ownership?.status === + TransferStatuses.Pending && + this.state.asset?.project_ownership?.recipient === username + ? true + : false; + } + + /** Display pending owner if not already included in list of user permissions */ + renderPendingOwner() { + if ( + this.state.asset?.project_ownership?.status === + TransferStatuses.Pending && + !this.state.permissions?.find( + (perm) => + perm.user.name === this.state.asset?.project_ownership?.recipient + ) + ) { + return ( + + ); + } else { + return null; + } + } + render() { if (!this.state.asset || !this.state.permissions) { return ; @@ -217,10 +253,12 @@ export default class SharingForm extends React.Component< assignablePerms={this.state.assignablePerms} permissions={perm.permissions} isUserOwner={perm.user.isOwner} + isPendingOwner={this.isPendingOwner(perm.user.name)} username={perm.user.name} /> ); })} + {this.renderPendingOwner()} {!this.state.isAddUserEditorVisible && (