Skip to content

Commit

Permalink
Merge pull request #910 from OpenSourceBrain/feature/804-new
Browse files Browse the repository at this point in the history
Feature/804 - addition of thumbnail image to repositories
  • Loading branch information
filippomc authored Feb 20, 2024
2 parents bcf874e + 058f22e commit 56765f0
Show file tree
Hide file tree
Showing 33 changed files with 819 additions and 391 deletions.
1 change: 1 addition & 0 deletions applications/osb-portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"start:dev": "webpack serve --progress --config webpack.dev.js --env DOMAIN=https://v2dev.opensourcebrain.org --env NAMESPACE=osb2dev --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:prod": "webpack serve --progress --config webpack.dev.js --env DOMAIN=https://v2.opensourcebrain.org --env NAMESPACE=osb2 --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:local": "webpack serve --progress --config webpack.dev.js --env DOMAIN=http://osb.local --env NAMESPACE=osblocal --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:local-be": "webpack serve --progress --config webpack.dev.js --env APP_DOMAIN=http://localhost:8888 --env DOMAIN=https://osb.local --env WORKSPACES_DOMAIN=http://localhost:5001 --env NAMESPACE=osblocal --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:dev-be": "webpack serve --progress --config webpack.dev.js --env DOMAIN=https://v2dev.opensourcebrain.org --env ACCOUNTS_API_DOMAIN=localhost:5001 --env WORKSPACES_DOMAIN=http://localhost:5001 --env NAMESPACE=osblocal --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:dev-app": "webpack serve --progress --config webpack.dev.js --env APP_DOMAIN=https://localhost:8888 --env DOMAIN=https://v2.opensourcebrain.org --env NAMESPACE=osblocal --env NODE_OPTIONS='--max-old-space-size=12048'",
"start:local-app": "webpack serve --progress --config webpack.dev.js --env APP_DOMAIN=http://localhost:8888 --env DOMAIN=http://osb.local --env NAMESPACE=osblocal --env NODE_OPTIONS='--max-old-space-size=12048'",
Expand Down
63 changes: 63 additions & 0 deletions applications/osb-portal/src/apiclient/workspaces/apis/RestApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ export interface WorkspaceresourcePostRequest {
workspaceResource: WorkspaceResource;
}

export interface WorkspacesControllersOsbrepositoryControllerSetthumbnailRequest {
id: number;
thumbNail?: Blob;
}

export interface WorkspacesControllersWorkspaceControllerAddimageRequest {
id: number;
image?: Blob;
Expand Down Expand Up @@ -1323,6 +1328,64 @@ export class RestApi extends runtime.BaseAPI {
return await response.value();
}

/**
* Sets the thumbnail of the workspace.
*/
async workspacesControllersOsbrepositoryControllerSetthumbnailRaw(requestParameters: WorkspacesControllersOsbrepositoryControllerSetthumbnailRequest): Promise<runtime.ApiResponse<void>> {
if (requestParameters.id === null || requestParameters.id === undefined) {
throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling workspacesControllersOsbrepositoryControllerSetthumbnail.');
}

const queryParameters: any = {};

const headerParameters: runtime.HTTPHeaders = {};

if (this.configuration && this.configuration.accessToken) {
const token = this.configuration.accessToken;
const tokenString = typeof token === 'function' ? token("bearerAuth", []) : token;

if (tokenString) {
headerParameters["Authorization"] = `Bearer ${tokenString}`;
}
}
const consumes: runtime.Consume[] = [
{ contentType: 'multipart/form-data' },
];
// @ts-ignore: canConsumeForm may be unused
const canConsumeForm = runtime.canConsumeForm(consumes);

let formParams: { append(param: string, value: any): any };
let useForm = false;
// use FormData to transmit files using content-type "multipart/form-data"
useForm = canConsumeForm;
if (useForm) {
formParams = new FormData();
} else {
formParams = new URLSearchParams();
}

if (requestParameters.thumbNail !== undefined) {
formParams.append('thumbNail', requestParameters.thumbNail as any);
}

const response = await this.request({
path: `/osbrepository/{id}/thumbnail/`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))),
method: 'POST',
headers: headerParameters,
query: queryParameters,
body: formParams,
});

return new runtime.VoidApiResponse(response);
}

/**
* Sets the thumbnail of the workspace.
*/
async workspacesControllersOsbrepositoryControllerSetthumbnail(requestParameters: WorkspacesControllersOsbrepositoryControllerSetthumbnailRequest): Promise<void> {
await this.workspacesControllersOsbrepositoryControllerSetthumbnailRaw(requestParameters);
}

/**
* Adds and image to the workspace.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ export interface OSBRepository {
* @memberof OSBRepository
*/
defaultContext?: string;
/**
*
* @type {string}
* @memberof OSBRepository
*/
thumbnail?: string;
/**
* OSBRepository keycloak user id, will be automatically be set to the logged in user
* @type {string}
Expand Down Expand Up @@ -178,6 +184,7 @@ export function OSBRepositoryFromJSONTyped(json: any, ignoreDiscriminator: boole
'autoSync': !exists(json, 'auto_sync') ? undefined : json['auto_sync'],
'uri': json['uri'],
'defaultContext': !exists(json, 'default_context') ? undefined : json['default_context'],
'thumbnail': !exists(json, 'thumbnail') ? undefined : json['thumbnail'],
'userId': !exists(json, 'user_id') ? undefined : json['user_id'],
'timestampCreated': !exists(json, 'timestamp_created') ? undefined : (new Date(json['timestamp_created'])),
'timestampUpdated': !exists(json, 'timestamp_updated') ? undefined : (new Date(json['timestamp_updated'])),
Expand Down Expand Up @@ -208,6 +215,7 @@ export function OSBRepositoryToJSON(value?: OSBRepository | null): any {
'auto_sync': value.autoSync,
'uri': value.uri,
'default_context': value.defaultContext,
'thumbnail': value.thumbnail,
'user_id': value.userId,
'timestamp_created': value.timestampCreated === undefined ? undefined : (value.timestampCreated.toISOString()),
'timestamp_updated': value.timestampUpdated === undefined ? undefined : (value.timestampUpdated.toISOString()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ export interface OSBRepositoryBase {
* @memberof OSBRepositoryBase
*/
defaultContext?: string;
/**
*
* @type {string}
* @memberof OSBRepositoryBase
*/
thumbnail?: string;
/**
* OSBRepository keycloak user id, will be automatically be set to the logged in user
* @type {string}
Expand Down Expand Up @@ -122,6 +128,7 @@ export function OSBRepositoryBaseFromJSONTyped(json: any, ignoreDiscriminator: b
'autoSync': !exists(json, 'auto_sync') ? undefined : json['auto_sync'],
'uri': json['uri'],
'defaultContext': !exists(json, 'default_context') ? undefined : json['default_context'],
'thumbnail': !exists(json, 'thumbnail') ? undefined : json['thumbnail'],
'userId': !exists(json, 'user_id') ? undefined : json['user_id'],
'timestampCreated': !exists(json, 'timestamp_created') ? undefined : (new Date(json['timestamp_created'])),
'timestampUpdated': !exists(json, 'timestamp_updated') ? undefined : (new Date(json['timestamp_updated'])),
Expand All @@ -146,6 +153,7 @@ export function OSBRepositoryBaseToJSON(value?: OSBRepositoryBase | null): any {
'auto_sync': value.autoSync,
'uri': value.uri,
'default_context': value.defaultContext,
'thumbnail': value.thumbnail,
'user_id': value.userId,
'timestamp_created': value.timestampCreated === undefined ? undefined : (value.timestampCreated.toISOString()),
'timestamp_updated': value.timestampUpdated === undefined ? undefined : (value.timestampUpdated.toISOString()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ export interface OSBRepositoryEntity {
* @memberof OSBRepositoryEntity
*/
defaultContext?: string;
/**
*
* @type {string}
* @memberof OSBRepositoryEntity
*/
thumbnail?: string;
/**
* OSBRepository keycloak user id, will be automatically be set to the logged in user
* @type {string}
Expand Down Expand Up @@ -126,6 +132,7 @@ export function OSBRepositoryEntityFromJSONTyped(json: any, ignoreDiscriminator:
'autoSync': !exists(json, 'auto_sync') ? undefined : json['auto_sync'],
'uri': json['uri'],
'defaultContext': !exists(json, 'default_context') ? undefined : json['default_context'],
'thumbnail': !exists(json, 'thumbnail') ? undefined : json['thumbnail'],
'userId': !exists(json, 'user_id') ? undefined : json['user_id'],
'timestampCreated': !exists(json, 'timestamp_created') ? undefined : (new Date(json['timestamp_created'])),
'timestampUpdated': !exists(json, 'timestamp_updated') ? undefined : (new Date(json['timestamp_updated'])),
Expand All @@ -150,6 +157,7 @@ export function OSBRepositoryEntityToJSON(value?: OSBRepositoryEntity | null): a
'auto_sync': value.autoSync,
'uri': value.uri,
'default_context': value.defaultContext,
'thumbnail': value.thumbnail,
'user_id': value.userId,
'timestamp_created': value.timestampCreated === undefined ? undefined : (value.timestampCreated.toISOString()),
'timestamp_updated': value.timestampUpdated === undefined ? undefined : (value.timestampUpdated.toISOString()),
Expand Down
193 changes: 193 additions & 0 deletions applications/osb-portal/src/components/common/ThumbnailUploadArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import * as React from "react";
import Dropzone from "react-dropzone";
import { Box, Button, Grid, IconButton, Typography } from "@mui/material";

//icons
import DeleteForeverIcon from "@mui/icons-material/DeleteForever";

//style
import styled from "@mui/system/styled";
import { radius, gutter, bgInputs } from "../../theme";

// import style manually
import { alpha } from "@mui/material/styles";


const MAX_ALLOWED_THUMBNAIL_SIZE = 1024 * 1024; // 1MB

export const StyledDropZoneBox = styled(Box)(({ theme }) => ({
color: bgInputs,
border: `2px dashed ${bgInputs}`,
borderRadius: 5,
padding: 4,
"& .MuiTypography-subtitle2": {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(2),
},
"& .MuiButton-outlined": {
margin: "0 auto",
display: "flex",
justifyContent: "center",
color: bgInputs,
borderRadius: radius,
border: `2px solid ${bgInputs}`,
},
}));

export const StyledImagePreviewSection = styled("section")(() => ({
display: "flex",
minHeight: "15em",
alignItems: "stretch",
backgroundPosition: "center",
backgroundSize: "cover",
flex: 1,
}));

export const dropAreaStyle = (error: any) => ({
flex: 1,
display: "flex",
alignItems: "center",
borderRadius: radius,
padding: gutter,
borderColor: error ? "red" : alpha(bgInputs, 1),
});


interface UploadAreaProps {
setThumbnail: any;
thumbnail: any;
thumbnailError: any;
setThumbnailError: any;
workspace: any;
}

export const OSBDialog: React.FunctionComponent<UploadAreaProps> = ({
setThumbnail,
thumbnail,
thumbnailError,
setThumbnailError,
workspace
}) => {
const [thumbnailPreview, setThumbnailPreview] = React.useState<any>(
workspace?.thumbnail ? "/proxy/workspaces/" + workspace.thumbnail : null
);


const dropThumbnail = (uploadedThumbnail: any) => {
setThumbnail(uploadedThumbnail);
previewFile(uploadedThumbnail);
};

const previewFile = (file: Blob) => {
if (!file) {
setThumbnailError(null);
setThumbnailPreview(null);
return;
}

if (!file.type.includes("image")) {
setThumbnailError("Not an image file");
return;
}
if (file.size > MAX_ALLOWED_THUMBNAIL_SIZE) {
setThumbnailError("File exceeds allowed size (1MB)");
return;
}

setThumbnailError(null);

const fileReader: FileReader = new FileReader();

fileReader.onload = () => {
setThumbnailPreview(fileReader.result);
};

fileReader.readAsDataURL(file);
};
return (
<StyledDropZoneBox alignItems="stretch">
<Dropzone
onDrop={(acceptedFiles: any) => {
dropThumbnail(acceptedFiles[0]);
}}
>
{({
getRootProps,
getInputProps,
acceptedFiles,
}: {
getRootProps: (p: any) => any;
getInputProps: () => any;
acceptedFiles: any[];
}) => (
<StyledImagePreviewSection
style={{
backgroundImage:
!thumbnailError && `url(${thumbnailPreview})`,
}}
>
<div
{...getRootProps({
style: dropAreaStyle(thumbnailError),
})}
>
<input {...getInputProps()} />
<Grid
container={true}
justifyContent="center"
alignItems="center"
direction="row"
>
{thumbnail && (
<Grid item={true}>
{!thumbnail ? (
""
) : (
<IconButton
onClick={(e: any) => {
e.preventDefault();
dropThumbnail(null);
}}
size="large"
>
<DeleteForeverIcon />
</IconButton>
)}
</Grid>
)}
<Grid item={true}>
<Box component="div" m={1}>
{!thumbnail ? (
<>
<span>Drop file here to upload...</span>
<Button
variant="outlined"
sx={{ margin: "auto !important" }}
>
Browse files
</Button>
</>
) : null}

{thumbnailError && (
<Typography
color="error"
variant="subtitle2"
component="p"
>
{thumbnailError}
</Typography>
)}
</Box>
</Grid>
</Grid>
</div>
</StyledImagePreviewSection>
)}
</Dropzone>
</StyledDropZoneBox>

);
};

export default OSBDialog;
31 changes: 31 additions & 0 deletions applications/osb-portal/src/components/icons.tsx

Large diffs are not rendered by default.

Loading

0 comments on commit 56765f0

Please sign in to comment.