[WEB-310] dev: private bucket implementation (#5793)

* chore: migrations and backmigration to move attachments to file asset

* chore: move attachments to file assets

* chore: update migration file to include created by and updated by and size

* chore: remove uninmport errors

* chore: make size as float field

* fix: file asset uploads

* chore: asset uploads migration changes

* chore: v2 assets endpoint

* chore: remove unused imports

* chore: issue attachments

* chore: issue attachments

* chore: workspace logo endpoints

* chore: private bucket changes

* chore: user asset endpoint

* chore: add logo_url validation

* chore: cover image urlk

* chore: change asset max length

* chore: pages endpoint

* chore: store the storage_metadata only when none

* chore: attachment asset apis

* chore: update create private bucket

* chore: make bucket private

* chore: fix response of user uploads

* fix: response of user uploads

* fix: job to fix file asset uploads

* fix: user asset endpoints

* chore: avatar for user profile

* chore: external apis user url endpoint

* chore: upload workspace and user asset actions updated

* chore: analytics endpoint

* fix: analytics export

* chore: avatar urls

* chore: update user avatar instances

* chore: avatar urls for assignees and creators

* chore: bucket permission script

* fix: all user avatr instances in the web app

* chore: update project cover image logic

* fix: issue attachment endpoint

* chore: patch endpoint for issue attachment

* chore: attachments

* chore: change attachment storage class

* chore: update issue attachment endpoints

* fix: issue attachment

* chore: update issue attachment implementation

* chore: page asset endpoints

* fix: web build errors

* chore: attachments

* chore: page asset urls

* chore: comment and issue asset endpoints

* chore: asset endpoints

* chore: attachment endpoints

* chore: bulk asset endpoint

* chore: restore endpoint

* chore: project assets endpoints

* chore: asset url

* chore: add delete asset endpoints

* chore: fix asset upload endpoint

* chore: update patch endpoints

* chore: update patch endpoint

* chore: update editor image handling

* chore: asset restore endpoints

* chore: avatar url for space assets

* chore: space app assets migration

* fix: space app urls

* chore: space endpoints

* fix: old editor images rendering logic

* fix: issue archive and attachment activity

* chore: asset deletes

* chore: attachment delete

* fix: issue attachment

* fix: issue attachment get

* chore: cover image url for projects

* chore: remove duplicate py file

* fix: url check function

* chore: chore project cover asset delete

* fix: migrations

* chore: delete migration files

* chore: update bucket

* fix: build errors

* chore: add asset url in intake attachment

* chore: project cover fix

* chore: update next.config

* chore: delete old workspace logos

* chore: workspace assets

* chore: asset get for space

* chore: update project modal

* chore: remove unused imports

* fix: space app editor helper

* chore: update rich-text read-only editor

* chore: create multiple column for entity identifiers

* chore: update migrations

* chore: remove entity identifier

* fix: issue assets

* chore: update maximum file size logic

* chore: update editor max file size logic

* fix: close modal after removing workspace logo

* chore: update uploaded asstes' status post issue creation

* chore: added file size limit to the space app

* dev: add file size limit restriction on all endpoints

* fix: remove old workspace logo and user avatar

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
This commit is contained in:
Aaryan Khandelwal 2024-10-11 20:13:38 +05:30 committed by GitHub
parent c9580ab794
commit 7e334203f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
241 changed files with 5326 additions and 2518 deletions

View file

@ -11,11 +11,13 @@ type Props = {
handleInsertText: (insertOnNextLine: boolean) => void;
handleRegenerate: () => Promise<void>;
isRegenerating: boolean;
projectId: string;
response: string | undefined;
workspaceSlug: string;
};
export const AskPiMenu: React.FC<Props> = (props) => {
const { handleInsertText, handleRegenerate, isRegenerating, response } = props;
const { handleInsertText, handleRegenerate, isRegenerating, projectId, response, workspaceSlug } = props;
// states
const [query, setQuery] = useState("");
@ -39,6 +41,8 @@ export const AskPiMenu: React.FC<Props> = (props) => {
initialValue={response}
containerClassName="!p-0 border-none"
editorClassName="!pl-0"
workspaceSlug={workspaceSlug}
projectId={projectId}
/>
<div className="mt-3 flex items-center gap-4">
<button

View file

@ -1,7 +1,6 @@
"use client";
import React, { RefObject, useEffect, useRef, useState } from "react";
import { useParams } from "next/navigation";
import { ChevronRight, CornerDownRight, LucideIcon, RefreshCcw, Sparkles, TriangleAlert } from "lucide-react";
// plane editor
import { EditorRefApi } from "@plane/editor";
@ -22,6 +21,8 @@ type Props = {
editorRef: RefObject<EditorRefApi>;
isOpen: boolean;
onClose: () => void;
projectId: string;
workspaceSlug: string;
};
const MENU_ITEMS: {
@ -58,7 +59,7 @@ const TONES_LIST = [
];
export const EditorAIMenu: React.FC<Props> = (props) => {
const { editorRef, isOpen, onClose } = props;
const { editorRef, isOpen, onClose, projectId, workspaceSlug } = props;
// states
const [activeTask, setActiveTask] = useState<AI_EDITOR_TASKS | null>(null);
const [response, setResponse] = useState<string | undefined>(undefined);
@ -66,7 +67,6 @@ export const EditorAIMenu: React.FC<Props> = (props) => {
// refs
const responseContainerRef = useRef<HTMLDivElement>(null);
// params
const { workspaceSlug } = useParams();
const handleGenerateResponse = async (payload: TTaskPayload) => {
if (!workspaceSlug) return;
await aiService.performEditorTask(workspaceSlug.toString(), payload).then((res) => setResponse(res.response));
@ -193,7 +193,9 @@ export const EditorAIMenu: React.FC<Props> = (props) => {
handleInsertText={handleInsertText}
handleRegenerate={handleRegenerate}
isRegenerating={isRegenerating}
projectId={projectId}
response={response}
workspaceSlug={workspaceSlug}
/>
) : (
<>
@ -215,6 +217,8 @@ export const EditorAIMenu: React.FC<Props> = (props) => {
initialValue={response}
containerClassName="!p-0 border-none"
editorClassName="!pl-0"
workspaceSlug={workspaceSlug}
projectId={projectId}
/>
<div className="mt-3 flex items-center gap-4">
<button

View file

@ -16,19 +16,21 @@ import { getRandomEmoji } from "@/helpers/emoji.helper";
// hooks
import { useEventTracker, useProject } from "@/hooks/store";
import { usePlatformOS } from "@/hooks/use-platform-os";
// plane web types
import { TProject } from "@/plane-web/types/projects";
import ProjectAttributes from "./attributes";
type Props = {
export type TCreateProjectFormProps = {
setToFavorite?: boolean;
workspaceSlug: string;
onClose: () => void;
handleNextStep: (projectId: string) => void;
data?: Partial<TProject>;
updateCoverImageStatus: (projectId: string, coverImage: string) => Promise<void>;
};
const defaultValues: Partial<TProject> = {
cover_image: PROJECT_UNSPLASH_COVERS[Math.floor(Math.random() * PROJECT_UNSPLASH_COVERS.length)],
cover_image_url: PROJECT_UNSPLASH_COVERS[Math.floor(Math.random() * PROJECT_UNSPLASH_COVERS.length)],
description: "",
logo_props: {
in_use: "emoji",
@ -42,8 +44,8 @@ const defaultValues: Partial<TProject> = {
project_lead: null,
};
export const CreateProjectForm: FC<Props> = observer((props) => {
const { setToFavorite, workspaceSlug, onClose, handleNextStep } = props;
export const CreateProjectForm: FC<TCreateProjectFormProps> = observer((props) => {
const { setToFavorite, workspaceSlug, onClose, handleNextStep, updateCoverImageStatus } = props;
// store
const { captureProjectEvent } = useEventTracker();
const { addProjectToFavorites, createProject } = useProject();
@ -71,9 +73,13 @@ export const CreateProjectForm: FC<Props> = observer((props) => {
const onSubmit = async (formData: Partial<TProject>) => {
// Upper case identifier
formData.identifier = formData.identifier?.toUpperCase();
const coverImage = formData.cover_image_url;
return createProject(workspaceSlug.toString(), formData)
.then((res) => {
.then(async (res) => {
if (coverImage) {
await updateCoverImageStatus(res.id, coverImage);
}
const newPayload = {
...res,
state: "SUCCESS",