From e967e1786639fb87e03f178ab0f38b0ec5b46c6b Mon Sep 17 00:00:00 2001 From: Tomas Kikutis Date: Wed, 16 Aug 2023 15:44:37 +0200 Subject: [PATCH 1/3] improve SelectUser component to show and allow filtering by sign off --- .../components/UserActivityWidget.tsx | 3 +- scripts/core/superdesk-api.d.ts | 2 + scripts/core/ui/components/SelectUser.tsx | 112 +++++++++++------- scripts/core/utils.ts | 1 + 4 files changed, 77 insertions(+), 41 deletions(-) diff --git a/scripts/apps/dashboard/user-activity/components/UserActivityWidget.tsx b/scripts/apps/dashboard/user-activity/components/UserActivityWidget.tsx index cefbffc3cc..f4d142b8db 100644 --- a/scripts/apps/dashboard/user-activity/components/UserActivityWidget.tsx +++ b/scripts/apps/dashboard/user-activity/components/UserActivityWidget.tsx @@ -346,12 +346,13 @@ export default class UserActivityWidget extends React.Component >
{ this.props.onUserChange(user); }} horizontalSpacing={true} + clearable={false} /> diff --git a/scripts/core/superdesk-api.d.ts b/scripts/core/superdesk-api.d.ts index c70559391a..3c02189f74 100644 --- a/scripts/core/superdesk-api.d.ts +++ b/scripts/core/superdesk-api.d.ts @@ -1176,6 +1176,8 @@ declare module 'superdesk-api' { disabled?: boolean; autoFocus?: boolean; horizontalSpacing?: boolean; + valueTemplate?: React.ComponentType<{option: IUser}>; + clearable: boolean; } export interface IDropdownTreeGroup { diff --git a/scripts/core/ui/components/SelectUser.tsx b/scripts/core/ui/components/SelectUser.tsx index c1bf37e808..c0f5b49572 100644 --- a/scripts/core/ui/components/SelectUser.tsx +++ b/scripts/core/ui/components/SelectUser.tsx @@ -1,8 +1,9 @@ +/* eslint-disable react/no-multi-comp */ import React from 'react'; import {IPropsSelectUser, IUser, IRestApiResponse} from 'superdesk-api'; import {gettext, getUserSearchMongoQuery} from 'core/utils'; import {UserAvatar} from 'apps/users/components/UserAvatar'; -import {SelectWithTemplate} from 'superdesk-ui-framework/react'; +import {SelectWithTemplate, Spacer} from 'superdesk-ui-framework/react'; import {httpRequestJsonLocal} from 'core/helpers/network'; import {SuperdeskReactComponent} from 'core/SuperdeskReactComponent'; @@ -10,6 +11,52 @@ interface IState { selectedUser: IUser | null | 'loading'; } +const itemTemplate = (props: {option: IUser}) => { + const user: IUser | null = props.option; + + return user == null + ? ( +
+ {gettext('Select a user')} +
+ ) + : ( + + +
+ +
+ + +
{user.display_name}
+
@{user.username}
+
+ +
+ +
{user.sign_off}
+
+ ); +}; + +const valueTemplateDefault = (props: {option: IUser}) => { + const user: IUser | null = props.option; + + return user == null + ? ( +
+ {gettext('Select a user')} +
+ ) + : ( + + + + {user.display_name} + + ); +}; + export class SelectUser extends SuperdeskReactComponent { constructor(props: IPropsSelectUser) { super(props); @@ -37,24 +84,26 @@ export class SelectUser extends SuperdeskReactComponent({ - method: 'GET', - path: `/users/${this.props.selectedUserId}`, - }).then((selectedUser) => { + if (prevProps.selectedUserId !== this.props.selectedUserId) { + // state.user needs to be updated if props.selectedUserId changes + if (this.props.selectedUserId == null) { // eslint-disable-next-line react/no-did-update-set-state - this.setState({selectedUser}); - }); + this.setState({selectedUser: null}); + } else if ( + this.state.selectedUser === 'loading' + || this.state.selectedUser?._id !== this.props.selectedUserId + ) { + // eslint-disable-next-line react/no-did-update-set-state + this.setState({selectedUser: 'loading'}); + + this.asyncHelpers.httpRequestJsonLocal({ + method: 'GET', + path: `/users/${this.props.selectedUserId}`, + }).then((selectedUser) => { + // eslint-disable-next-line react/no-did-update-set-state + this.setState({selectedUser}); + }); + } } } @@ -63,6 +112,8 @@ export class SelectUser extends SuperdeskReactComponent option.display_name} - itemTemplate={ - (props) => { - const user = props.option; - - return user == null - ? ( -
- {gettext('Select a user')} -
- ) - : ( -
- -
-
{user.display_name}
-
@{user.username}
-
-
- ); - } - } + itemTemplate={itemTemplate} + valueTemplate={valueTemplate} areEqual={(a, b) => a._id === b._id} autoFocus={this.props.autoFocus} autoOpen={this.state.selectedUser == null} @@ -137,7 +169,7 @@ export class SelectUser extends SuperdeskReactComponent ); } diff --git a/scripts/core/utils.ts b/scripts/core/utils.ts index 7f8a91971a..bc18522b17 100644 --- a/scripts/core/utils.ts +++ b/scripts/core/utils.ts @@ -187,6 +187,7 @@ export function getUserSearchMongoQuery(searchString: string) { {first_name: {$regex: searchString, $options: '-i'}}, {last_name: {$regex: searchString, $options: '-i'}}, {email: {$regex: searchString, $options: '-i'}}, + {sign_off: {$regex: searchString, $options: '-i'}}, ], }; } From 0547fdff3427c701b9356e5ab078848f580a6c9b Mon Sep 17 00:00:00 2001 From: Tomas Kikutis Date: Wed, 16 Aug 2023 18:02:43 +0200 Subject: [PATCH 2/3] superdesk-ui-framework@3.0.54 --- package-lock.json | 20 ++++++++++---------- package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3c748482a..4aa287078b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -331,9 +331,9 @@ }, "dependencies": { "tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" } } }, @@ -13253,7 +13253,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" } } }, @@ -16253,9 +16253,9 @@ } }, "superdesk-ui-framework": { - "version": "3.0.47", - "resolved": "https://registry.npmjs.org/superdesk-ui-framework/-/superdesk-ui-framework-3.0.47.tgz", - "integrity": "sha512-r6M7a8jCOdS9UOmf629YbcF8LzpaHUFhhMP66FrOSNfntu9uSJn/L7NWdoM7/tcl19wPlL9EMPx+E/E9b6Ibsg==", + "version": "3.0.54", + "resolved": "https://registry.npmjs.org/superdesk-ui-framework/-/superdesk-ui-framework-3.0.54.tgz", + "integrity": "sha512-wWtx2AEJUEShU7v60KteMcPW+vfP0iI3KDnWxnBxsNm6Y7T/nT2ROrd2U5dM/fjNt41jJEiP+AD7mN3ykX8Q4g==", "requires": { "@material-ui/lab": "^4.0.0-alpha.56", "@popperjs/core": "^2.4.0", @@ -16278,9 +16278,9 @@ }, "dependencies": { "@types/node": { - "version": "14.18.53", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", - "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" + "version": "14.18.54", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz", + "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw==" }, "cheerio": { "version": "1.0.0-rc.12", diff --git a/package.json b/package.json index 15cebcf161..b6e8448e6f 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "sass-loader": "6.0.6", "shortid": "2.2.8", "style-loader": "0.20.2", - "superdesk-ui-framework": "^3.0.47", + "superdesk-ui-framework": "^3.0.54", "ts-loader": "3.5.0", "tslint": "5.11.0", "typescript": "~4.9.5", From d7a1663ea1a81e489c69bb71ac49a3f9ea5ae8cf Mon Sep 17 00:00:00 2001 From: Tomas Kikutis Date: Thu, 17 Aug 2023 12:53:54 +0200 Subject: [PATCH 3/3] missing mandatory clearable prop --- scripts/extensions/markForUser/src/get-mark-for-user-modal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/extensions/markForUser/src/get-mark-for-user-modal.tsx b/scripts/extensions/markForUser/src/get-mark-for-user-modal.tsx index e7959a29b2..ae9e1adcda 100644 --- a/scripts/extensions/markForUser/src/get-mark-for-user-modal.tsx +++ b/scripts/extensions/markForUser/src/get-mark-for-user-modal.tsx @@ -78,6 +78,7 @@ export function getMarkForUserModal(options: { onSelect={(selectedUser) => this.setState({selectedUserId: selectedUser._id})} selectedUserId={this.state.selectedUserId} autoFocus={true} + clearable={false} />