[arvados-workbench2] updated: 2.4.0-56-g0bd774be
git repository hosting
git at public.arvados.org
Mon May 23 16:29:47 UTC 2022
Summary of changes:
package.json | 3 +
.../api-client-authorization-service.test.ts | 21 ++++-
.../api-client-authorization-service.ts | 9 ++-
src/store/sharing-dialog/sharing-dialog-actions.ts | 4 +-
.../sharing-dialog/sharing-dialog-component.tsx | 74 +++++++++++++++---
.../sharing-dialog/sharing-dialog.tsx | 4 +-
yarn.lock | 91 +++++++++++++++++++++-
7 files changed, 183 insertions(+), 23 deletions(-)
via 0bd774be1714eb7bb815cef3d44803eac6c735ec (commit)
via 4f26fc6e11a411c11fc481b937c2e073f4858081 (commit)
from 709996fdd46c5993944753fab7919676e0cbd60d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 0bd774be1714eb7bb815cef3d44803eac6c735ec
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Mon May 23 13:26:02 2022 -0300
16115: Adds inline DateTime picker to the sharing URLs dialog.
We're not currently exporting the API.MaxTokenLifetime configuration, so
client-side expires_at validation is not possible; added an explanation note
for the cases when the expiration date is capped by the backend.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/package.json b/package.json
index 210045ba..a8b3ee81 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@date-io/date-fns": "1",
"@fortawesome/fontawesome-svg-core": "1.2.28",
"@fortawesome/free-solid-svg-icons": "5.13.0",
"@fortawesome/react-fontawesome": "0.1.9",
@@ -28,6 +29,7 @@
"caniuse-lite": "1.0.30001299",
"classnames": "2.2.6",
"cwlts": "1.15.29",
+ "date-fns": "^2.28.0",
"debounce": "1.2.0",
"elliptic": "6.5.4",
"file-saver": "2.0.1",
@@ -40,6 +42,7 @@
"lodash-es": "4.17.14",
"lodash.mergewith": "4.6.2",
"lodash.template": "4.5.0",
+ "material-ui-pickers": "^2.2.4",
"mem": "4.0.0",
"moment": "2.29.1",
"parse-duration": "0.4.4",
diff --git a/src/views-components/sharing-dialog/sharing-dialog-component.tsx b/src/views-components/sharing-dialog/sharing-dialog-component.tsx
index 259390aa..0fa0056c 100644
--- a/src/views-components/sharing-dialog/sharing-dialog-component.tsx
+++ b/src/views-components/sharing-dialog/sharing-dialog-component.tsx
@@ -13,6 +13,9 @@ import {
Paper,
Tabs,
Tab,
+ Checkbox,
+ FormControlLabel,
+ Typography,
} from '@material-ui/core';
import {
StyleRulesCallback,
@@ -27,6 +30,14 @@ import {
} from 'models/resource';
import { SharingInvitationForm } from './sharing-invitation-form';
import { SharingManagementForm } from './sharing-management-form';
+import {
+ BasePicker,
+ Calendar,
+ MuiPickersUtilsProvider,
+ TimePickerView
+} from 'material-ui-pickers';
+import DateFnsUtils from "@date-io/date-fns";
+import moment from 'moment';
export interface SharingDialogDataProps {
open: boolean;
@@ -37,7 +48,7 @@ export interface SharingDialogDataProps {
export interface SharingDialogActionProps {
onClose: () => void;
onSave: () => void;
- onCreateSharingToken: () => void;
+ onCreateSharingToken: (d: Date | undefined) => () => void;
refreshPermissions: () => void;
}
enum SharingDialogTab {
@@ -49,12 +60,22 @@ export default (props: SharingDialogDataProps & SharingDialogActionProps) => {
onClose, onSave, onCreateSharingToken, refreshPermissions } = props;
const showTabs = extractUuidObjectType(sharedResourceUuid) === ResourceObjectType.COLLECTION;
const [tabNr, setTabNr] = React.useState<number>(SharingDialogTab.PERMISSIONS);
+ const [expDate, setExpDate] = React.useState<Date>();
+ const [withExpiration, setWithExpiration] = React.useState<boolean>(false);
// Sets up the dialog depending on the resource type
if (!showTabs && tabNr !== SharingDialogTab.PERMISSIONS) {
setTabNr(SharingDialogTab.PERMISSIONS);
}
+ React.useEffect(() => {
+ if (!withExpiration) {
+ setExpDate(undefined);
+ } else {
+ setExpDate(moment().add(1, 'hour').toDate());
+ }
+ }, [withExpiration]);
+
return <Dialog
{...{ open, onClose }}
className="sharing-dialog"
@@ -95,30 +116,59 @@ export default (props: SharingDialogDataProps & SharingDialogActionProps) => {
<Grid item md={12}>
<SharingInvitationForm />
</Grid> }
+ { tabNr === SharingDialogTab.URLS && withExpiration && <>
+ <Grid item container direction='row' md={12}>
+ <MuiPickersUtilsProvider utils={DateFnsUtils}>
+ <BasePicker autoOk value={expDate} onChange={setExpDate}>
+ {({ date, handleChange }) => (<>
+ <Grid item md={6}>
+ <Calendar date={date} minDate={new Date()} maxDate={undefined}
+ onChange={handleChange} />
+ </Grid>
+ <Grid item md={6}>
+ <TimePickerView type="hours" date={date} ampm={false}
+ onMinutesChange={() => {}}
+ onSecondsChange={() => {}}
+ onHourChange={handleChange}
+ />
+ </Grid>
+ </>)}
+ </BasePicker>
+ </MuiPickersUtilsProvider>
+ </Grid>
+ <Grid item md={12}>
+ <Typography variant='caption' align='center'>
+ Maximum expiration date may be limited by the cluster configuration.
+ </Typography>
+ </Grid>
+ </> }
<Grid item xs />
- { tabNr === SharingDialogTab.URLS &&
+ { tabNr === SharingDialogTab.URLS && <>
+ <Grid item><FormControlLabel
+ control={<Checkbox color="primary" checked={withExpiration}
+ onChange={(e) => setWithExpiration(e.target.checked)} />}
+ label="With expiration" />
+ </Grid>
<Grid item>
- <Button
- variant="contained"
- color="primary"
- onClick={onCreateSharingToken}>
+ <Button variant="contained" color="primary"
+ onClick={onCreateSharingToken(expDate)}>
Create sharing URL
</Button>
</Grid>
- }
+ </>}
{ tabNr === SharingDialogTab.PERMISSIONS &&
<Grid item>
- <Button
- variant='contained'
- color='primary'
- onClick={onSave}
+ <Button onClick={onSave} variant="contained" color="primary"
disabled={!saveEnabled}>
Save changes
</Button>
</Grid>
}
<Grid item>
- <Button onClick={onClose}>
+ <Button onClick={() => {
+ onClose();
+ setWithExpiration(false);
+ }}>
Close
</Button>
</Grid>
diff --git a/src/views-components/sharing-dialog/sharing-dialog.tsx b/src/views-components/sharing-dialog/sharing-dialog.tsx
index e48983a2..8cfc58f7 100644
--- a/src/views-components/sharing-dialog/sharing-dialog.tsx
+++ b/src/views-components/sharing-dialog/sharing-dialog.tsx
@@ -43,8 +43,8 @@ const mapDispatchToProps = (dispatch: Dispatch, { ...props }: Props): SharingDia
onSave: () => {
dispatch<any>(saveSharingDialogChanges);
},
- onCreateSharingToken: () => {
- dispatch<any>(createSharingToken);
+ onCreateSharingToken: (d: Date) => () => {
+ dispatch<any>(createSharingToken(d));
},
refreshPermissions: () => {
dispatch<any>(initializeManagementForm);
diff --git a/yarn.lock b/yarn.lock
index faa2b251..13ea553a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1710,6 +1710,24 @@ __metadata:
languageName: node
linkType: hard
+"@date-io/core at npm:^1.3.13":
+ version: 1.3.13
+ resolution: "@date-io/core at npm:1.3.13"
+ checksum: 5a9e9d1de20f0346a3c7d2d5946190caef4bfb0b64d82ba1f4c566657a9192667c94ebe7f438d11d4286d9c190974daad4fb2159294225cd8af4d9a140239879
+ languageName: node
+ linkType: hard
+
+"@date-io/date-fns at npm:1":
+ version: 1.3.13
+ resolution: "@date-io/date-fns at npm:1.3.13"
+ dependencies:
+ "@date-io/core": ^1.3.13
+ peerDependencies:
+ date-fns: ^2.0.0
+ checksum: 0026c0e538ea4add57a11936ff6bdb07e99f25275f8bb28c4702bbb7e82c3a41b3e8124132aa719180d462c01a26a3b4801e41b7349cdb73813749d4bf5e8fbd
+ languageName: node
+ linkType: hard
+
"@fortawesome/fontawesome-common-types at npm:^0.2.28":
version: 0.2.35
resolution: "@fortawesome/fontawesome-common-types at npm:0.2.35"
@@ -2716,6 +2734,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-text-mask at npm:^5.4.3":
+ version: 5.4.11
+ resolution: "@types/react-text-mask at npm:5.4.11"
+ dependencies:
+ "@types/react": "*"
+ checksum: 4defba1467e61b73bfdae74d0b1bea0f27846aabf5283f137fa372ef05bf23accfdf04fffaba33272e9eff5abf00a74863e9c24ca6974c731d73f3fae6efc577
+ languageName: node
+ linkType: hard
+
"@types/react-transition-group at npm:^2.0.8":
version: 2.9.2
resolution: "@types/react-transition-group at npm:2.9.2"
@@ -3710,6 +3737,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "arvados-workbench-2 at workspace:."
dependencies:
+ "@date-io/date-fns": 1
"@fortawesome/fontawesome-svg-core": 1.2.28
"@fortawesome/free-solid-svg-icons": 5.13.0
"@fortawesome/react-fontawesome": 0.1.9
@@ -3752,6 +3780,7 @@ __metadata:
classnames: 2.2.6
cwlts: 1.15.29
cypress: 6.3.0
+ date-fns: ^2.28.0
debounce: 1.2.0
elliptic: 6.5.4
enzyme: 3.11.0
@@ -3767,6 +3796,7 @@ __metadata:
lodash-es: 4.17.14
lodash.mergewith: 4.6.2
lodash.template: 4.5.0
+ material-ui-pickers: ^2.2.4
mem: 4.0.0
moment: 2.29.1
node-sass: ^4.9.4
@@ -5325,6 +5355,13 @@ __metadata:
languageName: node
linkType: hard
+"clsx at npm:^1.0.2":
+ version: 1.1.1
+ resolution: "clsx at npm:1.1.1"
+ checksum: ff052650329773b9b245177305fc4c4dc3129f7b2be84af4f58dc5defa99538c61d4207be7419405a5f8f3d92007c954f4daba5a7b74e563d5de71c28c830063
+ languageName: node
+ linkType: hard
+
"co at npm:^4.6.0":
version: 4.6.0
resolution: "co at npm:4.6.0"
@@ -6267,6 +6304,13 @@ __metadata:
languageName: node
linkType: hard
+"date-fns at npm:^2.28.0":
+ version: 2.28.0
+ resolution: "date-fns at npm:2.28.0"
+ checksum: a0516b2e4f99b8bffc6cc5193349f185f195398385bdcaf07f17c2c4a24473c99d933eb0018be4142a86a6d46cb0b06be6440ad874f15e795acbedd6fd727a1f
+ languageName: node
+ linkType: hard
+
"debounce at npm:1.2.0":
version: 1.2.0
resolution: "debounce at npm:1.2.0"
@@ -11738,6 +11782,25 @@ __metadata:
languageName: node
linkType: hard
+"material-ui-pickers at npm:^2.2.4":
+ version: 2.2.4
+ resolution: "material-ui-pickers at npm:2.2.4"
+ dependencies:
+ "@types/react-text-mask": ^5.4.3
+ clsx: ^1.0.2
+ react-event-listener: ^0.6.6
+ react-text-mask: ^5.4.3
+ react-transition-group: ^2.5.3
+ tslib: ^1.9.3
+ peerDependencies:
+ "@material-ui/core": ^3.2.0
+ prop-types: ^15.6.0
+ react: ^16.3.0
+ react-dom: ^16.3.0
+ checksum: be93e30a824c347ede9f82c6adc92748807ebc9665f00ed86b62b580748ca03470823871337d554659d6a6cb6d5898d3636a7fed9e4f2d9cbfa295c196d8c008
+ languageName: node
+ linkType: hard
+
"md5.js at npm:^1.3.4":
version: 1.3.5
resolution: "md5.js at npm:1.3.5"
@@ -14501,6 +14564,17 @@ __metadata:
languageName: node
linkType: hard
+"prop-types at npm:^15.5.6":
+ version: 15.8.1
+ resolution: "prop-types at npm:15.8.1"
+ dependencies:
+ loose-envify: ^1.4.0
+ object-assign: ^4.1.1
+ react-is: ^16.13.1
+ checksum: c056d3f1c057cb7ff8344c645450e14f088a915d078dcda795041765047fa080d38e5d626560ccaac94a4e16e3aa15f3557c1a9a8d1174530955e992c675e459
+ languageName: node
+ linkType: hard
+
"proxy-addr at npm:~2.0.5":
version: 2.0.7
resolution: "proxy-addr at npm:2.0.7"
@@ -14858,7 +14932,7 @@ __metadata:
languageName: node
linkType: hard
-"react-event-listener at npm:^0.6.2":
+"react-event-listener at npm:^0.6.2, react-event-listener at npm:^0.6.6":
version: 0.6.6
resolution: "react-event-listener at npm:0.6.6"
dependencies:
@@ -15095,6 +15169,17 @@ __metadata:
languageName: node
linkType: hard
+"react-text-mask at npm:^5.4.3":
+ version: 5.4.3
+ resolution: "react-text-mask at npm:5.4.3"
+ dependencies:
+ prop-types: ^15.5.6
+ peerDependencies:
+ react: ^0.14.0 || ^15.0.0 || ^16.0.0
+ checksum: ee9c560f47d2f67d0193636eeea36852503d6d7bfd16d75ecb8170256606923d786bbb3511971deedbd01136340acf597fe2b6ba0be3cddb2a17a602767eb7b9
+ languageName: node
+ linkType: hard
+
"react-transition-group at npm:2.5.0":
version: 2.5.0
resolution: "react-transition-group at npm:2.5.0"
@@ -15110,7 +15195,7 @@ __metadata:
languageName: node
linkType: hard
-"react-transition-group at npm:^2.2.1":
+"react-transition-group at npm:^2.2.1, react-transition-group at npm:^2.5.3":
version: 2.9.0
resolution: "react-transition-group at npm:2.9.0"
dependencies:
@@ -17661,7 +17746,7 @@ __metadata:
languageName: node
linkType: hard
-"tslib at npm:^1.8.0, tslib at npm:^1.8.1, tslib at npm:^1.9.0":
+"tslib at npm:^1.8.0, tslib at npm:^1.8.1, tslib at npm:^1.9.0, tslib at npm:^1.9.3":
version: 1.14.1
resolution: "tslib at npm:1.14.1"
checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd
commit 4f26fc6e11a411c11fc481b937c2e073f4858081
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Thu May 19 13:22:00 2022 -0300
16115: Adds expiration date param to sharing url service method.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/services/api-client-authorization-service/api-client-authorization-service.test.ts b/src/services/api-client-authorization-service/api-client-authorization-service.test.ts
index 3a271f53..4dd01b87 100644
--- a/src/services/api-client-authorization-service/api-client-authorization-service.test.ts
+++ b/src/services/api-client-authorization-service/api-client-authorization-service.test.ts
@@ -24,7 +24,7 @@ describe('ApiClientAuthorizationService', () => {
expect(() => apiClientAuthorizationService.createCollectionSharingToken("foo")).toThrowError("UUID foo is not a collection");
});
- it('should make a create request with proper scopes', async () => {
+ it('should make a create request with proper scopes and no expiration date', async () => {
serverApi.post = jest.fn(() => Promise.resolve(
{ data: { uuid: 'zzzzz-4zz18-0123456789abcde' } }
));
@@ -40,6 +40,25 @@ describe('ApiClientAuthorizationService', () => {
}
);
});
+
+ it('should make a create request with proper scopes and expiration date', async () => {
+ serverApi.post = jest.fn(() => Promise.resolve(
+ { data: { uuid: 'zzzzz-4zz18-0123456789abcde' } }
+ ));
+ const uuid = 'zzzzz-4zz18-0123456789abcde'
+ const expDate = new Date(2022, 8, 28, 12, 0, 0);
+ await apiClientAuthorizationService.createCollectionSharingToken(uuid, expDate);
+ expect(serverApi.post).toHaveBeenCalledWith(
+ '/api_client_authorizations', {
+ scopes: [
+ `GET /arvados/v1/collections/${uuid}`,
+ `GET /arvados/v1/collections/${uuid}/`,
+ `GET /arvados/v1/keep_services/accessible`,
+ ],
+ expires_at: expDate.toUTCString()
+ }
+ );
+ });
});
describe('listCollectionSharingToken', () => {
diff --git a/src/services/api-client-authorization-service/api-client-authorization-service.ts b/src/services/api-client-authorization-service/api-client-authorization-service.ts
index 7c985dbb..dbda0a42 100644
--- a/src/services/api-client-authorization-service/api-client-authorization-service.ts
+++ b/src/services/api-client-authorization-service/api-client-authorization-service.ts
@@ -14,17 +14,20 @@ export class ApiClientAuthorizationService extends CommonService<ApiClientAuthor
super(serverApi, "api_client_authorizations", actions);
}
- createCollectionSharingToken(uuid: string): Promise<ApiClientAuthorization> {
+ createCollectionSharingToken(uuid: string, expDate: Date | undefined): Promise<ApiClientAuthorization> {
if (extractUuidObjectType(uuid) !== ResourceObjectType.COLLECTION) {
throw new Error(`UUID ${uuid} is not a collection`);
}
- return this.create({
+ const data = {
scopes: [
`GET /arvados/v1/collections/${uuid}`,
`GET /arvados/v1/collections/${uuid}/`,
`GET /arvados/v1/keep_services/accessible`,
]
- });
+ }
+ return expDate !== undefined
+ ? this.create({...data, expiresAt: expDate.toUTCString()})
+ : this.create(data);
}
listCollectionSharingTokens(uuid: string): Promise<ListResults<ApiClientAuthorization>> {
diff --git a/src/store/sharing-dialog/sharing-dialog-actions.ts b/src/store/sharing-dialog/sharing-dialog-actions.ts
index 3eec0b59..ffd81fb7 100644
--- a/src/store/sharing-dialog/sharing-dialog-actions.ts
+++ b/src/store/sharing-dialog/sharing-dialog-actions.ts
@@ -61,14 +61,14 @@ export interface SharingDialogData {
refresh: () => void;
}
-export const createSharingToken = async (dispatch: Dispatch, getState: () => RootState, { apiClientAuthorizationService }: ServiceRepository) => {
+export const createSharingToken = (expDate: Date | undefined) => async (dispatch: Dispatch, getState: () => RootState, { apiClientAuthorizationService }: ServiceRepository) => {
const dialog = getDialog<SharingDialogData>(getState().dialog, SHARING_DIALOG_NAME);
if (dialog) {
const resourceUuid = dialog.data.resourceUuid;
if (extractUuidObjectType(resourceUuid) === ResourceObjectType.COLLECTION) {
dispatch(progressIndicatorActions.START_WORKING(SHARING_DIALOG_NAME));
try {
- const sharingToken = await apiClientAuthorizationService.createCollectionSharingToken(resourceUuid);
+ const sharingToken = await apiClientAuthorizationService.createCollectionSharingToken(resourceUuid, expDate);
dispatch(resourcesActions.SET_RESOURCES([sharingToken]));
dispatch(snackbarActions.OPEN_SNACKBAR({
message: 'Sharing URL created',
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list