From 0d2a8cca50c320ac7761322cf1ab3f4dc883c86e Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Thu, 21 Mar 2024 14:58:16 +0530 Subject: [PATCH 01/53] chore: project structuring --- deploy/1-click/README.md | 79 --- deploy/1-click/images/help.png | Bin 111313 -> 0 bytes deploy/1-click/images/install.png | Bin 177123 -> 0 bytes deploy/1-click/install.sh | 20 - deploy/1-click/plane-app | 791 ------------------------------ 5 files changed, 890 deletions(-) delete mode 100644 deploy/1-click/README.md delete mode 100644 deploy/1-click/images/help.png delete mode 100644 deploy/1-click/images/install.png delete mode 100644 deploy/1-click/install.sh delete mode 100644 deploy/1-click/plane-app diff --git a/deploy/1-click/README.md b/deploy/1-click/README.md deleted file mode 100644 index 9ed2323de..000000000 --- a/deploy/1-click/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# One-click deploy - -Deployment methods for Plane have improved significantly to make self-managing super-easy. One of those is a single-line-command installation of Plane. - -This short guide will guide you through the process, the background tasks that run with the command for the Community, One, and Enterprise editions, and the post-deployment configuration options available to you. - -### Requirements - -- Operating systems: Debian, Ubuntu, CentOS -- Supported CPU architectures: AMD64, ARM64, x86_64, AArch64 - -### Download the latest stable release - -Run ↓ on any CLI. - -``` -curl -fsSL https://raw.githubusercontent.com/makeplane/plane/master/deploy/1-click/install.sh | sh - -``` - -### Download the Preview release - -`Preview` builds do not support ARM64, AArch64 CPU architectures - -Run ↓ on any CLI. - -``` -export BRANCH=preview -curl -fsSL https://raw.githubusercontent.com/makeplane/plane/preview/deploy/1-click/install.sh | sh - -``` - ---- - -### Successful installation - -You should see ↓ if there are no hitches. That output will also list the IP address you can use to access your Plane instance. - -![Install Output](images/install.png) - ---- - -### Manage your Plane instance - -Use `plane-app` [OPERATOR] to manage your Plane instance easily. Get a list of all operators with `plane-app ---help`. - -![Plane Help](images/help.png) - -1. Basic operators - - 1. `plane-app start` starts the Plane server. - 2. `plane-app restart` restarts the Plane server. - 3. `plane-app stop` stops the Plane server. - -2. Advanced operators - - `plane-app --configure` will show advanced configurators. - - - Change your proxy or listening port -
Default: 80 - - Change your domain name -
Default: Deployed server's public IP address - - File upload size -
Default: 5MB - - Specify external database address when using an external database -
Default: `Empty` -
`Default folder: /opt/plane/data/postgres` - - Specify external Redis URL when using external Redis -
Default: `Empty` -
`Default folder: /opt/plane/data/redis` - - Configure AWS S3 bucket -
Use only when you or your users want to use S3 -
`Default folder: /opt/plane/data/minio` - -3. Version operators - - 1. `plane-app --upgrade` gets the latest stable version of `docker-compose.yaml`, `.env`, and Docker images - 2. `plane-app --update-installer` updates the installer and the `plane-app` utility. - 3. `plane-app --uninstall` uninstalls the Plane application and all Docker containers from the server but leaves the data stored in - Postgres, Redis, and Minio alone. - 4. `plane-app --install` installs the Plane app again. diff --git a/deploy/1-click/images/help.png b/deploy/1-click/images/help.png deleted file mode 100644 index c14603a4b1e2a4cc177cb7756b24cdf4239fc4e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111313 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
##?=`uQ_hyE*;86opm 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%0DFJIuy%ox`~KN9sF1vmKPV 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

{_26kMAg+5uDuwCJ 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

M$ z%p^QLR$<);hs=zKi5cl_iCcHfi6L-s#!hF%C>tmRmQ4fvkNSP>f!_WAx4*l5QKifsE3Aa;TI7u1EG$Gk8mXCX5A!V50!cC~?7ZNFDJkRx=xV9nSv z5Mef^(NfZ-lyFio111l8EYpC=$&Pa)(yd~Si-M#q(=y(MuX2rY%!_iQT13()nbl3^ ze`w-Z^hA}^jnr{K7G^^*AeRAnkMlZiE1oMamOS{-NSTO6N+kQ)Btrd$8qgHC9hX{S zN!8$#N}CzcU3x&YY6>lnQU{(o?8%N`a z1Ah{yDzGg1&2#u%_OrQuS0uj;n_cnqyRRd+F5#qXG&c@Mb&Bag^`ljVOUIu_(;)#J zJ2Wih*I$3F`pi+mL4$k!HeMB;GayYi*<=o{4BtQeeyxx1&DURf{}9KEet-3q_wQ?Y z3k+$uy>@k%UwDQ4;r2W0n`*da`LL`A|1Wtfja~FF(LutSn@Gq0<``!uI_Tno`D^1| zb4MS4q#JVm)hbum&;f!nhmh^yf>QS?u}O=jyiCBKoGsUsAwyqdKgo;fMxDjXRK6cb zM^0V?7^_w&6Qe)`cIIPi>@YdS7(o{$09tE-3wk)=3mqLxafq2o4rKe&)YpYrz;?VgH~15={NPV4q*^>%NrZjK>|uGW3DS;}1MMFWYs`-P}2Y&vLu({3De>IGA1c z*iGX{z9ADH?N<;0u_4eBWW!t5yx(U718SH`o;_SIVovG`kcp}@>w_gf<=Ge z1QZ^laWibastgnaR^9&>2f9_($^xqf=ro&fI#Cp7fN?k^JFs-v+!eZewS}JPXxhTWee4oU*7Z*B4*>DmS|i zA3nVM7(ZXr*Z<#r_uqyt65o6V&De53k6)ei)mOicwSAut&K(%#SFb`B8@&&^mj99-a9uu8;QMVnSoKeThzG02&-?U4 z?q?eGsXMuE?YXA(j-+SsX}5Ly_^}?$DxdJposhl=vNp*Fc4fWlah`+7=T`7Z?&cup zJbaRu5@v#}J@>fkZ<}%5qP;FdNxjVh{}H3&8ua9{B7OwzJ~lb|+C~sCc%*GiRHwP5ZU%m&g8KJ4da&xB|MJKDT0=gM%l@f` z_aU9v+>b9mdOeu+Z<`0RD({FRzeaOniX%Pt#`>xxzTI^~fSv%zKgYn_kY{PEFA}P= z956>xxt*^mIv;z^j@nUeI3g;0r#XvenZjNO~y${<!mw8pke2oHIzIE#64rZ~p|WKMZXn|Uw?)@p8+wUeJ5Fyvx)c?P5qvM0TbLXSQVDiKSYo{_jIS1{vahZLq-wmbmtx9yWAv^mqm~R)RtIp@r7#m*fi>cW_Z&ThyKYki5Caw z9^qoF)ME67sDCvK}_ZJ(m-}Ss9{I$ zfZ@=Es<>lj-RrqbD1US4M`uf zjsF2jFJ2qp19a<@Ak_MAUTb7{y^{g*o=VrTMrnJ5qMN%mQ3nj<@|q~hJQlB1GQ793 zHCakm$wksh-CYVMuE95ORjsxt_ZGE0wM~s&GK6^F?*0nb@&l^(j=CvpzF^6cJ?OfFIF&7(Hkh=&uu z?(+CkPL+*ll}}e<(^1-Tri74?%{Km=o%LFzcN{zMNzN6_N&1UJFRA~MwYjhHd>)-& ziua`7HN^$EU%1S-NzClU@;ZKM(jaz;O`v89>-ZUU7MroJZO^s6S7P|E=>hvFo;Vg( zQZJGqd1Xm2qNUVIrjLO4K)?7L<2vyha;6h}rol$upgax-fjDyik$!fEZo%31jyt-s=WJKtyecPm^dZ&#+6=OyV&E#>H?)D}y89?D0GAoBnwKQnZn^|>AJv%lGdp}=;y_v!wJ z^;RV38+yKZZdPN@?0qSZwc<@$8Lkfo?_Mm++L;__d?kbiG|^8P<%{41Gz7UyM?yjp38!~MuQa?Il=O&{pH{#l$=OH;p8_{o zI|CX5vb`t#kIEf?-YyhdZG6YfQB{CCRvi`h1HQ!HR=enXRD)%7E3X~R~h2M6I#M$N0h&aLOg8Zh1m9yFal6Y zc20UBuYsDoEXTC?tqY;g5nh+Uku=Whap|qj?Eab9^>ET>W0&Vq~~t8L#`plE1H$> z61@`VU4-8^OQ|S6DPMWIM0xkrUy31tz7! zyn`2EW9~-S$D=k2;?zQp&V4%*y1JZexGmjnDwX7}wGh-(hUch~VtO^c43`g%5goam zCx84S9$VFX15%cT=Y(0*-JMnOCI0LHXTzjvK2w>Fbv1|`H@u&$_5&+m=GCFb@fQF9 N002ovPDHLkV1i?t;otxO diff --git a/deploy/1-click/images/install.png b/deploy/1-click/images/install.png deleted file mode 100644 index c8ba1e5f829c0fb28a08ab442b573a2a25b3e9bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177123 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

T|q(b(;rMX*=oX_1=FkA1ose=3{bO| zWuolWW$T-QduBtk7&>47#7;?Vw^iTN7rP^uMHOH!_@ze&Sdm+Vn#*hd$br^bcXj zxHWf*-m0l}8K(@KaO1DWMGa53Ovo08`W8E9bWwN+p~a;>#X@hySgJy`P6J%(W6)g>ILA;7gD3_JH&HX~0QE+2f;gqD1*P=gwmQ4_{>rGUOj zn$aSxu_?HF`yvZy!GTE;5*r7_KuUzJBztH&tsaN4oO&xK`o^&2&z~+aB)}NSD7%|R*(Jv{>t}dk(axvJq zsdTx&^)RoVaMkoyPQR^iUBA+&;a+dHQmtu#C zDzEhDsTxzRAwA%|B%6bwaj8`xJiz#6IfH?Ni#2wTv6=@MC0$u&I`K;*<`w#Gu}3p! zsNA9Lw-Jl;l2^06y;hIvW1{+$WRA{s%0<$QRv|Y)%gRq;%2)vYR>6i}DL})~fHJhT zO00-ZSEs1{*8DUcd0Ke)*&hnN6?)(JS(ti%1Pn54`2Z(7wpc#NMyti|mp^89NL|sI zt5uYBNM|DAnyY^5^Q7jpIjxI)#YDb{jqzZ!Wq0?C030&49{Zx4k~4%E^2aryt@u_? zjO!c+`cw$hnlEGwl1J*c+9I6N>oAv2N)i}|Dno-(xu{bPCN%;qDD!Ec+(qb&;gd73 z))(DWKfu_qA^pRfC_`s4MWa?Ju>NmTub4YR|qxg$5T-V zj#!xfd1MpgUUMRLDKM*3J74q~RtD>YBwU}d=7^0L%dKYxOU$9<9LkG4o5w~s>`W`N z%T^3H_*=P(Z^g9+b=HEd`HZ(D⪼}@%?);7Q)nG-$Xt(%l0sFojm=J(O+VAqb5H6 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%0DBqd10BIk13#BxCg8FB@Pl2z0`^vJm@=AWX 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 diff --git a/deploy/1-click/install.sh b/deploy/1-click/install.sh deleted file mode 100644 index 9a0eac902..000000000 --- a/deploy/1-click/install.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -export GIT_REPO=makeplane/plane - -# Check if the user has sudo access -if command -v curl &> /dev/null; then - sudo curl -sSL \ - -o /usr/local/bin/plane-app \ - https://raw.githubusercontent.com/$GIT_REPO/${BRANCH:-master}/deploy/1-click/plane-app?token=$(date +%s) -else - sudo wget -q \ - -O /usr/local/bin/plane-app \ - https://raw.githubusercontent.com/$GIT_REPO/${BRANCH:-master}/deploy/1-click/plane-app?token=$(date +%s) -fi - -sudo chmod +x /usr/local/bin/plane-app -sudo sed -i 's@export DEPLOY_BRANCH=${BRANCH:-master}@export DEPLOY_BRANCH='${BRANCH:-master}'@' /usr/local/bin/plane-app -sudo sed -i 's@CODE_REPO=${GIT_REPO:-makeplane/plane}@CODE_REPO='$GIT_REPO'@' /usr/local/bin/plane-app - -plane-app -i #--help diff --git a/deploy/1-click/plane-app b/deploy/1-click/plane-app deleted file mode 100644 index ace0a0b79..000000000 --- a/deploy/1-click/plane-app +++ /dev/null @@ -1,791 +0,0 @@ -#!/bin/bash - -function print_header() { -clear - -cat <<"EOF" ---------------------------------------- - ____ _ -| _ \| | __ _ _ __ ___ -| |_) | |/ _` | '_ \ / _ \ -| __/| | (_| | | | | __/ -|_| |_|\__,_|_| |_|\___| - ---------------------------------------- -Project management tool from the future ---------------------------------------- - -EOF -} -function update_env_file() { - config_file=$1 - key=$2 - value=$3 - - # Check if the config file exists - if [ ! -f "$config_file" ]; then - echo "Config file not found. Creating a new one..." >&2 - sudo touch "$config_file" - fi - - # Check if the key already exists in the config file - if sudo grep "^$key=" "$config_file"; then - sudo awk -v key="$key" -v value="$value" -F '=' '{if ($1 == key) $2 = value} 1' OFS='=' "$config_file" | sudo tee "$config_file.tmp" > /dev/null - sudo mv "$config_file.tmp" "$config_file" &> /dev/null - else - # sudo echo "$key=$value" >> "$config_file" - echo -e "$key=$value" | sudo tee -a "$config_file" > /dev/null - fi -} -function read_env_file() { - config_file=$1 - key=$2 - - # Check if the config file exists - if [ ! -f "$config_file" ]; then - echo "Config file not found. Creating a new one..." >&2 - sudo touch "$config_file" - fi - - # Check if the key already exists in the config file - if sudo grep -q "^$key=" "$config_file"; then - value=$(sudo awk -v key="$key" -F '=' '{if ($1 == key) print $2}' "$config_file") - echo "$value" - else - echo "" - fi -} -function update_config() { - config_file="$PLANE_INSTALL_DIR/config.env" - update_env_file $config_file $1 $2 -} -function read_config() { - config_file="$PLANE_INSTALL_DIR/config.env" - read_env_file $config_file $1 -} -function update_env() { - config_file="$PLANE_INSTALL_DIR/.env" - update_env_file $config_file $1 $2 -} -function read_env() { - config_file="$PLANE_INSTALL_DIR/.env" - read_env_file $config_file $1 -} -function show_message() { - print_header - - if [ "$2" == "replace_last_line" ]; then - PROGRESS_MSG[-1]="$1" - else - PROGRESS_MSG+=("$1") - fi - - for statement in "${PROGRESS_MSG[@]}"; do - echo "$statement" - done - -} -function prepare_environment() { - show_message "Prepare Environment..." >&2 - - show_message "- Updating OS with required tools ✋" >&2 - sudo "$PACKAGE_MANAGER" update -y - # sudo "$PACKAGE_MANAGER" upgrade -y - - local required_tools=("curl" "awk" "wget" "nano" "dialog" "git" "uidmap" "jq") - - for tool in "${required_tools[@]}"; do - if ! command -v $tool &> /dev/null; then - sudo "$PACKAGE_MANAGER" install -y $tool - fi - done - - show_message "- OS Updated ✅" "replace_last_line" >&2 - - # Install Docker if not installed - if ! command -v docker &> /dev/null; then - show_message "- Installing Docker ✋" >&2 - # curl -o- https://get.docker.com | bash - - - if [ "$PACKAGE_MANAGER" == "yum" ]; then - sudo $PACKAGE_MANAGER install -y yum-utils - sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo &> /dev/null - elif [ "$PACKAGE_MANAGER" == "apt-get" ]; then - # Add Docker's official GPG key: - sudo $PACKAGE_MANAGER update - sudo $PACKAGE_MANAGER install ca-certificates curl &> /dev/null - sudo install -m 0755 -d /etc/apt/keyrings &> /dev/null - sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc &> /dev/null - sudo chmod a+r /etc/apt/keyrings/docker.asc &> /dev/null - - # Add the repository to Apt sources: - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - - sudo $PACKAGE_MANAGER update - fi - - sudo $PACKAGE_MANAGER install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y - - show_message "- Docker Installed ✅" "replace_last_line" >&2 - else - show_message "- Docker is already installed ✅" >&2 - fi - - update_config "PLANE_ARCH" "$CPU_ARCH" - update_config "DOCKER_VERSION" "$(docker -v | awk '{print $3}' | sed 's/,//g')" - update_config "PLANE_DATA_DIR" "$DATA_DIR" - update_config "PLANE_LOG_DIR" "$LOG_DIR" - - # echo "TRUE" - echo "Environment prepared successfully ✅" - show_message "Environment prepared successfully ✅" >&2 - show_message "" >&2 - return 0 -} -function download_plane() { - # Download Docker Compose File from github url - show_message "Downloading Plane Setup Files ✋" >&2 - sudo curl -H 'Cache-Control: no-cache, no-store' \ - -s -o $PLANE_INSTALL_DIR/docker-compose.yaml \ - https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/selfhost/docker-compose.yml?token=$(date +%s) - - sudo curl -H 'Cache-Control: no-cache, no-store' \ - -s -o $PLANE_INSTALL_DIR/variables-upgrade.env \ - https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/selfhost/variables.env?token=$(date +%s) - - # if .env does not exists rename variables-upgrade.env to .env - if [ ! -f "$PLANE_INSTALL_DIR/.env" ]; then - sudo mv $PLANE_INSTALL_DIR/variables-upgrade.env $PLANE_INSTALL_DIR/.env - fi - - show_message "Plane Setup Files Downloaded ✅" "replace_last_line" >&2 - show_message "" >&2 - - echo "PLANE_DOWNLOADED" - return 0 -} -function printUsageInstructions() { - show_message "" >&2 - show_message "----------------------------------" >&2 - show_message "Usage Instructions" >&2 - show_message "----------------------------------" >&2 - show_message "" >&2 - show_message "To use the Plane Setup utility, use below commands" >&2 - show_message "" >&2 - - show_message "Usage: plane-app [OPTION]" >&2 - show_message "" >&2 - show_message " start Start Server" >&2 - show_message " stop Stop Server" >&2 - show_message " restart Restart Server" >&2 - show_message "" >&2 - show_message "other options" >&2 - show_message " -i, --install Install Plane" >&2 - show_message " -c, --configure Configure Plane" >&2 - show_message " -up, --upgrade Upgrade Plane" >&2 - show_message " -un, --uninstall Uninstall Plane" >&2 - show_message " -ui, --update-installer Update Plane Installer" >&2 - show_message " -h, --help Show help" >&2 - show_message "" >&2 - show_message "" >&2 - show_message "Application Data is stored in mentioned folders" >&2 - show_message " - DB Data: $DATA_DIR/postgres" >&2 - show_message " - Redis Data: $DATA_DIR/redis" >&2 - show_message " - Minio Data: $DATA_DIR/minio" >&2 - show_message "" >&2 - show_message "" >&2 - show_message "----------------------------------" >&2 - show_message "" >&2 -} -function build_local_image() { - show_message "- Downloading Plane Source Code ✋" >&2 - REPO=https://github.com/$CODE_REPO.git - CURR_DIR=$PWD - PLANE_TEMP_CODE_DIR=$PLANE_INSTALL_DIR/temp - sudo rm -rf $PLANE_TEMP_CODE_DIR > /dev/null - - sudo git clone $REPO $PLANE_TEMP_CODE_DIR --branch $DEPLOY_BRANCH --single-branch -q > /dev/null - - sudo cp $PLANE_TEMP_CODE_DIR/deploy/selfhost/build.yml $PLANE_TEMP_CODE_DIR/build.yml - - show_message "- Plane Source Code Downloaded ✅" "replace_last_line" >&2 - - show_message "- Building Docker Images ✋" >&2 - sudo docker compose --env-file=$PLANE_INSTALL_DIR/.env -f $PLANE_TEMP_CODE_DIR/build.yml build --no-cache -} -function check_for_docker_images() { - show_message "" >&2 - # show_message "Building Plane Images" >&2 - - CURR_DIR=$(pwd) - - if [ "$DEPLOY_BRANCH" == "master" ]; then - update_env "APP_RELEASE" "latest" - export APP_RELEASE=latest - else - update_env "APP_RELEASE" "$DEPLOY_BRANCH" - export APP_RELEASE=$DEPLOY_BRANCH - fi - - if [ $USE_GLOBAL_IMAGES == 1 ]; then - # show_message "Building Plane Images for $CPU_ARCH is not required. Skipping... ✅" "replace_last_line" >&2 - export DOCKERHUB_USER=makeplane - update_env "DOCKERHUB_USER" "$DOCKERHUB_USER" - update_env "PULL_POLICY" "always" - echo "Building Plane Images for $CPU_ARCH is not required. Skipping..." - else - export DOCKERHUB_USER=myplane - show_message "Building Plane Images for $CPU_ARCH " >&2 - update_env "DOCKERHUB_USER" "$DOCKERHUB_USER" - update_env "PULL_POLICY" "never" - - build_local_image - - sudo rm -rf $PLANE_INSTALL_DIR/temp > /dev/null - - show_message "- Docker Images Built ✅" "replace_last_line" >&2 - sudo cd $CURR_DIR - fi - - sudo sed -i "s|- pgdata:|- $DATA_DIR/postgres:|g" $PLANE_INSTALL_DIR/docker-compose.yaml - sudo sed -i "s|- redisdata:|- $DATA_DIR/redis:|g" $PLANE_INSTALL_DIR/docker-compose.yaml - sudo sed -i "s|- uploads:|- $DATA_DIR/minio:|g" $PLANE_INSTALL_DIR/docker-compose.yaml - - show_message "Downloading Plane Images for $CPU_ARCH ✋" >&2 - sudo docker compose -f $PLANE_INSTALL_DIR/docker-compose.yaml --env-file=$PLANE_INSTALL_DIR/.env pull - show_message "Plane Images Downloaded ✅" "replace_last_line" >&2 -} -function configure_plane() { - show_message "" >&2 - show_message "Configuring Plane" >&2 - show_message "" >&2 - - exec 3>&1 - - nginx_port=$(read_env "NGINX_PORT") - domain_name=$(read_env "DOMAIN_NAME") - upload_limit=$(read_env "FILE_SIZE_LIMIT") - - NGINX_SETTINGS=$(dialog \ - --ok-label "Next" \ - --cancel-label "Skip" \ - --backtitle "Plane Configuration" \ - --title "Nginx Settings" \ - --form "" \ - 0 0 0 \ - "Port:" 1 1 "${nginx_port:-80}" 1 10 50 0 \ - "Domain:" 2 1 "${domain_name:-localhost}" 2 10 50 0 \ - "Upload Limit:" 3 1 "${upload_limit:-5242880}" 3 10 15 0 \ - 2>&1 1>&3) - - save_nginx_settings=0 - if [ $? -eq 0 ]; then - save_nginx_settings=1 - nginx_port=$(echo "$NGINX_SETTINGS" | sed -n 1p) - domain_name=$(echo "$NGINX_SETTINGS" | sed -n 2p) - upload_limit=$(echo "$NGINX_SETTINGS" | sed -n 3p) - fi - - - # smtp_host=$(read_env "EMAIL_HOST") - # smtp_user=$(read_env "EMAIL_HOST_USER") - # smtp_password=$(read_env "EMAIL_HOST_PASSWORD") - # smtp_port=$(read_env "EMAIL_PORT") - # smtp_from=$(read_env "EMAIL_FROM") - # smtp_tls=$(read_env "EMAIL_USE_TLS") - # smtp_ssl=$(read_env "EMAIL_USE_SSL") - - # SMTP_SETTINGS=$(dialog \ - # --ok-label "Next" \ - # --cancel-label "Skip" \ - # --backtitle "Plane Configuration" \ - # --title "SMTP Settings" \ - # --form "" \ - # 0 0 0 \ - # "Host:" 1 1 "$smtp_host" 1 10 80 0 \ - # "User:" 2 1 "$smtp_user" 2 10 80 0 \ - # "Password:" 3 1 "$smtp_password" 3 10 80 0 \ - # "Port:" 4 1 "${smtp_port:-587}" 4 10 5 0 \ - # "From:" 5 1 "${smtp_from:-Mailer }" 5 10 80 0 \ - # "TLS:" 6 1 "${smtp_tls:-1}" 6 10 1 1 \ - # "SSL:" 7 1 "${smtp_ssl:-0}" 7 10 1 1 \ - # 2>&1 1>&3) - - # save_smtp_settings=0 - # if [ $? -eq 0 ]; then - # save_smtp_settings=1 - # smtp_host=$(echo "$SMTP_SETTINGS" | sed -n 1p) - # smtp_user=$(echo "$SMTP_SETTINGS" | sed -n 2p) - # smtp_password=$(echo "$SMTP_SETTINGS" | sed -n 3p) - # smtp_port=$(echo "$SMTP_SETTINGS" | sed -n 4p) - # smtp_from=$(echo "$SMTP_SETTINGS" | sed -n 5p) - # smtp_tls=$(echo "$SMTP_SETTINGS" | sed -n 6p) - # fi - external_pgdb_url=$(dialog \ - --backtitle "Plane Configuration" \ - --title "Using External Postgres Database ?" \ - --ok-label "Next" \ - --cancel-label "Skip" \ - --inputbox "Enter your external database url" \ - 8 60 3>&1 1>&2 2>&3) - - - external_redis_url=$(dialog \ - --backtitle "Plane Configuration" \ - --title "Using External Redis Database ?" \ - --ok-label "Next" \ - --cancel-label "Skip" \ - --inputbox "Enter your external redis url" \ - 8 60 3>&1 1>&2 2>&3) - - - aws_region=$(read_env "AWS_REGION") - aws_access_key=$(read_env "AWS_ACCESS_KEY_ID") - aws_secret_key=$(read_env "AWS_SECRET_ACCESS_KEY") - aws_bucket=$(read_env "AWS_S3_BUCKET_NAME") - - - AWS_S3_SETTINGS=$(dialog \ - --ok-label "Next" \ - --cancel-label "Skip" \ - --backtitle "Plane Configuration" \ - --title "AWS S3 Bucket Configuration" \ - --form "" \ - 0 0 0 \ - "Region:" 1 1 "$aws_region" 1 10 50 0 \ - "Access Key:" 2 1 "$aws_access_key" 2 10 50 0 \ - "Secret Key:" 3 1 "$aws_secret_key" 3 10 50 0 \ - "Bucket:" 4 1 "$aws_bucket" 4 10 50 0 \ - 2>&1 1>&3) - - save_aws_settings=0 - if [ $? -eq 0 ]; then - save_aws_settings=1 - aws_region=$(echo "$AWS_S3_SETTINGS" | sed -n 1p) - aws_access_key=$(echo "$AWS_S3_SETTINGS" | sed -n 2p) - aws_secret_key=$(echo "$AWS_S3_SETTINGS" | sed -n 3p) - aws_bucket=$(echo "$AWS_S3_SETTINGS" | sed -n 4p) - fi - - # display dialogbox asking for confirmation to continue - CONFIRM_CONFIG=$(dialog \ - --title "Confirm Configuration" \ - --backtitle "Plane Configuration" \ - --yes-label "Confirm" \ - --no-label "Cancel" \ - --yesno \ - " - save_ngnix_settings: $save_nginx_settings - nginx_port: $nginx_port - domain_name: $domain_name - upload_limit: $upload_limit - - save_aws_settings: $save_aws_settings - aws_region: $aws_region - aws_access_key: $aws_access_key - aws_secret_key: $aws_secret_key - aws_bucket: $aws_bucket - - pdgb_url: $external_pgdb_url - redis_url: $external_redis_url - " \ - 0 0 3>&1 1>&2 2>&3) - - if [ $? -eq 0 ]; then - if [ $save_nginx_settings == 1 ]; then - update_env "NGINX_PORT" "$nginx_port" - update_env "DOMAIN_NAME" "$domain_name" - update_env "WEB_URL" "http://$domain_name" - update_env "CORS_ALLOWED_ORIGINS" "http://$domain_name" - update_env "FILE_SIZE_LIMIT" "$upload_limit" - fi - - # check enable smpt settings value - # if [ $save_smtp_settings == 1 ]; then - # update_env "EMAIL_HOST" "$smtp_host" - # update_env "EMAIL_HOST_USER" "$smtp_user" - # update_env "EMAIL_HOST_PASSWORD" "$smtp_password" - # update_env "EMAIL_PORT" "$smtp_port" - # update_env "EMAIL_FROM" "$smtp_from" - # update_env "EMAIL_USE_TLS" "$smtp_tls" - # update_env "EMAIL_USE_SSL" "$smtp_ssl" - # fi - - # check enable aws settings value - if [[ $save_aws_settings == 1 && $aws_access_key != "" && $aws_secret_key != "" ]] ; then - update_env "USE_MINIO" "0" - update_env "AWS_REGION" "$aws_region" - update_env "AWS_ACCESS_KEY_ID" "$aws_access_key" - update_env "AWS_SECRET_ACCESS_KEY" "$aws_secret_key" - update_env "AWS_S3_BUCKET_NAME" "$aws_bucket" - elif [[ -z $aws_access_key || -z $aws_secret_key ]] ; then - update_env "USE_MINIO" "1" - update_env "AWS_REGION" "" - update_env "AWS_ACCESS_KEY_ID" "" - update_env "AWS_SECRET_ACCESS_KEY" "" - update_env "AWS_S3_BUCKET_NAME" "uploads" - fi - - if [ "$external_pgdb_url" != "" ]; then - update_env "DATABASE_URL" "$external_pgdb_url" - fi - if [ "$external_redis_url" != "" ]; then - update_env "REDIS_URL" "$external_redis_url" - fi - fi - - exec 3>&- -} -function upgrade_configuration() { - upg_env_file="$PLANE_INSTALL_DIR/variables-upgrade.env" - # Check if the file exists - if [ -f "$upg_env_file" ]; then - # Read each line from the file - while IFS= read -r line; do - # Skip comments and empty lines - if [[ "$line" =~ ^\s*#.*$ ]] || [[ -z "$line" ]]; then - continue - fi - - # Split the line into key and value - key=$(echo "$line" | cut -d'=' -f1) - value=$(echo "$line" | cut -d'=' -f2-) - - current_value=$(read_env "$key") - - if [ -z "$current_value" ]; then - update_env "$key" "$value" - fi - done < "$upg_env_file" - fi -} -function install() { - show_message "" - if [ "$(uname)" == "Linux" ]; then - OS="linux" - OS_NAME=$(sudo awk -F= '/^ID=/{print $2}' /etc/os-release) - OS_NAME=$(echo "$OS_NAME" | tr -d '"') - print_header - if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || - [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then - OS_SUPPORTED=true - show_message "******** Installing Plane ********" - show_message "" - - prepare_environment - - if [ $? -eq 0 ]; then - download_plane - if [ $? -eq 0 ]; then - # create_service - check_for_docker_images - - last_installed_on=$(read_config "INSTALLATION_DATE") - # if [ "$last_installed_on" == "" ]; then - # configure_plane - # fi - - update_env "NGINX_PORT" "80" - update_env "DOMAIN_NAME" "$MY_IP" - update_env "WEB_URL" "http://$MY_IP" - update_env "CORS_ALLOWED_ORIGINS" "http://$MY_IP" - - update_config "INSTALLATION_DATE" "$(date '+%Y-%m-%d')" - - show_message "Plane Installed Successfully ✅" - show_message "" - else - show_message "Download Failed ❌" - exit 1 - fi - else - show_message "Initialization Failed ❌" - exit 1 - fi - - else - OS_SUPPORTED=false - PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌" - show_message "" - exit 1 - fi - else - PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌" - show_message "" - exit 1 - fi -} -function upgrade() { - print_header - if [ "$(uname)" == "Linux" ]; then - OS="linux" - OS_NAME=$(sudo awk -F= '/^ID=/{print $2}' /etc/os-release) - OS_NAME=$(echo "$OS_NAME" | tr -d '"') - if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || - [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then - - OS_SUPPORTED=true - show_message "******** Upgrading Plane ********" - show_message "" - - prepare_environment - - if [ $? -eq 0 ]; then - stop_server - download_plane - if [ $? -eq 0 ]; then - check_for_docker_images - upgrade_configuration - update_config "UPGRADE_DATE" "$(date)" - - start_server - - show_message "" - show_message "Plane Upgraded Successfully ✅" - show_message "" - printUsageInstructions - else - show_message "Download Failed ❌" - exit 1 - fi - else - show_message "Initialization Failed ❌" - exit 1 - fi - else - PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌" - show_message "" - exit 1 - fi - else - PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌" - show_message "" - exit 1 - fi -} -function uninstall() { - print_header - if [ "$(uname)" == "Linux" ]; then - OS="linux" - OS_NAME=$(awk -F= '/^ID=/{print $2}' /etc/os-release) - OS_NAME=$(echo "$OS_NAME" | tr -d '"') - if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || - [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then - - OS_SUPPORTED=true - show_message "******** Uninstalling Plane ********" - show_message "" - - stop_server - - if ! [ -x "$(command -v docker)" ]; then - echo "DOCKER_NOT_INSTALLED" &> /dev/null - else - # Ask of user input to confirm uninstall docker ? - CONFIRM_DOCKER_PURGE=$(dialog --title "Uninstall Docker" --defaultno --yesno "Are you sure you want to uninstall docker ?" 8 60 3>&1 1>&2 2>&3) - if [ $? -eq 0 ]; then - show_message "- Uninstalling Docker ✋" - sudo docker images -q | xargs -r sudo docker rmi -f &> /dev/null - sudo "$PACKAGE_MANAGER" remove -y docker-engine docker docker.io docker-ce docker-ce-cli docker-compose-plugin &> /dev/null - sudo "$PACKAGE_MANAGER" autoremove -y docker-engine docker docker.io docker-ce docker-compose-plugin &> /dev/null - show_message "- Docker Uninstalled ✅" "replace_last_line" >&2 - fi - fi - - sudo rm $PLANE_INSTALL_DIR/.env &> /dev/null - sudo rm $PLANE_INSTALL_DIR/variables-upgrade.env &> /dev/null - sudo rm $PLANE_INSTALL_DIR/config.env &> /dev/null - sudo rm $PLANE_INSTALL_DIR/docker-compose.yaml &> /dev/null - - # rm -rf $PLANE_INSTALL_DIR &> /dev/null - show_message "- Configuration Cleaned ✅" - - show_message "" - show_message "******** Plane Uninstalled ********" - show_message "" - show_message "" - show_message "Plane Configuration Cleaned with some exceptions" - show_message "- DB Data: $DATA_DIR/postgres" - show_message "- Redis Data: $DATA_DIR/redis" - show_message "- Minio Data: $DATA_DIR/minio" - show_message "" - show_message "" - show_message "Thank you for using Plane. We hope to see you again soon." - show_message "" - show_message "" - else - PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌" - show_message "" - exit 1 - fi - else - PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌" - show_message "" - exit 1 - fi -} -function start_server() { - docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml" - env_file="$PLANE_INSTALL_DIR/.env" - # check if both the files exits - if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then - show_message "Starting Plane Server ($APP_RELEASE) ✋" - sudo docker compose -f $docker_compose_file --env-file=$env_file up -d - - # Wait for containers to be running - echo "Waiting for containers to start..." - while ! sudo docker compose -f "$docker_compose_file" --env-file="$env_file" ps --services --filter "status=running" --quiet | grep -q "."; do - sleep 1 - done - # wait for migrator container to exit with status 0 before starting the application - migrator_container_id=$(sudo docker container ls -aq -f "name=plane-migrator") - - # if migrator container is running, wait for it to exit - if [ -n "$migrator_container_id" ]; then - while sudo docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do - show_message "Waiting for Plane Server ($APP_RELEASE) to start...✋ (Migrator in progress)" "replace_last_line" >&2 - sleep 1 - done - fi - - # if migrator exit status is not 0, show error message and exit - if [ -n "$migrator_container_id" ]; then - migrator_exit_code=$(sudo docker inspect --format='{{.State.ExitCode}}' $migrator_container_id) - if [ $migrator_exit_code -ne 0 ]; then - # show_message "Migrator failed with exit code $migrator_exit_code ❌" "replace_last_line" >&2 - show_message "Plane Server failed to start ❌" "replace_last_line" >&2 - stop_server - exit 1 - fi - fi - - api_container_id=$(sudo docker container ls -q -f "name=plane-api") - while ! sudo docker logs $api_container_id 2>&1 | grep -i "Application startup complete"; - do - show_message "Waiting for Plane Server ($APP_RELEASE) to start...✋ (API starting)" "replace_last_line" >&2 - sleep 1 - done - show_message "Plane Server Started ($APP_RELEASE) ✅" "replace_last_line" >&2 - show_message "---------------------------------------------------------------" >&2 - show_message "Access the Plane application at http://$MY_IP" >&2 - show_message "---------------------------------------------------------------" >&2 - - else - show_message "Plane Server not installed. Please install Plane first ❌" "replace_last_line" >&2 - fi -} -function stop_server() { - docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml" - env_file="$PLANE_INSTALL_DIR/.env" - # check if both the files exits - if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then - show_message "Stopping Plane Server ($APP_RELEASE) ✋" - sudo docker compose -f $docker_compose_file --env-file=$env_file down - show_message "Plane Server Stopped ($APP_RELEASE) ✅" "replace_last_line" >&2 - else - show_message "Plane Server not installed [Skipping] ✅" "replace_last_line" >&2 - fi -} -function restart_server() { - docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml" - env_file="$PLANE_INSTALL_DIR/.env" - # check if both the files exits - if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then - show_message "Restarting Plane Server ($APP_RELEASE) ✋" - sudo docker compose -f $docker_compose_file --env-file=$env_file restart - show_message "Plane Server Restarted ($APP_RELEASE) ✅" "replace_last_line" >&2 - else - show_message "Plane Server not installed. Please install Plane first ❌" "replace_last_line" >&2 - fi -} -function show_help() { - # print_header - show_message "Usage: plane-app [OPTION]" >&2 - show_message "" >&2 - show_message " start Start Server" >&2 - show_message " stop Stop Server" >&2 - show_message " restart Restart Server" >&2 - show_message "" >&2 - show_message "other options" >&2 - show_message " -i, --install Install Plane" >&2 - show_message " -c, --configure Configure Plane" >&2 - show_message " -up, --upgrade Upgrade Plane" >&2 - show_message " -un, --uninstall Uninstall Plane" >&2 - show_message " -ui, --update-installer Update Plane Installer" >&2 - show_message " -h, --help Show help" >&2 - show_message "" >&2 - exit 1 - -} -function update_installer() { - show_message "Updating Plane Installer ✋" >&2 - sudo curl -H 'Cache-Control: no-cache, no-store' \ - -s -o /usr/local/bin/plane-app \ - https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/1-click/plane-app?token=$(date +%s) - - sudo chmod +x /usr/local/bin/plane-app > /dev/null&> /dev/null - show_message "Plane Installer Updated ✅" "replace_last_line" >&2 -} - -export DEPLOY_BRANCH=${BRANCH:-master} -export APP_RELEASE=$DEPLOY_BRANCH -export DOCKERHUB_USER=makeplane -export PULL_POLICY=always - -if [ "$DEPLOY_BRANCH" == "master" ]; then - export APP_RELEASE=latest -fi - -PLANE_INSTALL_DIR=/opt/plane -DATA_DIR=$PLANE_INSTALL_DIR/data -LOG_DIR=$PLANE_INSTALL_DIR/logs -CODE_REPO=${GIT_REPO:-makeplane/plane} -OS_SUPPORTED=false -CPU_ARCH=$(uname -m) -PROGRESS_MSG="" -USE_GLOBAL_IMAGES=0 -PACKAGE_MANAGER="" -MY_IP=$(curl -s ifconfig.me) - -if [[ $CPU_ARCH == "amd64" || $CPU_ARCH == "x86_64" || ( $DEPLOY_BRANCH == "master" && ( $CPU_ARCH == "arm64" || $CPU_ARCH == "aarch64" ) ) ]]; then - USE_GLOBAL_IMAGES=1 -fi - -sudo mkdir -p $PLANE_INSTALL_DIR/{data,log} - -if command -v apt-get &> /dev/null; then - PACKAGE_MANAGER="apt-get" -elif command -v yum &> /dev/null; then - PACKAGE_MANAGER="yum" -elif command -v apk &> /dev/null; then - PACKAGE_MANAGER="apk" -fi - -if [ "$1" == "start" ]; then - start_server -elif [ "$1" == "stop" ]; then - stop_server -elif [ "$1" == "restart" ]; then - restart_server -elif [ "$1" == "--install" ] || [ "$1" == "-i" ]; then - install - start_server - show_message "" >&2 - show_message "To view help, use plane-app --help " >&2 -elif [ "$1" == "--configure" ] || [ "$1" == "-c" ]; then - configure_plane - printUsageInstructions -elif [ "$1" == "--upgrade" ] || [ "$1" == "-up" ]; then - upgrade -elif [ "$1" == "--uninstall" ] || [ "$1" == "-un" ]; then - uninstall -elif [ "$1" == "--update-installer" ] || [ "$1" == "-ui" ]; then - update_installer -elif [ "$1" == "--help" ] || [ "$1" == "-h" ]; then - show_help -else - show_help -fi From 8911eaf676cc12e721418c4d0914b05e4aedc1c7 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:36:16 +0530 Subject: [PATCH 02/53] fix: profile cover fix (#4010) --- web/components/core/image-picker-popover.tsx | 55 +++++++++++++------- web/pages/profile/index.tsx | 1 + 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/web/components/core/image-picker-popover.tsx b/web/components/core/image-picker-popover.tsx index f8c247ce7..a4a55e702 100644 --- a/web/components/core/image-picker-popover.tsx +++ b/web/components/core/image-picker-popover.tsx @@ -40,13 +40,14 @@ type Props = { onChange: (data: string) => void; disabled?: boolean; tabIndex?: number; + isProfileCover?: boolean; }; // services const fileService = new FileService(); export const ImagePickerPopover: React.FC = observer((props) => { - const { label, value, control, onChange, disabled = false, tabIndex } = props; + const { label, value, control, onChange, disabled = false, tabIndex, isProfileCover = false } = props; // states const [image, setImage] = useState(null); const [isImageUploading, setIsImageUploading] = useState(false); @@ -97,31 +98,47 @@ export const ImagePickerPopover: React.FC = observer((props) => { const handleSubmit = async () => { setIsImageUploading(true); - if (!image || !workspaceSlug) return; + if (!image) return; const formData = new FormData(); formData.append("asset", image); formData.append("attributes", JSON.stringify({})); - fileService - .uploadFile(workspaceSlug.toString(), formData) - .then((res) => { - const oldValue = value; - const isUnsplashImage = oldValue?.split("/")[2] === "images.unsplash.com"; + const oldValue = value; + const isUnsplashImage = oldValue?.split("/")[2] === "images.unsplash.com"; - const imageUrl = res.asset; - onChange(imageUrl); - setIsImageUploading(false); - setImage(null); - setIsOpen(false); + const uploadCallback = (res: any) => { + const imageUrl = res.asset; + onChange(imageUrl); + setIsImageUploading(false); + setImage(null); + setIsOpen(false); + }; - if (isUnsplashImage) return; - - if (oldValue && currentWorkspace) fileService.deleteFile(currentWorkspace.id, oldValue); - }) - .catch((err) => { - console.error(err); - }); + if (isProfileCover) { + fileService + .uploadUserFile(formData) + .then((res) => { + uploadCallback(res); + if (isUnsplashImage) return; + if (oldValue && currentWorkspace) fileService.deleteUserFile(oldValue); + }) + .catch((err) => { + console.error(err); + }); + } else { + if (!workspaceSlug) return; + fileService + .uploadFile(workspaceSlug.toString(), formData) + .then((res) => { + uploadCallback(res); + if (isUnsplashImage) return; + if (oldValue && currentWorkspace) fileService.deleteFile(currentWorkspace.id, oldValue); + }) + .catch((err) => { + console.error(err); + }); + } }; useEffect(() => { diff --git a/web/pages/profile/index.tsx b/web/pages/profile/index.tsx index a3b96bce7..6d2fe4d54 100644 --- a/web/pages/profile/index.tsx +++ b/web/pages/profile/index.tsx @@ -215,6 +215,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => { onChange={(imageUrl) => onChange(imageUrl)} control={control} value={value ?? "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"} + isProfileCover /> )} /> From 15e04e55bb31ecd893d4c9d669fa2d9560c005c0 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 21 Mar 2024 20:46:02 +0530 Subject: [PATCH 03/53] [WEB-692] fix: project modal cover image popover z-index fix (#4018) * fix: project modal cover image popover z-index fix * fix: project modal cover image popover z-index fix --- web/components/core/image-picker-popover.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/components/core/image-picker-popover.tsx b/web/components/core/image-picker-popover.tsx index a4a55e702..53e1179dc 100644 --- a/web/components/core/image-picker-popover.tsx +++ b/web/components/core/image-picker-popover.tsx @@ -166,7 +166,7 @@ export const ImagePickerPopover: React.FC = observer((props) => { useOutsideClickDetector(ref, handleClose); return ( - + = observer((props) => { {isOpen && (

Date: Thu, 21 Mar 2024 20:46:18 +0530 Subject: [PATCH 04/53] fix: rendering default state in the issue create update modal whenever we switch between the projects in the issue modal (#4024) --- web/components/dropdowns/state.tsx | 54 ++++++++++++++++++++---------- web/store/state.store.ts | 2 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/web/components/dropdowns/state.tsx b/web/components/dropdowns/state.tsx index 7ba69d1ce..7775f3946 100644 --- a/web/components/dropdowns/state.tsx +++ b/web/components/dropdowns/state.tsx @@ -4,7 +4,7 @@ import { usePopper } from "react-popper"; import { Check, ChevronDown, Search } from "lucide-react"; import { Combobox } from "@headlessui/react"; // hooks -import { StateGroupIcon } from "@plane/ui"; +import { Spinner, StateGroupIcon } from "@plane/ui"; import { cn } from "@/helpers/common.helper"; import { useApplication, useProjectState } from "@/hooks/store"; import { useDropdownKeyDown } from "@/hooks/use-dropdown-key-down"; @@ -50,6 +50,7 @@ export const StateDropdown: React.FC = observer((props) => { // states const [query, setQuery] = useState(""); const [isOpen, setIsOpen] = useState(false); + const [stateLoader, setStateLoader] = useState(false); // refs const dropdownRef = useRef(null); const inputRef = useRef(null); @@ -74,6 +75,8 @@ export const StateDropdown: React.FC = observer((props) => { } = useApplication(); const { fetchProjectStates, getProjectStates, getStateById } = useProjectState(); const statesList = getProjectStates(projectId); + const defaultStateList = statesList?.find((state) => state.default); + const stateValue = value ? value : defaultStateList?.id; const options = statesList?.map((state) => ({ value: state.id, @@ -89,11 +92,19 @@ export const StateDropdown: React.FC = observer((props) => { const filteredOptions = query === "" ? options : options?.filter((o) => o.query.toLowerCase().includes(query.toLowerCase())); - const selectedState = getStateById(value); + const selectedState = stateValue ? getStateById(stateValue) : undefined; - const onOpen = () => { - if (!statesList && workspaceSlug) fetchProjectStates(workspaceSlug, projectId); + const onOpen = async () => { + if (!statesList && workspaceSlug) { + setStateLoader(true); + await fetchProjectStates(workspaceSlug, projectId); + setStateLoader(false); + } }; + useEffect(() => { + if (projectId) onOpen(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [projectId]); const handleClose = () => { if (!isOpen) return; @@ -141,7 +152,7 @@ export const StateDropdown: React.FC = observer((props) => { ref={dropdownRef} tabIndex={tabIndex} className={cn("h-full", className)} - value={value} + value={stateValue} onChange={dropdownOnChange} disabled={disabled} onKeyDown={handleKeyDown} @@ -178,18 +189,27 @@ export const StateDropdown: React.FC = observer((props) => { showTooltip={showTooltip} variant={buttonVariant} > - {!hideIcon && ( - - )} - {BUTTON_VARIANTS_WITH_TEXT.includes(buttonVariant) && ( - {selectedState?.name ?? "State"} - )} - {dropdownArrow && ( -
-
+

{project.description && project.description.trim() !== "" ? project.description : `Created on ${renderFormattedDate(project.created_at)}`}

- 0 ? `${project.members.length} Members` : "No Member" - } - position="top" - > - {projectMembersIds && projectMembersIds.length > 0 ? ( -
- - {projectMembersIds.map((memberId) => { - const member = project.members?.find((m) => m.member_id === memberId); - - if (!member) return null; - - return ; - })} - +
+ 0 ? `${project.members.length} Members` : "No Member" + } + position="top" + > + {projectMembersIds && projectMembersIds.length > 0 ? ( +
+ + {projectMembersIds.map((memberId) => { + const member = project.members?.find((m) => m.member_id === memberId); + if (!member) return null; + return ( + + ); + })} + +
+ ) : ( + No Member Yet + )} +
+ {isArchived &&
Archived
} +
+ {isArchived ? ( + isOwner && ( +
+
{ + e.preventDefault(); + e.stopPropagation(); + setRestoreProject(true); + }} + > +
+ + Restore +
+
+
{ + e.preventDefault(); + e.stopPropagation(); + setDeleteProjectModal(true); + }} + > + +
- ) : ( - No Member Yet - )} - - {project.is_member && - (isOwner || isMember ? ( - { - e.stopPropagation(); - }} - href={`/${workspaceSlug}/projects/${project.id}/settings`} - > - - - ) : ( - - - Joined - - ))} - {!project.is_member && ( -
- -
+ ) + ) : ( + <> + {project.is_member && + (isOwner || isMember ? ( + { + e.stopPropagation(); + }} + href={`/${workspaceSlug}/projects/${project.id}/settings`} + > + + + ) : ( + + + Joined + + ))} + {!project.is_member && ( +
+ +
+ )} + )}
diff --git a/web/components/project/dropdowns/filters/root.tsx b/web/components/project/dropdowns/filters/root.tsx index a7e50cec1..12008eecd 100644 --- a/web/components/project/dropdowns/filters/root.tsx +++ b/web/components/project/dropdowns/filters/root.tsx @@ -51,6 +51,15 @@ export const ProjectFiltersSelection: React.FC = observer((props) => { } title="My projects" /> + + handleDisplayFiltersUpdate({ + archived_projects: !displayFilters.archived_projects, + }) + } + title="Archived" + />
{/* access */} diff --git a/web/components/project/settings/archive-project/archive-restore-modal.tsx b/web/components/project/settings/archive-project/archive-restore-modal.tsx new file mode 100644 index 000000000..88361895c --- /dev/null +++ b/web/components/project/settings/archive-project/archive-restore-modal.tsx @@ -0,0 +1,135 @@ +import { useState, Fragment } from "react"; +import { useRouter } from "next/router"; +import { Dialog, Transition } from "@headlessui/react"; +// ui +import { Button, TOAST_TYPE, setToast } from "@plane/ui"; +// hooks +import { useProject } from "@/hooks/store"; + +type Props = { + workspaceSlug: string; + projectId: string; + isOpen: boolean; + onClose: () => void; + archive: boolean; +}; + +export const ArchiveRestoreProjectModal: React.FC = (props) => { + const { workspaceSlug, projectId, isOpen, onClose, archive } = props; + // router + const router = useRouter(); + // states + const [isLoading, setIsLoading] = useState(false); + // store hooks + const { getProjectById, archiveProject, restoreProject } = useProject(); + + const projectDetails = getProjectById(projectId); + if (!projectDetails) return null; + + const handleClose = () => { + setIsLoading(false); + onClose(); + }; + + const handleArchiveProject = async () => { + setIsLoading(true); + await archiveProject(workspaceSlug, projectId) + .then(() => { + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Archive success", + message: `${projectDetails.name} has been archived successfully`, + }); + onClose(); + router.push(`/${workspaceSlug}/projects/`); + }) + .catch(() => + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Project could not be archived. Please try again.", + }) + ) + .finally(() => setIsLoading(false)); + }; + + const handleRestoreProject = async () => { + setIsLoading(true); + await restoreProject(workspaceSlug, projectId) + .then(() => { + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Restore success", + message: `You can find ${projectDetails.name} in your projects.`, + }); + onClose(); + router.push(`/${workspaceSlug}/projects/`); + }) + .catch(() => + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Project could not be restored. Please try again.", + }) + ) + .finally(() => setIsLoading(false)); + }; + + return ( + + + +
+ + +
+
+ + +
+

+ {archive ? "Archive" : "Restore"} {projectDetails.name} +

+

+ {archive + ? "This project and its issues, cycles, modules, and pages will be archived. Its issues won’t appear in search. Only project admins can restore the project." + : "Restoring a project will activate it and make it visible to all members of the project. Are you sure you want to continue?"} +

+
+ + +
+
+
+
+
+
+
+
+ ); +}; diff --git a/web/components/project/settings/archive-project/index.tsx b/web/components/project/settings/archive-project/index.tsx new file mode 100644 index 000000000..23da8dcb2 --- /dev/null +++ b/web/components/project/settings/archive-project/index.tsx @@ -0,0 +1,2 @@ +export * from "./selection"; +export * from "./archive-restore-modal"; diff --git a/web/components/project/settings/archive-project/selection.tsx b/web/components/project/settings/archive-project/selection.tsx new file mode 100644 index 000000000..14fb43053 --- /dev/null +++ b/web/components/project/settings/archive-project/selection.tsx @@ -0,0 +1,60 @@ +import React from "react"; +import { ChevronRight, ChevronUp } from "lucide-react"; +import { Disclosure, Transition } from "@headlessui/react"; +// types +import { IProject } from "@plane/types"; +// ui +import { Button, Loader } from "@plane/ui"; + +export interface IArchiveProject { + projectDetails: IProject; + handleArchive: () => void; +} + +export const ArchiveProjectSelection: React.FC = (props) => { + const { projectDetails, handleArchive } = props; + + return ( + + {({ open }) => ( +
+ + Archive project + {open ? : } + + + +
+ + Archiving a project will unlist your project from your side navigation although you will still be able + to access it from your projects page. You can restore the project or delete it whenever you want. + +
+ {projectDetails ? ( +
+ +
+ ) : ( + + + + )} +
+
+
+
+
+ )} +
+ ); +}; diff --git a/web/components/project/settings/delete-project-section.tsx b/web/components/project/settings/delete-project-section.tsx index 991b29207..690f67432 100644 --- a/web/components/project/settings/delete-project-section.tsx +++ b/web/components/project/settings/delete-project-section.tsx @@ -1,12 +1,10 @@ import React from "react"; - -// ui -import { ChevronDown, ChevronUp } from "lucide-react"; +import { ChevronRight, ChevronUp } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; -import { IProject } from "@plane/types"; -import { Button, Loader } from "@plane/ui"; -// icons // types +import { IProject } from "@plane/types"; +// ui +import { Button, Loader } from "@plane/ui"; export interface IDeleteProjectSection { projectDetails: IProject; @@ -17,12 +15,12 @@ export const DeleteProjectSection: React.FC = (props) => const { projectDetails, handleDelete } = props; return ( - + {({ open }) => (
- + Delete Project - {open ? : } + {open ? : } = (props) => leaveTo="transform opacity-0" > -
+
The danger zone of the project delete page is a critical area that requires careful consideration and attention. When deleting a project, all of the data and resources within that project will be diff --git a/web/components/project/settings/index.ts b/web/components/project/settings/index.ts index 0bf79ec17..0f8e9aa6d 100644 --- a/web/components/project/settings/index.ts +++ b/web/components/project/settings/index.ts @@ -1,2 +1,3 @@ export * from "./delete-project-section"; export * from "./features-list"; +export * from "./archive-project"; diff --git a/web/constants/empty-state.ts b/web/constants/empty-state.ts index 8be4a52e2..6705021a5 100644 --- a/web/constants/empty-state.ts +++ b/web/constants/empty-state.ts @@ -125,9 +125,9 @@ const emptyStateDetails = { }, [EmptyStateType.WORKSPACE_PROJECTS]: { key: EmptyStateType.WORKSPACE_PROJECTS, - title: "Start a Project", + title: "No active projects", description: - "Think of each project as the parent for goal-oriented work. Projects are where Jobs, Cycles, and Modules live and, along with your colleagues, help you achieve that goal.", + "Think of each project as the parent for goal-oriented work. Projects are where Jobs, Cycles, and Modules live and, along with your colleagues, help you achieve that goal. Create a new project or filter for archived projects.", path: "/empty-state/onboarding/projects", primaryButton: { text: "Start your first project", diff --git a/web/constants/project.ts b/web/constants/project.ts index 6393a6a6c..c4ef817fd 100644 --- a/web/constants/project.ts +++ b/web/constants/project.ts @@ -1,9 +1,9 @@ // icons import { Globe2, Lock, LucideIcon } from "lucide-react"; +import { TProjectAppliedDisplayFilterKeys, TProjectOrderByOptions } from "@plane/types"; import { SettingIcon } from "@/components/icons"; // types import { Props } from "@/components/icons/types"; -import { TProjectOrderByOptions } from "@plane/types"; export enum EUserProjectRoles { GUEST = 5, @@ -162,3 +162,17 @@ export const PROJECT_ORDER_BY_OPTIONS: { label: "Number of members", }, ]; + +export const PROJECT_DISPLAY_FILTER_OPTIONS: { + key: TProjectAppliedDisplayFilterKeys; + label: string; +}[] = [ + { + key: "my_projects", + label: "My projects", + }, + { + key: "archived_projects", + label: "Archived", + }, +]; diff --git a/web/helpers/project.helper.ts b/web/helpers/project.helper.ts index b4c461bb4..f479eb25c 100644 --- a/web/helpers/project.helper.ts +++ b/web/helpers/project.helper.ts @@ -1,11 +1,11 @@ import sortBy from "lodash/sortBy"; -// helpers -import { satisfiesDateFilter } from "@/helpers/filter.helper"; -import { getDate } from "@/helpers/date-time.helper"; // types import { IProject, TProjectDisplayFilters, TProjectFilters, TProjectOrderByOptions } from "@plane/types"; // constants import { EUserProjectRoles } from "@/constants/project"; +// helpers +import { getDate } from "@/helpers/date-time.helper"; +import { satisfiesDateFilter } from "@/helpers/filter.helper"; /** * Updates the sort order of the project. @@ -93,6 +93,8 @@ export const shouldFilterProject = ( } }); if (displayFilters.my_projects && !project.is_member) fallsInFilters = false; + if (displayFilters.archived_projects && !project.archived_at) fallsInFilters = false; + if (project.archived_at) fallsInFilters = displayFilters.archived_projects ? fallsInFilters : false; return fallsInFilters; }; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx index f099a97f7..946d9b9cb 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx @@ -2,26 +2,29 @@ import { useState, ReactElement } from "react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; import useSWR from "swr"; -// hooks +// components import { PageHead } from "@/components/core"; import { ProjectSettingHeader } from "@/components/headers"; import { + ArchiveRestoreProjectModal, + ArchiveProjectSelection, DeleteProjectModal, DeleteProjectSection, ProjectDetailsForm, ProjectDetailsFormLoader, } from "@/components/project"; +// hooks import { useProject } from "@/hooks/store"; // layouts import { AppLayout } from "@/layouts/app-layout"; import { ProjectSettingLayout } from "@/layouts/settings-layout"; -// components // types import { NextPageWithLayout } from "@/lib/types"; const GeneralSettingsPage: NextPageWithLayout = observer(() => { // states const [selectProject, setSelectedProject] = useState(null); + const [archiveProject, setArchiveProject] = useState(false); // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -42,12 +45,21 @@ const GeneralSettingsPage: NextPageWithLayout = observer(() => { return ( <> - {currentProjectDetails && ( - setSelectedProject(null)} - /> + {currentProjectDetails && workspaceSlug && projectId && ( + <> + setArchiveProject(false)} + archive + /> + setSelectedProject(null)} + /> + )}
@@ -63,10 +75,16 @@ const GeneralSettingsPage: NextPageWithLayout = observer(() => { )} {isAdmin && ( - setSelectedProject(currentProjectDetails.id ?? null)} - /> + <> + setArchiveProject(true)} + /> + setSelectedProject(currentProjectDetails.id ?? null)} + /> + )}
diff --git a/web/pages/[workspaceSlug]/projects/index.tsx b/web/pages/[workspaceSlug]/projects/index.tsx index 1e153b688..5db5daa34 100644 --- a/web/pages/[workspaceSlug]/projects/index.tsx +++ b/web/pages/[workspaceSlug]/projects/index.tsx @@ -1,6 +1,6 @@ import { ReactElement, useCallback } from "react"; import { observer } from "mobx-react"; -import { TProjectFilters } from "@plane/types"; +import { TProjectAppliedDisplayFilterKeys, TProjectFilters } from "@plane/types"; // components import { PageHead } from "@/components/core"; import { ProjectsHeader } from "@/components/headers"; @@ -19,8 +19,15 @@ const ProjectsPage: NextPageWithLayout = observer(() => { router: { workspaceSlug }, } = useApplication(); const { currentWorkspace } = useWorkspace(); - const { workspaceProjectIds, filteredProjectIds } = useProject(); - const { currentWorkspaceFilters, clearAllFilters, updateFilters } = useProjectFilter(); + const { totalProjectIds, filteredProjectIds } = useProject(); + const { + currentWorkspaceFilters, + currentWorkspaceAppliedDisplayFilters, + clearAllFilters, + clearAllAppliedDisplayFilters, + updateFilters, + updateDisplayFilters, + } = useProjectFilter(); // derived values const pageTitle = currentWorkspace?.name ? `${currentWorkspace?.name} - Projects` : undefined; @@ -37,18 +44,35 @@ const ProjectsPage: NextPageWithLayout = observer(() => { [currentWorkspaceFilters, updateFilters, workspaceSlug] ); + const handleRemoveDisplayFilter = useCallback( + (key: TProjectAppliedDisplayFilterKeys) => { + if (!workspaceSlug) return; + updateDisplayFilters(workspaceSlug.toString(), { [key]: false }); + }, + [updateDisplayFilters, workspaceSlug] + ); + + const handleClearAllFilters = useCallback(() => { + if (!workspaceSlug) return; + clearAllFilters(workspaceSlug.toString()); + clearAllAppliedDisplayFilters(workspaceSlug.toString()); + }, [clearAllFilters, clearAllAppliedDisplayFilters, workspaceSlug]); + return ( <>
- {calculateTotalFilters(currentWorkspaceFilters ?? {}) !== 0 && ( + {(calculateTotalFilters(currentWorkspaceFilters ?? {}) !== 0 || + currentWorkspaceAppliedDisplayFilters?.length !== 0) && (
clearAllFilters(`${workspaceSlug}`)} + appliedDisplayFilters={currentWorkspaceAppliedDisplayFilters ?? []} + handleClearAllFilters={handleClearAllFilters} handleRemoveFilter={handleRemoveFilter} + handleRemoveDisplayFilter={handleRemoveDisplayFilter} filteredProjects={filteredProjectIds?.length ?? 0} - totalProjects={workspaceProjectIds?.length ?? 0} + totalProjects={totalProjectIds?.length ?? 0} alwaysAllowEditing />
diff --git a/web/services/project/index.ts b/web/services/project/index.ts index 18cf1200a..d131ceb6b 100644 --- a/web/services/project/index.ts +++ b/web/services/project/index.ts @@ -4,3 +4,4 @@ export * from "./project-export.service"; export * from "./project-member.service"; export * from "./project-state.service"; export * from "./project-publish.service"; +export * from "./project-archive.service"; diff --git a/web/services/project/project-archive.service.ts b/web/services/project/project-archive.service.ts new file mode 100644 index 000000000..5fdca54b6 --- /dev/null +++ b/web/services/project/project-archive.service.ts @@ -0,0 +1,31 @@ +// helpers +import { API_BASE_URL } from "@/helpers/common.helper"; +// services +import { APIService } from "@/services/api.service"; + +export class ProjectArchiveService extends APIService { + constructor() { + super(API_BASE_URL); + } + + async archiveProject( + workspaceSlug: string, + projectId: string + ): Promise<{ + archived_at: string; + }> { + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archive/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } + + async restoreProject(workspaceSlug: string, projectId: string): Promise { + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archive/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } +} diff --git a/web/store/project/project.store.ts b/web/store/project/project.store.ts index dfd35ac59..a12039ba6 100644 --- a/web/store/project/project.store.ts +++ b/web/store/project/project.store.ts @@ -3,12 +3,15 @@ import sortBy from "lodash/sortBy"; import { observable, action, computed, makeObservable, runInAction } from "mobx"; import { computedFn } from "mobx-utils"; // types -import { IssueLabelService, IssueService } from "@/services/issue"; -import { ProjectService, ProjectStateService } from "@/services/project"; import { IProject } from "@plane/types"; -import { RootStore } from "../root.store"; +// helpers import { orderProjects, shouldFilterProject } from "@/helpers/project.helper"; // services +import { IssueLabelService, IssueService } from "@/services/issue"; +import { ProjectService, ProjectStateService, ProjectArchiveService } from "@/services/project"; +// store +import { RootStore } from "../root.store"; + export interface IProjectStore { // observables projectMap: { @@ -17,6 +20,8 @@ export interface IProjectStore { // computed filteredProjectIds: string[] | undefined; workspaceProjectIds: string[] | undefined; + archivedProjectIds: string[] | undefined; + totalProjectIds: string[] | undefined; joinedProjectIds: string[]; favoriteProjectIds: string[]; currentProjectDetails: IProject | undefined; @@ -35,6 +40,9 @@ export interface IProjectStore { createProject: (workspaceSlug: string, data: Partial) => Promise; updateProject: (workspaceSlug: string, projectId: string, data: Partial) => Promise; deleteProject: (workspaceSlug: string, projectId: string) => Promise; + // archive actions + archiveProject: (workspaceSlug: string, projectId: string) => Promise; + restoreProject: (workspaceSlug: string, projectId: string) => Promise; } export class ProjectStore implements IProjectStore { @@ -46,6 +54,7 @@ export class ProjectStore implements IProjectStore { rootStore: RootStore; // service projectService; + projectArchiveService; issueLabelService; issueService; stateService; @@ -57,6 +66,8 @@ export class ProjectStore implements IProjectStore { // computed filteredProjectIds: computed, workspaceProjectIds: computed, + archivedProjectIds: computed, + totalProjectIds: computed, currentProjectDetails: computed, joinedProjectIds: computed, favoriteProjectIds: computed, @@ -76,6 +87,7 @@ export class ProjectStore implements IProjectStore { this.rootStore = _rootStore; // services this.projectService = new ProjectService(); + this.projectArchiveService = new ProjectArchiveService(); this.issueService = new IssueService(); this.issueLabelService = new IssueLabelService(); this.stateService = new ProjectStateService(); @@ -109,11 +121,42 @@ export class ProjectStore implements IProjectStore { get workspaceProjectIds() { const workspaceDetails = this.rootStore.workspaceRoot.currentWorkspace; if (!workspaceDetails) return; - const workspaceProjects = Object.values(this.projectMap).filter((p) => p.workspace === workspaceDetails.id); + const workspaceProjects = Object.values(this.projectMap).filter( + (p) => p.workspace === workspaceDetails.id && !p.archived_at + ); const projectIds = workspaceProjects.map((p) => p.id); return projectIds ?? null; } + /** + * Returns archived project IDs belong to current workspace. + */ + get archivedProjectIds() { + const currentWorkspace = this.rootStore.workspaceRoot.currentWorkspace; + if (!currentWorkspace) return; + + let projects = Object.values(this.projectMap ?? {}); + projects = sortBy(projects, "archived_at"); + + const projectIds = projects + .filter((project) => project.workspace === currentWorkspace.id && !!project.archived_at) + .map((project) => project.id); + return projectIds; + } + + /** + * Returns total project IDs belong to the current workspace + */ + // workspaceProjectIds + archivedProjectIds + get totalProjectIds() { + const currentWorkspace = this.rootStore.workspaceRoot.currentWorkspace; + if (!currentWorkspace) return; + + const workspaceProjects = this.workspaceProjectIds ?? []; + const archivedProjects = this.archivedProjectIds ?? []; + return [...workspaceProjects, ...archivedProjects]; + } + /** * Returns current project details */ @@ -133,7 +176,7 @@ export class ProjectStore implements IProjectStore { projects = sortBy(projects, "sort_order"); const projectIds = projects - .filter((project) => project.workspace === currentWorkspace.id && project.is_member) + .filter((project) => project.workspace === currentWorkspace.id && project.is_member && !project.archived_at) .map((project) => project.id); return projectIds; } @@ -149,7 +192,10 @@ export class ProjectStore implements IProjectStore { projects = sortBy(projects, "created_at"); const projectIds = projects - .filter((project) => project.workspace === currentWorkspace.id && project.is_member && project.is_favorite) + .filter( + (project) => + project.workspace === currentWorkspace.id && project.is_member && project.is_favorite && !project.archived_at + ) .map((project) => project.id); return projectIds; } @@ -348,4 +394,48 @@ export class ProjectStore implements IProjectStore { this.fetchProjects(workspaceSlug); } }; + + /** + * Archives a project from specific workspace and updates it in the store + * @param workspaceSlug + * @param projectId + * @returns Promise + */ + archiveProject = async (workspaceSlug: string, projectId: string) => { + await this.projectArchiveService + .archiveProject(workspaceSlug, projectId) + .then((response) => { + runInAction(() => { + set(this.projectMap, [projectId, "archived_at"], response.archived_at); + }); + }) + .catch((error) => { + console.log("Failed to archive project from project store"); + this.fetchProjects(workspaceSlug); + this.fetchProjectDetails(workspaceSlug, projectId); + throw error; + }); + }; + + /** + * Restores a project from specific workspace and updates it in the store + * @param workspaceSlug + * @param projectId + * @returns Promise + */ + restoreProject = async (workspaceSlug: string, projectId: string) => { + await this.projectArchiveService + .restoreProject(workspaceSlug, projectId) + .then(() => { + runInAction(() => { + set(this.projectMap, [projectId, "archived_at"], null); + }); + }) + .catch((error) => { + console.log("Failed to restore project from project store"); + this.fetchProjects(workspaceSlug); + this.fetchProjectDetails(workspaceSlug, projectId); + throw error; + }); + }; } diff --git a/web/store/project/project_filter.store.ts b/web/store/project/project_filter.store.ts index 7d6aff96f..94d5f7073 100644 --- a/web/store/project/project_filter.store.ts +++ b/web/store/project/project_filter.store.ts @@ -1,9 +1,10 @@ +import set from "lodash/set"; import { action, computed, observable, makeObservable, runInAction, reaction } from "mobx"; import { computedFn } from "mobx-utils"; -import set from "lodash/set"; // types +import { TProjectDisplayFilters, TProjectFilters, TProjectAppliedDisplayFilterKeys } from "@plane/types"; +// store import { RootStore } from "@/store/root.store"; -import { TProjectDisplayFilters, TProjectFilters } from "@plane/types"; export interface IProjectFilterStore { // observables @@ -12,6 +13,7 @@ export interface IProjectFilterStore { searchQuery: string; // computed currentWorkspaceDisplayFilters: TProjectDisplayFilters | undefined; + currentWorkspaceAppliedDisplayFilters: TProjectAppliedDisplayFilterKeys[] | undefined; currentWorkspaceFilters: TProjectFilters | undefined; // computed functions getDisplayFiltersByWorkspaceSlug: (workspaceSlug: string) => TProjectDisplayFilters | undefined; @@ -21,6 +23,7 @@ export interface IProjectFilterStore { updateFilters: (workspaceSlug: string, filters: TProjectFilters) => void; updateSearchQuery: (query: string) => void; clearAllFilters: (workspaceSlug: string) => void; + clearAllAppliedDisplayFilters: (workspaceSlug: string) => void; } export class ProjectFilterStore implements IProjectFilterStore { @@ -39,12 +42,14 @@ export class ProjectFilterStore implements IProjectFilterStore { searchQuery: observable.ref, // computed currentWorkspaceDisplayFilters: computed, + currentWorkspaceAppliedDisplayFilters: computed, currentWorkspaceFilters: computed, // actions updateDisplayFilters: action, updateFilters: action, updateSearchQuery: action, clearAllFilters: action, + clearAllAppliedDisplayFilters: action, }); // root store this.rootStore = _rootStore; @@ -67,6 +72,21 @@ export class ProjectFilterStore implements IProjectFilterStore { return this.displayFilters[workspaceSlug]; } + /** + * @description get project state applied display filter of the current workspace + * @returns {TProjectAppliedDisplayFilterKeys[] | undefined} // An array of keys of applied display filters + */ + // TODO: Figure out a better approach for this + get currentWorkspaceAppliedDisplayFilters() { + const workspaceSlug = this.rootStore.app.router.workspaceSlug; + if (!workspaceSlug) return; + const displayFilters = this.displayFilters[workspaceSlug]; + return Object.keys(displayFilters).filter( + (key): key is TProjectAppliedDisplayFilterKeys => + ["my_projects", "archived_projects"].includes(key) && !!displayFilters[key as keyof TProjectDisplayFilters] + ); + } + /** * @description get filters of the current workspace */ @@ -143,4 +163,17 @@ export class ProjectFilterStore implements IProjectFilterStore { this.filters[workspaceSlug] = {}; }); }; + + /** + * @description clear project display filters of a workspace + * @param {string} workspaceSlug + */ + clearAllAppliedDisplayFilters = (workspaceSlug: string) => { + runInAction(() => { + if (!this.currentWorkspaceAppliedDisplayFilters) return; + this.currentWorkspaceAppliedDisplayFilters.forEach((key) => { + set(this.displayFilters, [workspaceSlug, key], false); + }); + }); + }; } From 165bec9aa40be2c23af4665b5edd4cfaecf36ada Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Thu, 21 Mar 2024 21:06:55 +0530 Subject: [PATCH 11/53] fix: handled the empty issue propety, create more in edit modal, and moving drafts from issue functionality (#4030) --- .../issues/issue-modal/draft-issue-layout.tsx | 25 +++++++++++--- web/components/issues/issue-modal/form.tsx | 33 ++++++++++++------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/web/components/issues/issue-modal/draft-issue-layout.tsx b/web/components/issues/issue-modal/draft-issue-layout.tsx index 55f8d711f..78a97675e 100644 --- a/web/components/issues/issue-modal/draft-issue-layout.tsx +++ b/web/components/issues/issue-modal/draft-issue-layout.tsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; import type { TIssue } from "@plane/types"; @@ -6,12 +7,10 @@ import type { TIssue } from "@plane/types"; import { TOAST_TYPE, setToast } from "@plane/ui"; import { ConfirmIssueDiscard } from "@/components/issues"; import { IssueFormRoot } from "@/components/issues/issue-modal/form"; +import { isEmptyHtmlString } from "@/helpers/string.helper"; import { useEventTracker } from "@/hooks/store"; // services import { IssueDraftService } from "@/services/issue"; -// ui -// components -// types export interface DraftIssueProps { changesMade: Partial | null; @@ -50,8 +49,24 @@ export const DraftIssueLayout: React.FC = observer((props) => { const { captureIssueEvent } = useEventTracker(); const handleClose = () => { - if (changesMade) setIssueDiscardModal(true); - else onClose(false); + if (changesMade) { + Object.entries(changesMade).forEach(([key, value]) => { + const issueKey = key as keyof TIssue; + if (value === null || value === undefined || value === "") delete changesMade[issueKey]; + if (typeof value === "object" && !value) delete changesMade[issueKey]; + if (Array.isArray(value) && value.length === 0) delete changesMade[issueKey]; + if (issueKey === "project_id") delete changesMade.project_id; + if (issueKey === "priority" && value && value === "none") delete changesMade.priority; + if ( + issueKey === "description_html" && + changesMade.description_html && + isEmptyHtmlString(changesMade.description_html) + ) + delete changesMade.description_html; + }); + if (isEmpty(changesMade)) onClose(false); + else setIssueDiscardModal(true); + } }; const handleCreateDraftIssue = async () => { diff --git a/web/components/issues/issue-modal/form.tsx b/web/components/issues/issue-modal/form.tsx index b6c773335..dcc1a3b7d 100644 --- a/web/components/issues/issue-modal/form.tsx +++ b/web/components/issues/issue-modal/form.tsx @@ -178,6 +178,10 @@ export const IssueFormRoot: FC = observer((props) => { id: data.id, description_html: formData.description_html ?? "

", }; + + // this condition helps to move the issues from draft to project issues + if (formData.hasOwnProperty("is_draft")) submitData.is_draft = formData.is_draft; + await onSubmit(submitData, is_draft_issue); setGptAssistantModal(false); @@ -716,19 +720,24 @@ export const IssueFormRoot: FC = observer((props) => {
-
onCreateMoreToggleChange(!isCreateMoreToggleEnabled)} - onKeyDown={(e) => { - if (e.key === "Enter") onCreateMoreToggleChange(!isCreateMoreToggleEnabled); - }} - tabIndex={getTabIndex("create_more")} - > -
- {}} size="sm" /> -
- Create more +
+ {!data?.id && ( +
onCreateMoreToggleChange(!isCreateMoreToggleEnabled)} + onKeyDown={(e) => { + if (e.key === "Enter") onCreateMoreToggleChange(!isCreateMoreToggleEnabled); + }} + tabIndex={getTabIndex("create_more")} + > +
+ {}} size="sm" /> +
+ Create more +
+ )}
+
-
+
{currentCycle && (
= observer((props) => {
-
+
{renderDate && ( From baab6ce99fc02068b72942d8342c994004e6c48c Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:26:44 +0530 Subject: [PATCH 13/53] fix: project order by dropdown (#4037) --- web/components/project/dropdowns/order-by.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/components/project/dropdowns/order-by.tsx b/web/components/project/dropdowns/order-by.tsx index 1d262f8ac..048513d08 100644 --- a/web/components/project/dropdowns/order-by.tsx +++ b/web/components/project/dropdowns/order-by.tsx @@ -40,7 +40,8 @@ export const ProjectOrderByDropdown: React.FC = (props) => { key={option.key} className="flex items-center justify-between gap-2" onClick={() => { - if (isDescending) onChange(`-${option.key}` as TProjectOrderByOptions); + if (isDescending) + onChange(option.key == "sort_order" ? option.key : (`-${option.key}` as TProjectOrderByOptions)); else onChange(option.key); }} > From 60aea627392c46371c0ffde7181399a4755a3fcd Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Fri, 22 Mar 2024 18:28:44 +0530 Subject: [PATCH 14/53] fix: handled inital empty state close in the issue create/edit odal (#4033) --- .../issues/issue-modal/draft-issue-layout.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/web/components/issues/issue-modal/draft-issue-layout.tsx b/web/components/issues/issue-modal/draft-issue-layout.tsx index 78a97675e..240968faa 100644 --- a/web/components/issues/issue-modal/draft-issue-layout.tsx +++ b/web/components/issues/issue-modal/draft-issue-layout.tsx @@ -53,7 +53,7 @@ export const DraftIssueLayout: React.FC = observer((props) => { Object.entries(changesMade).forEach(([key, value]) => { const issueKey = key as keyof TIssue; if (value === null || value === undefined || value === "") delete changesMade[issueKey]; - if (typeof value === "object" && !value) delete changesMade[issueKey]; + if (typeof value === "object" && isEmpty(value)) delete changesMade[issueKey]; if (Array.isArray(value) && value.length === 0) delete changesMade[issueKey]; if (issueKey === "project_id") delete changesMade.project_id; if (issueKey === "priority" && value && value === "none") delete changesMade.priority; @@ -64,8 +64,13 @@ export const DraftIssueLayout: React.FC = observer((props) => { ) delete changesMade.description_html; }); - if (isEmpty(changesMade)) onClose(false); - else setIssueDiscardModal(true); + if (isEmpty(changesMade)) { + onClose(false); + setIssueDiscardModal(false); + } else setIssueDiscardModal(true); + } else { + onClose(false); + setIssueDiscardModal(false); } }; From d262eb4ffb7ba22504d9d65dbc2a8dd8fbd8cc5c Mon Sep 17 00:00:00 2001 From: Lakhan Baheti <94619783+1akhanBaheti@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:30:23 +0530 Subject: [PATCH 15/53] [WEB-800] fix: issue peekview, and detail page create label colour selector autoplacement (#4032) * fix: issue peekview, and detail label colour selector autoplacement * fix: build errors --- .../issue-detail/label/create-label.tsx | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/web/components/issues/issue-detail/label/create-label.tsx b/web/components/issues/issue-detail/label/create-label.tsx index 160ff0071..de376ce79 100644 --- a/web/components/issues/issue-detail/label/create-label.tsx +++ b/web/components/issues/issue-detail/label/create-label.tsx @@ -1,14 +1,13 @@ import { FC, useState, Fragment, useEffect } from "react"; import { TwitterPicker } from "react-color"; import { Controller, useForm } from "react-hook-form"; +import { usePopper } from "react-popper"; import { Plus, X, Loader } from "lucide-react"; -import { Popover, Transition } from "@headlessui/react"; +import { Popover } from "@headlessui/react"; import { IIssueLabel } from "@plane/types"; // hooks import { Input, TOAST_TYPE, setToast } from "@plane/ui"; import { useIssueDetail } from "@/hooks/store"; -// helpers -import { cn } from "helpers/common.helper"; // ui // types import { TLabelOperations } from "./root"; @@ -31,11 +30,12 @@ export const LabelCreate: FC = (props) => { // hooks const { issue: { getIssueById }, - peekIssue, } = useIssueDetail(); // state const [isCreateToggle, setIsCreateToggle] = useState(false); const handleIsCreateToggle = () => setIsCreateToggle(!isCreateToggle); + const [referenceElement, setReferenceElement] = useState(null); + const [popperElement, setPopperElement] = useState(null); // react hook form const { handleSubmit, @@ -47,6 +47,18 @@ export const LabelCreate: FC = (props) => { defaultValues, }); + const { styles, attributes } = usePopper(referenceElement, popperElement, { + placement: "bottom-start", + modifiers: [ + { + name: "preventOverflow", + options: { + padding: 12, + }, + }, + ], + }); + useEffect(() => { if (!isCreateToggle) return; @@ -93,36 +105,28 @@ export const LabelCreate: FC = (props) => { render={({ field: { value, onChange } }) => ( <> - - {value && value?.trim() !== "" && ( - - )} + + - - - +
- onChange(value.hex)} - /> - - + onChange(value.hex)} /> +
+
)} From db8cf1fb24c0e51f214cdf4023a4e766fded3fdc Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Fri, 22 Mar 2024 18:35:06 +0530 Subject: [PATCH 16/53] fix: handled quick actions in the project draft issues (#4034) --- .../kanban/roots/draft-issue-root.tsx | 4 +- .../list/roots/draft-issue-root.tsx | 4 +- .../quick-action-dropdowns/draft-issue.tsx | 121 ++++++++++++++++++ .../quick-action-dropdowns/index.ts | 1 + 4 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 web/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx diff --git a/web/components/issues/issue-layouts/kanban/roots/draft-issue-root.tsx b/web/components/issues/issue-layouts/kanban/roots/draft-issue-root.tsx index 6ff958a72..4bd840b5e 100644 --- a/web/components/issues/issue-layouts/kanban/roots/draft-issue-root.tsx +++ b/web/components/issues/issue-layouts/kanban/roots/draft-issue-root.tsx @@ -1,11 +1,11 @@ import { observer } from "mobx-react-lite"; // components -import { ProjectIssueQuickActions } from "@/components/issues"; +import { DraftIssueQuickActions } from "@/components/issues"; import { EIssuesStoreType } from "@/constants/issue"; import { BaseKanBanRoot } from "../base-kanban-root"; export interface IKanBanLayout {} export const DraftKanBanLayout: React.FC = observer(() => ( - + )); diff --git a/web/components/issues/issue-layouts/list/roots/draft-issue-root.tsx b/web/components/issues/issue-layouts/list/roots/draft-issue-root.tsx index 4f303ffd4..9911b8ed4 100644 --- a/web/components/issues/issue-layouts/list/roots/draft-issue-root.tsx +++ b/web/components/issues/issue-layouts/list/roots/draft-issue-root.tsx @@ -2,7 +2,7 @@ import { FC } from "react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; // hooks -import { ProjectIssueQuickActions } from "@/components/issues"; +import { DraftIssueQuickActions } from "@/components/issues"; import { EIssuesStoreType } from "@/constants/issue"; // components // types @@ -15,5 +15,5 @@ export const DraftIssueListLayout: FC = observer(() => { if (!workspaceSlug || !projectId) return null; - return ; + return ; }); diff --git a/web/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx b/web/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx new file mode 100644 index 000000000..b773e7031 --- /dev/null +++ b/web/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx @@ -0,0 +1,121 @@ +import { useState } from "react"; +import omit from "lodash/omit"; +import { observer } from "mobx-react"; +// hooks +import { Copy, Pencil, Trash2 } from "lucide-react"; +import { TIssue } from "@plane/types"; +import { CustomMenu } from "@plane/ui"; +import { CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; +import { EIssuesStoreType } from "@/constants/issue"; +import { EUserProjectRoles } from "@/constants/project"; +import { useEventTracker, useIssues, useUser } from "@/hooks/store"; +// ui +// components +// helpers +// types +import { IQuickActionProps } from "../list/list-view-types"; +// constant + +export const DraftIssueQuickActions: React.FC = observer((props) => { + const { issue, handleDelete, handleUpdate, customActionButton, portalElement, readOnly = false } = props; + // states + const [createUpdateIssueModal, setCreateUpdateIssueModal] = useState(false); + const [issueToEdit, setIssueToEdit] = useState(undefined); + const [deleteIssueModal, setDeleteIssueModal] = useState(false); + // store hooks + const { + membership: { currentProjectRole }, + } = useUser(); + const { setTrackElement } = useEventTracker(); + const { issuesFilter } = useIssues(EIssuesStoreType.PROJECT); + // derived values + const activeLayout = `${issuesFilter.issueFilters?.displayFilters?.layout} layout`; + // auth + const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER && !readOnly; + const isDeletingAllowed = isEditingAllowed; + + const duplicateIssuePayload = omit( + { + ...issue, + name: `${issue.name} (copy)`, + is_draft: true, + }, + ["id"] + ); + + return ( + <> + setDeleteIssueModal(false)} + onSubmit={handleDelete} + /> + + { + setCreateUpdateIssueModal(false); + setIssueToEdit(undefined); + }} + data={issueToEdit ?? duplicateIssuePayload} + onSubmit={async (data) => { + if (issueToEdit && handleUpdate) await handleUpdate(data); + }} + storeType={EIssuesStoreType.PROJECT} + isDraft + /> + + + {isEditingAllowed && ( + { + setTrackElement(activeLayout); + setIssueToEdit(issue); + setCreateUpdateIssueModal(true); + }} + > +
+ + Edit +
+
+ )} + {isEditingAllowed && ( + { + setTrackElement(activeLayout); + setCreateUpdateIssueModal(true); + }} + > +
+ + Make a copy +
+
+ )} + {isDeletingAllowed && ( + { + setTrackElement(activeLayout); + setDeleteIssueModal(true); + }} + > +
+ + Delete +
+
+ )} +
+ + ); +}); diff --git a/web/components/issues/issue-layouts/quick-action-dropdowns/index.ts b/web/components/issues/issue-layouts/quick-action-dropdowns/index.ts index e38440017..212a43f91 100644 --- a/web/components/issues/issue-layouts/quick-action-dropdowns/index.ts +++ b/web/components/issues/issue-layouts/quick-action-dropdowns/index.ts @@ -2,4 +2,5 @@ export * from "./cycle-issue"; export * from "./module-issue"; export * from "./project-issue"; export * from "./archived-issue"; +export * from "./draft-issue"; export * from "./all-issue"; From 72392d573178ec28a1ad4d9bd65d6a99303dc1b6 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Fri, 22 Mar 2024 18:35:40 +0530 Subject: [PATCH 17/53] fix: resetting the changesMage when the createmore toggle is turned on in issue create-edit modal (#4039) --- web/components/issues/issue-modal/modal.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/components/issues/issue-modal/modal.tsx b/web/components/issues/issue-modal/modal.tsx index 609392d4f..29633918f 100644 --- a/web/components/issues/issue-modal/modal.tsx +++ b/web/components/issues/issue-modal/modal.tsx @@ -171,7 +171,10 @@ export const CreateUpdateIssueModal: React.FC = observer((prop path: router.asPath, }); !createMore && handleClose(); - if (createMore) issueTitleRef && issueTitleRef?.current?.focus(); + if (createMore) { + issueTitleRef && issueTitleRef?.current?.focus(); + setChangesMade(null); + } return response; } catch (error) { setToast({ From cdf86391f00759944b9af53db425d5789f06ce59 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:36:09 +0530 Subject: [PATCH 18/53] fix: module filter and order by (#4040) --- web/components/modules/modules-list-view.tsx | 2 +- web/helpers/module.helper.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/components/modules/modules-list-view.tsx b/web/components/modules/modules-list-view.tsx index ce8ce4e65..b0ff67609 100644 --- a/web/components/modules/modules-list-view.tsx +++ b/web/components/modules/modules-list-view.tsx @@ -38,7 +38,7 @@ export const ModulesListView: React.FC = observer(() => { ); - if (totalFilters > 0 || searchQuery.trim() !== "") + if (totalFilters > 0 && filteredModuleIds.length === 0) return (
diff --git a/web/helpers/module.helper.ts b/web/helpers/module.helper.ts index 1a01915f2..f5cbfe08a 100644 --- a/web/helpers/module.helper.ts +++ b/web/helpers/module.helper.ts @@ -22,7 +22,7 @@ export const orderModules = (modules: IModule[], orderByKey: TModuleOrderByOptio (m) => { let progress = (m.completed_issues + m.cancelled_issues) / m.total_issues; if (isNaN(progress)) progress = 0; - return orderByKey === "progress" ? progress : !progress; + return orderByKey === "progress" ? progress : -progress; }, "name", ]); From 53f3357149d26160408bb403c0206a87b69cd5f1 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:36:34 +0530 Subject: [PATCH 19/53] chore: cycle list page alignment (#4041) --- web/components/cycles/list/root.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/cycles/list/root.tsx b/web/components/cycles/list/root.tsx index ef05228ee..0239f1d78 100644 --- a/web/components/cycles/list/root.tsx +++ b/web/components/cycles/list/root.tsx @@ -29,7 +29,7 @@ export const CyclesList: FC = observer((props) => { isArchived={isArchived} /> {completedCycleIds.length !== 0 && ( - + {({ open }) => ( <> From 1caceca1e7d146be7134cfd17ede302f58a8e599 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:37:11 +0530 Subject: [PATCH 20/53] [WEB-818] fix: sub-issue and attachment delete not working in the peek overview (#4042) * fix: delete attachment not working in the peek overview * fix: sub-issue delete not working * fix: lint errors --- .../issues/attachment/attachment-detail.tsx | 30 +++++++++---------- .../issues/peek-overview/header.tsx | 4 +-- web/components/issues/peek-overview/view.tsx | 16 +++------- .../issues/sub-issues/issue-list-item.tsx | 2 +- web/components/issues/sub-issues/root.tsx | 2 +- web/store/issue/issue-details/root.store.ts | 25 ++++++++++------ 6 files changed, 38 insertions(+), 41 deletions(-) diff --git a/web/components/issues/attachment/attachment-detail.tsx b/web/components/issues/attachment/attachment-detail.tsx index b96ab7b18..8a1ade183 100644 --- a/web/components/issues/attachment/attachment-detail.tsx +++ b/web/components/issues/attachment/attachment-detail.tsx @@ -1,18 +1,19 @@ -import { FC, useState } from "react"; +import { FC } from "react"; +import { observer } from "mobx-react"; import Link from "next/link"; import { AlertCircle, X } from "lucide-react"; -// hooks -// ui import { Tooltip } from "@plane/ui"; -// components -// icons import { getFileIcon } from "@/components/icons"; -// helper import { convertBytesToSize, getFileExtension, getFileName } from "@/helpers/attachment.helper"; import { renderFormattedDate } from "@/helpers/date-time.helper"; import { truncateText } from "@/helpers/string.helper"; import { useIssueDetail, useMember } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; +// hooks +// ui +// components +// icons +// helper import { IssueAttachmentDeleteModal } from "./delete-attachment-confirmation-modal"; // types import { TAttachmentOperations } from "./root"; @@ -25,16 +26,17 @@ type TIssueAttachmentsDetail = { disabled?: boolean; }; -export const IssueAttachmentsDetail: FC = (props) => { +export const IssueAttachmentsDetail: FC = observer((props) => { // props const { attachmentId, handleAttachmentOperations, disabled } = props; // store hooks const { getUserDetails } = useMember(); const { attachment: { getAttachmentById }, + isDeleteAttachmentModalOpen, + toggleDeleteAttachmentModal, } = useIssueDetail(); // states - const [attachmentDeleteModal, setAttachmentDeleteModal] = useState(false); const { isMobile } = usePlatformOS(); const attachment = attachmentId && getAttachmentById(attachmentId); @@ -42,8 +44,8 @@ export const IssueAttachmentsDetail: FC = (props) => { return ( <> toggleDeleteAttachmentModal(false)} handleAttachmentOperations={handleAttachmentOperations} data={attachment} /> @@ -81,15 +83,11 @@ export const IssueAttachmentsDetail: FC = (props) => { {!disabled && ( - )}
); -}; +}); diff --git a/web/components/issues/peek-overview/header.tsx b/web/components/issues/peek-overview/header.tsx index ba1b0f5b6..70c57c3f3 100644 --- a/web/components/issues/peek-overview/header.tsx +++ b/web/components/issues/peek-overview/header.tsx @@ -53,7 +53,7 @@ export type PeekOverviewHeaderProps = { issueId: string; isArchived: boolean; disabled: boolean; - toggleDeleteIssueModal: (value: boolean) => void; + toggleDeleteIssueModal: (issueId: string | null) => void; toggleArchiveIssueModal: (value: boolean) => void; handleRestoreIssue: () => void; isSubmitting: "submitting" | "submitted" | "saved"; @@ -188,7 +188,7 @@ export const IssuePeekOverviewHeader: FC = observer((pr )} {!disabled && ( - diff --git a/web/components/issues/peek-overview/view.tsx b/web/components/issues/peek-overview/view.tsx index 493b8bd51..3723627a9 100644 --- a/web/components/issues/peek-overview/view.tsx +++ b/web/components/issues/peek-overview/view.tsx @@ -91,26 +91,18 @@ export const IssueView: FC = observer((props) => { /> )} - {issue && !is_archived && ( + {issue && isDeleteIssueModalOpen === issue.id && ( { - toggleDeleteIssueModal(false); + toggleDeleteIssueModal(null); + removeRoutePeekId(); }} data={issue} onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId)} /> )} - {issue && is_archived && ( - toggleDeleteIssueModal(false)} - onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId)} - /> - )} -
{issueId && (
= observer((props) => { { handleIssueCrudState("delete", parentIssueId, issue); - toggleDeleteIssueModal(true); + toggleDeleteIssueModal(issue.id); }} >
diff --git a/web/components/issues/sub-issues/root.tsx b/web/components/issues/sub-issues/root.tsx index b9c40f6e2..25cbc2b17 100644 --- a/web/components/issues/sub-issues/root.tsx +++ b/web/components/issues/sub-issues/root.tsx @@ -523,7 +523,7 @@ export const SubIssuesRoot: FC = observer((props) => { isOpen={issueCrudState?.delete?.toggle} handleClose={() => { handleIssueCrudState("delete", null, null); - toggleDeleteIssueModal(false); + toggleDeleteIssueModal(null); }} data={issueCrudState?.delete?.issue as TIssue} onSubmit={async () => diff --git a/web/store/issue/issue-details/root.store.ts b/web/store/issue/issue-details/root.store.ts index c58e1af42..a9672655b 100644 --- a/web/store/issue/issue-details/root.store.ts +++ b/web/store/issue/issue-details/root.store.ts @@ -47,10 +47,11 @@ export interface IIssueDetail isCreateIssueModalOpen: boolean; isIssueLinkModalOpen: boolean; isParentIssueModalOpen: boolean; - isDeleteIssueModalOpen: boolean; + isDeleteIssueModalOpen: string | null; isArchiveIssueModalOpen: boolean; isRelationModalOpen: TIssueRelationTypes | null; isSubIssuesModalOpen: boolean; + isDeleteAttachmentModalOpen: boolean; // computed isAnyModalOpen: boolean; // actions @@ -58,10 +59,11 @@ export interface IIssueDetail toggleCreateIssueModal: (value: boolean) => void; toggleIssueLinkModal: (value: boolean) => void; toggleParentIssueModal: (value: boolean) => void; - toggleDeleteIssueModal: (value: boolean) => void; + toggleDeleteIssueModal: (issueId: string | null) => void; toggleArchiveIssueModal: (value: boolean) => void; - toggleRelationModal: (value: TIssueRelationTypes | null) => void; + toggleRelationModal: (relationType: TIssueRelationTypes | null) => void; toggleSubIssuesModal: (value: boolean) => void; + toggleDeleteAttachmentModal: (value: boolean) => void; // store rootIssueStore: IIssueRootStore; issue: IIssueStore; @@ -82,10 +84,11 @@ export class IssueDetail implements IIssueDetail { isCreateIssueModalOpen: boolean = false; isIssueLinkModalOpen: boolean = false; isParentIssueModalOpen: boolean = false; - isDeleteIssueModalOpen: boolean = false; + isDeleteIssueModalOpen: string | null = null; isArchiveIssueModalOpen: boolean = false; isRelationModalOpen: TIssueRelationTypes | null = null; isSubIssuesModalOpen: boolean = false; + isDeleteAttachmentModalOpen: boolean = false; // store rootIssueStore: IIssueRootStore; issue: IIssueStore; @@ -110,6 +113,7 @@ export class IssueDetail implements IIssueDetail { isArchiveIssueModalOpen: observable.ref, isRelationModalOpen: observable.ref, isSubIssuesModalOpen: observable.ref, + isDeleteAttachmentModalOpen: observable.ref, // computed isAnyModalOpen: computed, // action @@ -121,6 +125,7 @@ export class IssueDetail implements IIssueDetail { toggleArchiveIssueModal: action, toggleRelationModal: action, toggleSubIssuesModal: action, + toggleDeleteAttachmentModal: action, }); // store @@ -143,10 +148,11 @@ export class IssueDetail implements IIssueDetail { this.isCreateIssueModalOpen || this.isIssueLinkModalOpen || this.isParentIssueModalOpen || - this.isDeleteIssueModalOpen || + !!this.isDeleteIssueModalOpen || this.isArchiveIssueModalOpen || - Boolean(this.isRelationModalOpen) || - this.isSubIssuesModalOpen + !!this.isRelationModalOpen || + this.isSubIssuesModalOpen || + this.isDeleteAttachmentModalOpen ); } @@ -155,10 +161,11 @@ export class IssueDetail implements IIssueDetail { toggleCreateIssueModal = (value: boolean) => (this.isCreateIssueModalOpen = value); toggleIssueLinkModal = (value: boolean) => (this.isIssueLinkModalOpen = value); toggleParentIssueModal = (value: boolean) => (this.isParentIssueModalOpen = value); - toggleDeleteIssueModal = (value: boolean) => (this.isDeleteIssueModalOpen = value); + toggleDeleteIssueModal = (issueId: string | null) => (this.isDeleteIssueModalOpen = issueId); toggleArchiveIssueModal = (value: boolean) => (this.isArchiveIssueModalOpen = value); - toggleRelationModal = (value: TIssueRelationTypes | null) => (this.isRelationModalOpen = value); + toggleRelationModal = (relationType: TIssueRelationTypes | null) => (this.isRelationModalOpen = relationType); toggleSubIssuesModal = (value: boolean) => (this.isSubIssuesModalOpen = value); + toggleDeleteAttachmentModal = (value: boolean) => (this.isDeleteAttachmentModalOpen = value); // issue fetchIssue = async ( From 5c7886d7f3e98261072aa75c1eede2507decf663 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:38:39 +0530 Subject: [PATCH 21/53] [WEB-811] chore: filter dropdown custom date select improvement (#4043) * fix: handled custom start_date and target_date custom filter in project-issues * chore: filter dropdown improvement --------- Co-authored-by: gurusainath --- web/components/headers/cycle-issues.tsx | 6 +++++- web/components/headers/global-issues.tsx | 2 ++ web/components/headers/module-issues.tsx | 6 +++++- web/components/headers/project-draft-issues.tsx | 2 ++ web/components/headers/project-issues.tsx | 2 ++ web/components/headers/project-view-issues.tsx | 2 ++ .../filters/header/filters/start-date.tsx | 13 ++++++++++++- .../filters/header/filters/target-date.tsx | 13 ++++++++++++- web/components/issues/issues-mobile-header.tsx | 2 ++ web/components/modules/module-mobile-header.tsx | 2 ++ web/components/profile/profile-issues-filter.tsx | 2 ++ 11 files changed, 48 insertions(+), 4 deletions(-) diff --git a/web/components/headers/cycle-issues.tsx b/web/components/headers/cycle-issues.tsx index 4c66aabc7..35a646c1c 100644 --- a/web/components/headers/cycle-issues.tsx +++ b/web/components/headers/cycle-issues.tsx @@ -109,8 +109,10 @@ export const CycleIssuesHeader: React.FC = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); @@ -224,7 +226,9 @@ export const CycleIssuesHeader: React.FC = observer(() => { className="ml-1.5 flex-shrink-0 truncate" placement="bottom-start" > - {currentProjectCycleIds?.map((cycleId) => )} + {currentProjectCycleIds?.map((cycleId) => ( + + ))} } /> diff --git a/web/components/headers/global-issues.tsx b/web/components/headers/global-issues.tsx index 3fe24804b..2d58d9b16 100644 --- a/web/components/headers/global-issues.tsx +++ b/web/components/headers/global-issues.tsx @@ -56,8 +56,10 @@ export const GlobalIssuesHeader: React.FC = observer((props) => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/headers/module-issues.tsx b/web/components/headers/module-issues.tsx index 7cbaf1efc..59cc2a429 100644 --- a/web/components/headers/module-issues.tsx +++ b/web/components/headers/module-issues.tsx @@ -110,8 +110,10 @@ export const ModuleIssuesHeader: React.FC = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); @@ -225,7 +227,9 @@ export const ModuleIssuesHeader: React.FC = observer(() => { className="ml-1.5 flex-shrink-0" placement="bottom-start" > - {projectModuleIds?.map((moduleId) => )} + {projectModuleIds?.map((moduleId) => ( + + ))} } /> diff --git a/web/components/headers/project-draft-issues.tsx b/web/components/headers/project-draft-issues.tsx index ab79b3b1f..bdfaebc8d 100644 --- a/web/components/headers/project-draft-issues.tsx +++ b/web/components/headers/project-draft-issues.tsx @@ -38,8 +38,10 @@ export const ProjectDraftIssueHeader: FC = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/headers/project-issues.tsx b/web/components/headers/project-issues.tsx index b3dd77826..7c018d5c2 100644 --- a/web/components/headers/project-issues.tsx +++ b/web/components/headers/project-issues.tsx @@ -60,8 +60,10 @@ export const ProjectIssuesHeader: React.FC = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/headers/project-view-issues.tsx b/web/components/headers/project-view-issues.tsx index deab59796..6f545f25b 100644 --- a/web/components/headers/project-view-issues.tsx +++ b/web/components/headers/project-view-issues.tsx @@ -74,8 +74,10 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/issues/issue-layouts/filters/header/filters/start-date.tsx b/web/components/issues/issue-layouts/filters/header/filters/start-date.tsx index 2b55ada35..b1c68aaed 100644 --- a/web/components/issues/issue-layouts/filters/header/filters/start-date.tsx +++ b/web/components/issues/issue-layouts/filters/header/filters/start-date.tsx @@ -25,6 +25,17 @@ export const FilterStartDate: React.FC = observer((props) => { d.name.toLowerCase().includes(searchQuery.toLowerCase()) ); + const isCustomDateSelected = () => { + const isCustomFateApplied = appliedFilters?.filter((f) => f.includes("-")) || []; + return isCustomFateApplied.length > 0 ? true : false; + }; + const handleCustomDate = () => { + if (isCustomDateSelected()) { + const updateAppliedFilters = appliedFilters?.filter((f) => f.includes("-")) || []; + handleUpdate(updateAppliedFilters); + } else setIsDateFilterModalOpen(true); + }; + return ( <> {isDateFilterModalOpen && ( @@ -53,7 +64,7 @@ export const FilterStartDate: React.FC = observer((props) => { multiple /> ))} - setIsDateFilterModalOpen(true)} title="Custom" multiple /> + ) : (

No matches found

diff --git a/web/components/issues/issue-layouts/filters/header/filters/target-date.tsx b/web/components/issues/issue-layouts/filters/header/filters/target-date.tsx index e46e52a41..f696e66cf 100644 --- a/web/components/issues/issue-layouts/filters/header/filters/target-date.tsx +++ b/web/components/issues/issue-layouts/filters/header/filters/target-date.tsx @@ -25,6 +25,17 @@ export const FilterTargetDate: React.FC = observer((props) => { d.name.toLowerCase().includes(searchQuery.toLowerCase()) ); + const isCustomDateSelected = () => { + const isCustomFateApplied = appliedFilters?.filter((f) => f.includes("-")) || []; + return isCustomFateApplied.length > 0 ? true : false; + }; + const handleCustomDate = () => { + if (isCustomDateSelected()) { + const updateAppliedFilters = appliedFilters?.filter((f) => f.includes("-")) || []; + handleUpdate(updateAppliedFilters); + } else setIsDateFilterModalOpen(true); + }; + return ( <> {isDateFilterModalOpen && ( @@ -53,7 +64,7 @@ export const FilterTargetDate: React.FC = observer((props) => { multiple /> ))} - setIsDateFilterModalOpen(true)} title="Custom" multiple /> + ) : (

No matches found

diff --git a/web/components/issues/issues-mobile-header.tsx b/web/components/issues/issues-mobile-header.tsx index 0293380ce..4bc90b686 100644 --- a/web/components/issues/issues-mobile-header.tsx +++ b/web/components/issues/issues-mobile-header.tsx @@ -52,8 +52,10 @@ export const IssuesMobileHeader = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/modules/module-mobile-header.tsx b/web/components/modules/module-mobile-header.tsx index 8e632dac8..6419b13b0 100644 --- a/web/components/modules/module-mobile-header.tsx +++ b/web/components/modules/module-mobile-header.tsx @@ -54,8 +54,10 @@ export const ModuleMobileHeader = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); diff --git a/web/components/profile/profile-issues-filter.tsx b/web/components/profile/profile-issues-filter.tsx index fe2c004ba..1a7d8cfb0 100644 --- a/web/components/profile/profile-issues-filter.tsx +++ b/web/components/profile/profile-issues-filter.tsx @@ -44,8 +44,10 @@ export const ProfileIssuesFilter = observer(() => { const newValues = issueFilters?.filters?.[key] ?? []; if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom value.forEach((val) => { if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); }); } else { if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); From 95d2b6f1c147395fd96603770483a9c769fe3f2f Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Fri, 22 Mar 2024 18:39:06 +0530 Subject: [PATCH 22/53] style: hide cycle and module dropdown placeholder from list and kanban view. (#4044) --- web/components/dropdowns/cycle/index.tsx | 4 ++-- web/components/dropdowns/module/index.tsx | 20 +++++++++++--------- web/components/issues/issue-modal/form.tsx | 2 ++ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/web/components/dropdowns/cycle/index.tsx b/web/components/dropdowns/cycle/index.tsx index d59cb8b83..ce721e0a1 100644 --- a/web/components/dropdowns/cycle/index.tsx +++ b/web/components/dropdowns/cycle/index.tsx @@ -41,7 +41,7 @@ export const CycleDropdown: React.FC = observer((props) => { hideIcon = false, onChange, onClose, - placeholder = "Cycle", + placeholder = "", placement, projectId, showTooltip = false, @@ -132,7 +132,7 @@ export const CycleDropdown: React.FC = observer((props) => { variant={buttonVariant} > {!hideIcon && } - {BUTTON_VARIANTS_WITH_TEXT.includes(buttonVariant) && ( + {BUTTON_VARIANTS_WITH_TEXT.includes(buttonVariant) && (!!selectedName || !!placeholder) && ( {selectedName ?? placeholder} )} {dropdownArrow && ( diff --git a/web/components/dropdowns/module/index.tsx b/web/components/dropdowns/module/index.tsx index 5b7df2f23..1d843db8a 100644 --- a/web/components/dropdowns/module/index.tsx +++ b/web/components/dropdowns/module/index.tsx @@ -46,7 +46,7 @@ type ButtonContentProps = { hideIcon: boolean; hideText: boolean; onChange: (moduleIds: string[]) => void; - placeholder: string; + placeholder?: string; showCount: boolean; showTooltip?: boolean; value: string | string[] | null; @@ -75,13 +75,15 @@ const ButtonContent: React.FC = (props) => { {showCount ? (
{!hideIcon && } -
- {value.length > 0 - ? value.length === 1 - ? `${getModuleById(value[0])?.name || "module"}` - : `${value.length} Module${value.length === 1 ? "" : "s"}` - : placeholder} -
+ {(value.length > 0 || !!placeholder) && ( +
+ {value.length > 0 + ? value.length === 1 + ? `${getModuleById(value[0])?.name || "module"}` + : `${value.length} Module${value.length === 1 ? "" : "s"}` + : placeholder} +
+ )}
) : value.length > 0 ? (
@@ -158,7 +160,7 @@ export const ModuleDropdown: React.FC = observer((props) => { multiple, onChange, onClose, - placeholder = "Module", + placeholder = "", placement, projectId, showCount = false, diff --git a/web/components/issues/issue-modal/form.tsx b/web/components/issues/issue-modal/form.tsx index dcc1a3b7d..6c9872369 100644 --- a/web/components/issues/issue-modal/form.tsx +++ b/web/components/issues/issue-modal/form.tsx @@ -601,6 +601,7 @@ export const IssueFormRoot: FC = observer((props) => { onChange(cycleId); handleFormChange(); }} + placeholder="Cycle" value={value} buttonVariant="border-with-text" tabIndex={getTabIndex("cycle_id")} @@ -622,6 +623,7 @@ export const IssueFormRoot: FC = observer((props) => { onChange(moduleIds); handleFormChange(); }} + placeholder="Modules" buttonVariant="border-with-text" tabIndex={getTabIndex("module_ids")} multiple From 2f637fc9f1cf03a7f9e02808153aca9801977303 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Fri, 22 Mar 2024 18:39:26 +0530 Subject: [PATCH 23/53] fix: project total issue count mutation. (#4045) --- web/store/issue/project/issue.store.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/web/store/issue/project/issue.store.ts b/web/store/issue/project/issue.store.ts index 5b4a5894e..5c329749a 100644 --- a/web/store/issue/project/issue.store.ts +++ b/web/store/issue/project/issue.store.ts @@ -3,12 +3,12 @@ import pull from "lodash/pull"; import set from "lodash/set"; import update from "lodash/update"; import { action, makeObservable, observable, runInAction, computed } from "mobx"; +// types +import { TIssue, TGroupedIssues, TSubGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types"; // base class import { IssueService, IssueArchiveService } from "@/services/issue"; -import { TIssue, TGroupedIssues, TSubGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types"; import { IssueHelperStore } from "../helpers/issue-helper.store"; // services -// types import { IIssueRootStore } from "../root.store"; export interface IProjectIssues { @@ -117,6 +117,7 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues { }); this.rootStore.issues.addIssue(response); + this.rootIssueStore.rootStore.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId); return response; } catch (error) { @@ -137,6 +138,7 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues { }); this.rootStore.issues.addIssue([response]); + this.rootIssueStore.rootStore.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId); return response; } catch (error) { @@ -164,6 +166,7 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues { }); this.rootStore.issues.removeIssue(issueId); + this.rootIssueStore.rootStore.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId); } catch (error) { throw error; } @@ -179,6 +182,8 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues { }); pull(this.issues[projectId], issueId); }); + + this.rootIssueStore.rootStore.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId); } catch (error) { throw error; } @@ -216,6 +221,7 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues { }); const response = await this.issueService.bulkDeleteIssues(workspaceSlug, projectId, { issue_ids: issueIds }); + this.rootIssueStore.rootStore.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId); return response; } catch (error) { From 9652d56e49c4bfef842c33012ad20aa85ee427ad Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Fri, 22 Mar 2024 18:42:33 +0530 Subject: [PATCH 24/53] chore: removing deepsource.toml file (#4046) --- .deepsource.toml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index 2b40af672..000000000 --- a/.deepsource.toml +++ /dev/null @@ -1,23 +0,0 @@ -version = 1 - -exclude_patterns = [ - "bin/**", - "**/node_modules/", - "**/*.min.js" -] - -[[analyzers]] -name = "shell" - -[[analyzers]] -name = "javascript" - - [analyzers.meta] - plugins = ["react"] - environment = ["nodejs"] - -[[analyzers]] -name = "python" - - [analyzers.meta] - runtime_version = "3.x.x" \ No newline at end of file From b5ed602e05fb937d70f3dc9704389cd4c83b269c Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Fri, 22 Mar 2024 18:46:38 +0530 Subject: [PATCH 25/53] fix: disbaled the issue property check in the issue create/edit modal (#4038) --- .../issues/issue-modal/draft-issue-layout.tsx | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/web/components/issues/issue-modal/draft-issue-layout.tsx b/web/components/issues/issue-modal/draft-issue-layout.tsx index 240968faa..799a6bc4a 100644 --- a/web/components/issues/issue-modal/draft-issue-layout.tsx +++ b/web/components/issues/issue-modal/draft-issue-layout.tsx @@ -49,28 +49,33 @@ export const DraftIssueLayout: React.FC = observer((props) => { const { captureIssueEvent } = useEventTracker(); const handleClose = () => { - if (changesMade) { - Object.entries(changesMade).forEach(([key, value]) => { - const issueKey = key as keyof TIssue; - if (value === null || value === undefined || value === "") delete changesMade[issueKey]; - if (typeof value === "object" && isEmpty(value)) delete changesMade[issueKey]; - if (Array.isArray(value) && value.length === 0) delete changesMade[issueKey]; - if (issueKey === "project_id") delete changesMade.project_id; - if (issueKey === "priority" && value && value === "none") delete changesMade.priority; - if ( - issueKey === "description_html" && - changesMade.description_html && - isEmptyHtmlString(changesMade.description_html) - ) - delete changesMade.description_html; - }); - if (isEmpty(changesMade)) { - onClose(false); - setIssueDiscardModal(false); - } else setIssueDiscardModal(true); - } else { + if (data?.id) { onClose(false); setIssueDiscardModal(false); + } else { + if (changesMade) { + Object.entries(changesMade).forEach(([key, value]) => { + const issueKey = key as keyof TIssue; + if (value === null || value === undefined || value === "") delete changesMade[issueKey]; + if (typeof value === "object" && isEmpty(value)) delete changesMade[issueKey]; + if (Array.isArray(value) && value.length === 0) delete changesMade[issueKey]; + if (issueKey === "project_id") delete changesMade.project_id; + if (issueKey === "priority" && value && value === "none") delete changesMade.priority; + if ( + issueKey === "description_html" && + changesMade.description_html && + isEmptyHtmlString(changesMade.description_html) + ) + delete changesMade.description_html; + }); + if (isEmpty(changesMade)) { + onClose(false); + setIssueDiscardModal(false); + } else setIssueDiscardModal(true); + } else { + onClose(false); + setIssueDiscardModal(false); + } } }; From ec837a42d56466ed4ba8e47640f638d0e4c93bb7 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Fri, 22 Mar 2024 20:06:49 +0530 Subject: [PATCH 26/53] fix: handled undefined condition on issue title when we are converting into draft (#4048) --- web/components/issues/issue-modal/draft-issue-layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/issues/issue-modal/draft-issue-layout.tsx b/web/components/issues/issue-modal/draft-issue-layout.tsx index 799a6bc4a..5ec7e3a99 100644 --- a/web/components/issues/issue-modal/draft-issue-layout.tsx +++ b/web/components/issues/issue-modal/draft-issue-layout.tsx @@ -84,7 +84,7 @@ export const DraftIssueLayout: React.FC = observer((props) => { const payload = { ...changesMade, - name: changesMade.name?.trim() === "" ? "Untitled" : changesMade.name?.trim(), + name: changesMade?.name && changesMade?.name?.trim() === "" ? changesMade.name?.trim() : "Untitled", }; await issueDraftService From 31b2fa2c14fedd489de58ea3dcd54244985121fb Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Fri, 22 Mar 2024 20:46:13 +0530 Subject: [PATCH 27/53] fix: profile activity load more button (#4049) --- web/pages/profile/activity.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/web/pages/profile/activity.tsx b/web/pages/profile/activity.tsx index b3d88b1b3..f2a73c180 100644 --- a/web/pages/profile/activity.tsx +++ b/web/pages/profile/activity.tsx @@ -41,17 +41,19 @@ const ProfileActivityPage: NextPageWithLayout = observer(() => { /> ); + const isLoadMoreVisible = pageCount < totalPages && resultsCount !== 0; + return ( <> -
-
+
+
themeStore.toggleSidebar()} />

Activity

-
+
{activityPages} - {pageCount < totalPages && resultsCount !== 0 && ( + {isLoadMoreVisible && (
- } - completed={assignee.completed_issues} - total={assignee.total_issues} - /> - ); - })} + } + completed={assignee.completed_issues} + total={assignee.total_issues} + /> + ); + else + return ( + +
+ User +
+ No assignee +
+ } + completed={assignee.completed_issues} + total={assignee.total_issues} + /> + ); + }) + ) : ( +
+ +
+ )} - {cycle.distribution?.labels?.map((label, index) => ( - - - {label.label_name ?? "No labels"} -
- } - completed={label.completed_issues} - total={label.total_issues} - /> - ))} + {cycleIssues.length > 0 ? ( + cycle.distribution?.labels?.map((label, index) => ( + + + {label.label_name ?? "No labels"} +
+ } + completed={label.completed_issues} + total={label.total_issues} + /> + )) + ) : ( +
+ +
+ )} diff --git a/web/components/cycles/active-cycle/productivity.tsx b/web/components/cycles/active-cycle/productivity.tsx index 59c2ac3c9..a3366d934 100644 --- a/web/components/cycles/active-cycle/productivity.tsx +++ b/web/components/cycles/active-cycle/productivity.tsx @@ -3,6 +3,9 @@ import { FC } from "react"; import { ICycle } from "@plane/types"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; +import { EmptyState } from "@/components/empty-state"; +// constants +import { EmptyStateType } from "@/constants/empty-state"; export type ActiveCycleProductivityProps = { cycle: ICycle; @@ -16,31 +19,40 @@ export const ActiveCycleProductivity: FC = (props)

Issue burndown

- -
-
-
-
- - Ideal + {cycle.total_issues > 0 ? ( + <> +
+
+
+
+ + Ideal +
+
+ + Current +
+
+ {`Pending issues - ${cycle.backlog_issues + cycle.unstarted_issues + cycle.started_issues}`}
-
- - Current +
+
- {`Pending issues - ${cycle.backlog_issues + cycle.unstarted_issues + cycle.started_issues}`} -
-
- -
-
+ + ) : ( + <> +
+ +
+ + )}
); }; diff --git a/web/components/cycles/active-cycle/progress.tsx b/web/components/cycles/active-cycle/progress.tsx index dea3b496a..752f72bcc 100644 --- a/web/components/cycles/active-cycle/progress.tsx +++ b/web/components/cycles/active-cycle/progress.tsx @@ -3,8 +3,11 @@ import { FC } from "react"; import { ICycle } from "@plane/types"; // ui import { LinearProgressIndicator } from "@plane/ui"; +// components +import { EmptyState } from "@/components/empty-state"; // constants import { CYCLE_STATE_GROUPS_DETAILS } from "@/constants/cycle"; +import { EmptyStateType } from "@/constants/empty-state"; export type ActiveCycleProgressProps = { cycle: ICycle; @@ -32,48 +35,56 @@ export const ActiveCycleProgress: FC = (props) => {

Progress

- - {`${cycle.completed_issues + cycle.cancelled_issues}/${cycle.total_issues - cycle.cancelled_issues} ${ - cycle.completed_issues + cycle.cancelled_issues > 1 ? "Issues" : "Issue" - } closed`} - + {cycle.total_issues > 0 && ( + + {`${cycle.completed_issues + cycle.cancelled_issues}/${cycle.total_issues - cycle.cancelled_issues} ${ + cycle.completed_issues + cycle.cancelled_issues > 1 ? "Issues" : "Issue" + } closed`} + + )}
- + {cycle.total_issues > 0 && }
-
- {Object.keys(groupedIssues).map((group, index) => ( - <> - {groupedIssues[group] > 0 && ( -
-
-
- - {group} + {cycle.total_issues > 0 ? ( +
+ {Object.keys(groupedIssues).map((group, index) => ( + <> + {groupedIssues[group] > 0 && ( +
+
+
+ + {group} +
+ {`${groupedIssues[group]} ${ + groupedIssues[group] > 1 ? "Issues" : "Issue" + }`}
- {`${groupedIssues[group]} ${ - groupedIssues[group] > 1 ? "Issues" : "Issue" - }`}
-
- )} - - ))} - {cycle.cancelled_issues > 0 && ( - - - {`${cycle.cancelled_issues} cancelled ${ - cycle.cancelled_issues > 1 ? "issues are" : "issue is" - } excluded from this report.`}{" "} + )} + + ))} + {cycle.cancelled_issues > 0 && ( + + + {`${cycle.cancelled_issues} cancelled ${ + cycle.cancelled_issues > 1 ? "issues are" : "issue is" + } excluded from this report.`}{" "} + - - )} -
+ )} +
+ ) : ( +
+ +
+ )}
); }; diff --git a/web/components/cycles/active-cycle/upcoming-cycles-list.tsx b/web/components/cycles/active-cycle/upcoming-cycles-list.tsx index f4156f341..221ffab0b 100644 --- a/web/components/cycles/active-cycle/upcoming-cycles-list.tsx +++ b/web/components/cycles/active-cycle/upcoming-cycles-list.tsx @@ -1,5 +1,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; +import Image from "next/image"; +import { useTheme } from "next-themes"; // components import { UpcomingCycleListItem } from "@/components/cycles"; // hooks @@ -14,6 +16,11 @@ export const UpcomingCyclesList: FC = observer((props) => { // store hooks const { currentProjectUpcomingCycleIds } = useCycle(); + // theme + const { resolvedTheme } = useTheme(); + + const resolvedEmptyStatePath = `/empty-state/active-cycle/cycle-${resolvedTheme === "light" ? "light" : "dark"}.webp`; + if (!currentProjectUpcomingCycleIds) return null; return ( @@ -28,8 +35,18 @@ export const UpcomingCyclesList: FC = observer((props) => { ))}
) : ( -
-
+
+
+
+ button image +
No upcoming cycles

Create new cycles to find them here or check diff --git a/web/components/empty-state/empty-state.tsx b/web/components/empty-state/empty-state.tsx index 88fe21612..790bd5aec 100644 --- a/web/components/empty-state/empty-state.tsx +++ b/web/components/empty-state/empty-state.tsx @@ -151,12 +151,12 @@ export const EmptyState: React.FC = (props) => { )} {layout === "screen-simple" && (

-
+
{key diff --git a/web/constants/empty-state.ts b/web/constants/empty-state.ts index 6705021a5..363147775 100644 --- a/web/constants/empty-state.ts +++ b/web/constants/empty-state.ts @@ -84,6 +84,12 @@ export enum EmptyStateType { NOTIFICATION_ARCHIVED_EMPTY_STATE = "notification-archived-empty-state", NOTIFICATION_SNOOZED_EMPTY_STATE = "notification-snoozed-empty-state", NOTIFICATION_UNREAD_EMPTY_STATE = "notification-unread-empty-state", + + ACTIVE_CYCLE_PROGRESS_EMPTY_STATE = "active-cycle-progress-empty-state", + ACTIVE_CYCLE_CHART_EMPTY_STATE = "active-cycle-chart-empty-state", + ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE = "active-cycle-priority-issue-empty-state", + ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE = "active-cycle-assignee-empty-state", + ACTIVE_CYCLE_LABEL_EMPTY_STATE = "active-cycle-label-empty-state", } const emptyStateDetails = { @@ -584,6 +590,31 @@ const emptyStateDetails = { description: "Any notification you archive will be \n available here to help you focus", path: "/empty-state/search/archive", }, + [EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE, + title: "Add issues to the cycle to view it's \n progress", + path: "/empty-state/active-cycle/progress", + }, + [EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE, + title: "Add issues to the cycle to view the \n burndown chart.", + path: "/empty-state/active-cycle/chart", + }, + [EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE, + title: "Observe high priority issues tackled in \n the cycle at a glance.", + path: "/empty-state/active-cycle/priority", + }, + [EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE, + title: "Add assignees to issues to see a \n breakdown of work by assignees.", + path: "/empty-state/active-cycle/assignee", + }, + [EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE, + title: "Add labels to issues to see the \n breakdown of work by labels.", + path: "/empty-state/active-cycle/label", + }, } as const; export const EMPTY_STATE_DETAILS: Record = emptyStateDetails; diff --git a/web/public/empty-state/active-cycle/assignee-dark.webp b/web/public/empty-state/active-cycle/assignee-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..25906276703e5d6f61c413c1c4ed4380fa743141 GIT binary patch literal 1188 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 literal 0 HcmV?d00001 diff --git a/web/public/empty-state/active-cycle/chart-light.webp b/web/public/empty-state/active-cycle/chart-light.webp new file mode 100644 index 0000000000000000000000000000000000000000..587906fba3df748dd91b16f7482f3cd059c380bd GIT binary patch literal 1154 zcmV-|1bzEbNk&F`1ONb6MM6+kP&il$0000G0001+005f+06|PpNaq3o00E#?TW{T3 z`ydE{A#4bS5C~?l%^+dWFi08nFc1Vo5ClQcLvM*~>HL?Mh?oFOFfH|Va1*hYB8`u& z<{vmuxgKH{wnxq66XhFQmwe0KP-V5AA0@d#m2E&SNgrHiA`S8 zKv`}2x(u_Li|Zgab8;QxFgK6>h|SSPol!Ga8+Ap^oNd%oGk3Y8!yG=kSB&m0ru3&SYFZi_p*3*(iK+{==h469GVnNL3 zNEGChVqvUjNF0>DTP={=S4kqF^i8o)Zr?~Ols+pK%<`E;gFng^&iu&{kNpF(cq+Xs z0kQgyBf@Wzg_K^EnABH~nD8r$snSypish$0D*F>hg#nO-m4Fq#T*0My76&+3%4#I5ONK(hrM`o*$sY_&Xip&op z14vvNaF5F$pvI*FIW8HXxDWu23Io6%mHjD4B|nh{1ur=!e_qv?lvfm!^a>mi#@iZ^ z@{Tkh^bUJG4t$v7kv{=PL-28lM){017J@IgSd?!_BO&P>uO8q~2+|0@b^MYj@vvTukDb&{at4mnK}F{aVoD z=GBHicb_)&diUs#e%YUfj;VRms3%bKr4jn3<_QzJzx#2=h?^HX#@u|^FzTZ7(~NPG z%uW(UrhRTZVeq2!(u(mD&x#YKSY<|9G0SwH&m&=?i_AqbCR=14S~1~G=Aav4%BjeB zx)J7GWGpU(x##;Zx@R~@g-75@@G_N0SIU*(Y~HyK-ZQ~v%JtE%kfUaT^FO(62RD&d zB8`u|E(sF^09H^qAZ!5u0Pq$7odGJG0Gt3mkv^M8rK6)EF1(1~uo4MrZrxvcsh_TY z*gpV2KtA#X-HYr?ZZ>4nkO+b-+I@u*N2`!GH8I3T|HTHI$EsU=K#TN2h(8gAxGP;Z z=YUY~ofT^@kkC%+5);6E1c=vjc1TtoMNDLzswt>IcXHHd7TpY`cs_6d?)3&l=%fgM*uPf#uHDP`a81(wT+tJAV3xjFKVx~ zHj%18e}|hds`0e_c9aq0U%7YGDx&V&D>N#?cnP~~|9_0XsGNluPT!k6#c;=PGH;%L z@9z`SUSbdb*H`8#!*keQaG(G7YybVJSO4~z1UQgXV>eZyNf103Q<}}f%>U11mK+9^ UDEaeX-*GC7q(;dG!I>NY0OST4vH$=8 literal 0 HcmV?d00001 diff --git a/web/public/empty-state/active-cycle/cycle-dark.webp b/web/public/empty-state/active-cycle/cycle-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..d092308046fba21f8f4302b081e150b3f53e462e GIT binary patch literal 1360 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 E0KfPStN;K2 literal 0 HcmV?d00001 diff --git a/web/public/empty-state/active-cycle/label-light.webp b/web/public/empty-state/active-cycle/label-light.webp new file mode 100644 index 0000000000000000000000000000000000000000..e5ccc6994d13c152506d9bf7ba00d036676a8d54 GIT binary patch literal 1186 zcmV;T1YP@5Nk&GR1ONb6MM6+kP&il$0000G0001+005i-06|PpNaq3o00E#?TW{T3 z`ydE{A#4bS5C~?l%^+dWFi08nFc1Vo5ClQcLvM*~>HL?Mh?oHU<))?H4sIg$Ql#;* z)%@cf<$8!+*d8^LPn2(LUGgn^LzUHfew5?}Rki`SkO%puHtLZlM}=)@DHEerZFnhZ zPPD2`QPvs#s!dbMY_ix?WtmBO*mRFHjbF71OPxbvn>42h{Hje`%V>17so!X*BsO_T z17)@8>oUx0F0O;z%*l0#!`wXjBQ{4Hbw|p zn^zn9+)oR}`elC_I;Q4Lqn<#`mqzHDnkP)?{_e*eBW_;o7<2Ps!>EhSPcz0% zGCN5anfAHugu#o>ODo1tJS$F^VwD+b#Vpf(K97WnE;1L%m~4@GXvKs#nS*YGDW@Xi z=|-4$k+HZC=AQ4v=$_#q6&`^r!OK)0T`5O)M;FWTl1Nzl;eVg(Z);uz&V2aIbTCr{FUhPqPpT+dIVSN zRl)F|j^h9T{=FRnJv-|hjMa%SB7gt<_%0%CKe%`c`0=E|9U*{_RTo1EN093wYN(X1 zlIzz}yyh8O#k1fOLz|bTLn4X3@hmz06120_+)(~3({kgV?@7fp3YD(?bYJBKO zL%$rC8%rL6S+4-PIkq^5qFC{>!00E$uZExI4 zdm#vdAsh&X5C~>)%phUVFi0767zlzP2!bGJmM)2HX};x8L`(o?n3j4wxQW%EOTJ}ysIpqmkCObL$~GVuav|T;Mm_TEsIUz!WoERh4KF24 zidMBL$~vWQwP{M3P8OT0EK^Ajo9>b3@vSytsgp=-ljbyoZ?$P_8IEo?^&5?q#3nCk zq^vf5UB+3>#dVaMIk}E;n48A{#O7$D-l&v>5cpy{;3Lijjqu^{G? zBnom)u`t$CBo0a^tQN@avm}vF`lwhaw~r(iN*@#pX8Ay(!S7`YXMXF5$NmmkJeA%k z0kQf9M}%J`3n{%QF{v*eG2s^$Q>7<4D3+h>QQ4nxRQM0Fuo8eAmkglBr2=@wR7|0geo#MW#U_Bhj(Y{vSaiBhhJ*Y2e5(?vXjLM`lBf zOvMtJj1-wKATj_XE)BpvE<3Ps}ap2t?kNg%m8iMyrG|C60u@HQ^#iD#f8VN}sVT;6u z&q?DTIJ3r~oC1l0;M^RA{}aNz8u5s-8mY6L1SWd9gfCiPC!C8*vNT)g|X<7yJm zgf2r;zciu4?AL-WH?KByy8E=D+q*}1bjk5_c5oAUCerxW>yj`*09H^qAo>6R0FV#>odGJH0Gt3mkwTtIC8MJut28Kp zuo4MrZr{`d00bZYR3GMIgCr58E(G4ena0^|?cy=v%sF#I(0Yf7bmRg$W?Z~O4T!v! zO+mYubeV@fE(dz-yg;ekXaV3}xp4|OTos(oU(jXh;A9Aq(x3SiI=!@6IW!vr$ zxXE$F9uh!KxFYa+O7B`=N8cDuu9qT5G?Xm1hgJ}AYCe@7Nxq(?f%<^MtF2K1H&?Ky W6r?)`dS&naK_QZFBpht`00003o8$!m literal 0 HcmV?d00001 diff --git a/web/public/empty-state/active-cycle/priority-light.webp b/web/public/empty-state/active-cycle/priority-light.webp new file mode 100644 index 0000000000000000000000000000000000000000..fde814c6a7c2c5c373b5a900a78ae0ff6cfdbe12 GIT binary patch literal 1096 zcmV-O1h@NANk&FM1ONb6MM6+kP&il$0000G0001+005f+06|PpNaq3o00E#?TW{T3 z`ydE{A#4bS5C~?l%^+dWFi08nFc1Vo5ClQcLvM*~>HL?Mh?oFOFfH|Va1*hYB8`u& z<{vmuxgKH{wnxq66XhFQmwe0KP-V5AA0@d#m2E&SNgrHiA`S8 zKv`}2x(u_Li|Zgab8;QxFgK6>h|SSPol!Ga8+Ap^oNd%oGk3Y8!yG=kSB&m0ru3&SYFZi_p*3*(iK+{==h469GVnNL3 zNEGChVqvUjNF0>DTP={=S4kqF^i8o)Zr?~Ols+pK%<`E;gFng^&iu&{kNpF(cq+Xs z0kQgyBf@Wzg_K^EnABH~nD8r$snSypish$0D*F>hg#nO-m4Fq#T*0My76&+3%4#I5ONK(hrM`o*$sY_&Xip&op z14vvNaF5F$pvI*FIW8HXxDWu23Io6%mHjD4B|nh{1ur=!e_qv?lvfm!^a>mi#@iZ^ z@{Tkh^bUJG4t$v7kv{=PL-28lM){017J@IgSd?!_BO&P>uO8q~2+|0@b^MYj@vvTukDb&{at4mnK}F{aVoD z=GBHicb_)&diUs#e%YUfj;VRms3%bKr4jn3<_QzJzx#2=h?^HX#@u|^FzTZ7(~NPG z%uW(UrhRTZVeq2!(u(mD&x#YKSY<|9G0SwH&m&=?i_AqbCR=14S~1~G=Aav4%BjeB zx)J7GWGpU(x##;Zx@R~@g-75@@G_N0SIU*(Y~HyK-ZQ~v%JtE%kfUaT^FO(62RD&d zB8`u|E(sF^09H^qATj{}0I(APodGJG0Gt3mkwlwGC8Q#uEZoQduo4MrZs5QGW=dWE zsGrUM20uVP_JuR91l+3oD~NqKQy7;nbS$WW06L0S4~Sf2hk@peah}H*=BNXh2BRic z(D*vX=5LhldN9Y=%Y@?I4#oTVwevgddSZy;G`c*}X-rH>&}VVw^9QsDT13U|dPafE ztC@PGuZruC!(j7WgKv=NwENd1Tg2VdGI2lv{+(6V4}mLYK)%h!N7@qJ31ojj2!@MM zmR~?1DT1)X%zTv#As)iw!Rx-Fur_|uR%NaQWrOG`B9zG>EF5YcT_so34p07~Lk;)%phUVFi0767zlzP2!bGJmM)2HX};x8L`(qwdec&G2R9LWD$@Aa zYW{MMay`T@Y>%4BDatptF8P+-p~`AKKT7h0D%*fu$c21U8}-Puqrx_{l$p`0HoTNH zDO%O0DC?BI)ut(BI$3P0vP>mCY`RC9$G6&qrA{KTO`6jTzSX9!WjMOo)NeFa5}UlF zk+RzKbs1+h7uQj4=HxoYVQwA+5SycodZT8pHtLI-IoqhKX6|xNhdF%ovzp7dURHB@ z?PD>wa}P=V(sUh(IWBbB&0N1-Rm}N%O;YbPUBc!*U-4}Ltmh?(fTq(93*qCe#e$em zk|@YI#ll!mkvJ%wuv#Fu&yqw!>7!zy+&+?6D1A^YnB@bB2EUgrocXOI9{W3F@l<-F z1jOna91(t%ETr_J#H7A>#Drg1OqHJGpjdvgM`eG)QQ<$x!b$*gTrz+fmkQt!mjghH zivX~|0$-6y$dOr4BU7D0t2>`SGI0 zq`aV*q!-|bFkaV)ls8BNLT_M?$ANcqJn~!MXb9df(I_8~#zOGv7K`!`X(S|lge?*q zJ|~TX;LI9_atb60f^%~emXq*^!GW`rMnKYOs1c~Rko{v^nbbQ?m!NuAaPjWjj;l#L z6S@pZ{nCUEvtJ9k+`QV*>F(2pZtou5(J}ke&@(k}8g&I~zBEGT)I4EA|93y`7;^Js z$Do@J8-`tUews0GlG#bZ(6rBOCyZWnURp81#IxdrIaZmGR!lS9=krLI=^}HHjM)~M zhgQsZlR4-{m~$#Jo^FJR7a5BSVe!N0aj2rAS3|*0MHQtodGJH0G$9nkw%_MrK6&uq?Ni* zuo4MrZs5T;_y$NWzyaoc^?>zJc$GP>W8pynR>|84C2+}?d?}zK*o@mRw;L!q`W(=? z=^%-&I^)t(fdpZm^{G-RpXT{}KzlGv8Tu|Q5ZmdlM$UD`xOMq*VvOM{Iq6?L9VhzE z4!=PFtXQ*dZs*B~6#?D$s*=ut1&-1H0R0L**t*4y|N3Iu$AsB_?zz5`0%+t;9|E72j%oz3%TP#o zPi(1~FO*hv7J~xbipBc}Vb5~V6e$dJZ=DP~xceTBb2AtEWF@7)X}ThZj+m2}TeSWN MWeMCLcpv}(0Pm3pc>n+a literal 0 HcmV?d00001 diff --git a/web/public/empty-state/active-cycle/progress-light.webp b/web/public/empty-state/active-cycle/progress-light.webp new file mode 100644 index 0000000000000000000000000000000000000000..ae30cf76a5cec3bdcf4c83c809099ae5bb172749 GIT binary patch literal 1172 zcmV;F1Z(?JNk&GD1ONb6MM6+kP&il$0000G0001+005f+06|PpNaq3o00E#?TW{T3 z`ydE{A#4bS5C~?l%^+dWFi08nFc1Vo5ClQcLvM*~>HL?Mh?oFOFfH|Va1*hYB8`u& z<{vmuxgKH{wnxq66XhFQmwe0KP-V5AA0@d#m2E&SNgrHiA`S8 zKv`}2x(u_Li|Zgab8;QxFgK6>h|SSPol!Ga8+Ap^oNd%oGk3Y8!yG=kSB&m0ru3&SYFZi_p*3*(iK+{==h469GVnNL3 zNEGChVqvUjNF0>DTP={=S4kqF^i8o)Zr?~Ols+pK%<`E;gFng^&iu&{kNpF(cq+Xs z0kQgyBf@Wzg_K^EnABH~nD8r$snSypish$0D*F>hg#nO-m4Fq#T*0My76&+3%4#I5ONK(hrM`o*$sY_&Xip&op z14vvNaF5F$pvI*FIW8HXxDWu23Io6%mHjD4B|nh{1ur=!e_qv?lvfm!^a>mi#@iZ^ z@{Tkh^bUJG4t$v7kv{=PL-28lM){017J@IgSd?!_BO&P>uO8q~2+|0@b^MYj@vvTukDb&{at4mnK}F{aVoD z=GBHicb_)&diUs#e%YUfj;VRms3%bKr4jn3<_QzJzx#2=h?^HX#@u|^FzTZ7(~NPG z%uW(UrhRTZVeq2!(u(mD&x#YKSY<|9G0SwH&m&=?i_AqbCR=14S~1~G=Aav4%BjeB zx)J7GWGpU(x##;Zx@R~@g-75@@G_N0SIU*(Y~HyK-ZQ~v%JtE%kfUaT^FO(62RD&d zB8`u|E(sF^09H^qAbtS=05BE+odGJG0Gt3mkwTwJrK6)Eqg2|cuo4MrZs5THW=dT@ zt>4f;3jaVp^m;rXo>TXElFkN)zjh5aNGn{sXQ$b+q*DB)qX9-ze{@$073uOOMY!{f zW)#}s1r_4IsLg~SRSB)G9qNgg9hb#sf7`|m#Vrtnocb)zExUMZk{ZFrwoKu*@`q|4 zQ5H~jZ=R^}=U@@i<^Dq&WWvdvPNOh{loi~|ZGk<9HSJr};RWMj<=dWPuv>rt{>5Qz zpRMHoz^_2r&$T%Ug(unuVEy||2<@WMLKTwRlTlqWKvdEKSoM}C%cUly_KeV$-6-)K zgTThim1KK`s#=0vb_{Vz>+7-9swihiT_(VAEy|D4Ro-zi2S7$B@ zBjDH;EIBRRi#rBe74(U-`_aCQat4ymJ{T#S$mWTk!qRz6U^@U;Ap@B}{ctXq6aW9b mumAVeAOG*1v>@Go<&XKbD!_cW78>wc>S;r0$QdeP-~a&Rw=ItV literal 0 HcmV?d00001 From 7e0037b06bcfb6a661086d177ba92c27712db2af Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:17:34 +0530 Subject: [PATCH 30/53] [WEB-823] fix: quick add flicker and dropdown placement in calendar layout (#4054) * chore: placement prop added in quick action menu * fix: calenar layout quick action menu placement * fix: calendar quick add flicker --- .../issue-layouts/calendar/base-calendar-root.tsx | 3 ++- .../issues/issue-layouts/calendar/calendar.tsx | 3 ++- .../issues/issue-layouts/calendar/day-tile.tsx | 3 ++- .../issues/issue-layouts/calendar/issue-block-root.tsx | 3 ++- .../issues/issue-layouts/calendar/issue-block.tsx | 10 ++++++++-- .../issues/issue-layouts/calendar/issue-blocks.tsx | 3 ++- .../issue-layouts/calendar/quick-add-issue-form.tsx | 2 +- .../issues/issue-layouts/calendar/week-days.tsx | 3 ++- .../issues/issue-layouts/list/list-view-types.d.ts | 2 ++ .../quick-action-dropdowns/cycle-issue.tsx | 3 ++- .../quick-action-dropdowns/module-issue.tsx | 3 ++- .../quick-action-dropdowns/project-issue.tsx | 3 ++- 12 files changed, 29 insertions(+), 12 deletions(-) diff --git a/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx b/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx index a5f478746..9e54d2cf7 100644 --- a/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx +++ b/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx @@ -89,7 +89,7 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => { groupedIssueIds={groupedIssueIds} layout={displayFilters?.calendar?.layout} showWeekends={displayFilters?.calendar?.show_weekends ?? false} - quickActions={(issue, customActionButton) => ( + quickActions={(issue, customActionButton, placement) => ( { handleArchive={async () => archiveIssue && archiveIssue(issue.project_id, issue.id)} handleRestore={async () => restoreIssue && restoreIssue(issue.project_id, issue.id)} readOnly={!isEditingAllowed || isCompletedCycle} + placements={placement} /> )} addIssuesToView={addIssuesToView} diff --git a/web/components/issues/issue-layouts/calendar/calendar.tsx b/web/components/issues/issue-layouts/calendar/calendar.tsx index 70efb6c46..8c6a7ebe9 100644 --- a/web/components/issues/issue-layouts/calendar/calendar.tsx +++ b/web/components/issues/issue-layouts/calendar/calendar.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import { Placement } from "@popperjs/core"; import { observer } from "mobx-react-lite"; import type { IIssueDisplayFilterOptions, @@ -37,7 +38,7 @@ type Props = { groupedIssueIds: TGroupedIssues; layout: "month" | "week" | undefined; showWeekends: boolean; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; quickAddCallback?: ( workspaceSlug: string, projectId: string, diff --git a/web/components/issues/issue-layouts/calendar/day-tile.tsx b/web/components/issues/issue-layouts/calendar/day-tile.tsx index 8239458e0..ba4049888 100644 --- a/web/components/issues/issue-layouts/calendar/day-tile.tsx +++ b/web/components/issues/issue-layouts/calendar/day-tile.tsx @@ -1,4 +1,5 @@ import { Droppable } from "@hello-pangea/dnd"; +import { Placement } from "@popperjs/core"; import { observer } from "mobx-react-lite"; import { TGroupedIssues, TIssue, TIssueMap } from "@plane/types"; // components @@ -19,7 +20,7 @@ type Props = { date: ICalendarDate; issues: TIssueMap | undefined; groupedIssueIds: TGroupedIssues; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; enableQuickIssueCreate?: boolean; disableIssueCreation?: boolean; quickAddCallback?: ( diff --git a/web/components/issues/issue-layouts/calendar/issue-block-root.tsx b/web/components/issues/issue-layouts/calendar/issue-block-root.tsx index dacc3439b..f7fd7ab52 100644 --- a/web/components/issues/issue-layouts/calendar/issue-block-root.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-block-root.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { Placement } from "@popperjs/core"; // components import { TIssue, TIssueMap } from "@plane/types"; import { CalendarIssueBlock } from "@/components/issues"; @@ -7,7 +8,7 @@ import { CalendarIssueBlock } from "@/components/issues"; type Props = { issues: TIssueMap | undefined; issueId: string; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; isDragging?: boolean; }; diff --git a/web/components/issues/issue-layouts/calendar/issue-block.tsx b/web/components/issues/issue-layouts/calendar/issue-block.tsx index 7c72cca2e..713049ac3 100644 --- a/web/components/issues/issue-layouts/calendar/issue-block.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-block.tsx @@ -1,4 +1,5 @@ import { useState, useRef } from "react"; +import { Placement } from "@popperjs/core"; import { observer } from "mobx-react"; import { MoreHorizontal } from "lucide-react"; import { TIssue } from "@plane/types"; @@ -14,7 +15,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os"; type Props = { issue: TIssue; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; isDragging?: boolean; }; @@ -56,6 +57,11 @@ export const CalendarIssueBlock: React.FC = observer((props) => {
); + const isMenuActionRefAboveScreenBottom = + menuActionRef?.current && menuActionRef?.current?.getBoundingClientRect().bottom < window.innerHeight - 220; + + const placement = isMenuActionRefAboveScreenBottom ? "bottom-end" : "top-end"; + return ( = observer((props) => { e.stopPropagation(); }} > - {quickActions(issue, customActionButton)} + {quickActions(issue, customActionButton, placement)}
diff --git a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx index 711639470..79cc84ecb 100644 --- a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx @@ -1,5 +1,6 @@ import { useState } from "react"; import { Draggable } from "@hello-pangea/dnd"; +import { Placement } from "@popperjs/core"; import { observer } from "mobx-react-lite"; import { TIssue, TIssueMap } from "@plane/types"; // components @@ -12,7 +13,7 @@ type Props = { date: Date; issues: TIssueMap | undefined; issueIdList: string[] | null; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; isDragDisabled?: boolean; enableQuickIssueCreate?: boolean; disableIssueCreation?: boolean; diff --git a/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx b/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx index 4bac9ff4f..7e17496d4 100644 --- a/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx +++ b/web/components/issues/issue-layouts/calendar/quick-add-issue-form.tsx @@ -230,7 +230,7 @@ export const CalendarQuickAddIssueForm: React.FC = observer((props) => { {!isOpen && (
diff --git a/web/components/issues/issue-layouts/calendar/week-days.tsx b/web/components/issues/issue-layouts/calendar/week-days.tsx index 765680827..429c237e2 100644 --- a/web/components/issues/issue-layouts/calendar/week-days.tsx +++ b/web/components/issues/issue-layouts/calendar/week-days.tsx @@ -1,3 +1,4 @@ +import { Placement } from "@popperjs/core"; import { observer } from "mobx-react-lite"; import { TGroupedIssues, TIssue, TIssueMap } from "@plane/types"; // components @@ -16,7 +17,7 @@ type Props = { issues: TIssueMap | undefined; groupedIssueIds: TGroupedIssues; week: ICalendarWeek | undefined; - quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode; + quickActions: (issue: TIssue, customActionButton?: React.ReactElement, placement?: Placement) => React.ReactNode; enableQuickIssueCreate?: boolean; disableIssueCreation?: boolean; quickAddCallback?: ( diff --git a/web/components/issues/issue-layouts/list/list-view-types.d.ts b/web/components/issues/issue-layouts/list/list-view-types.d.ts index f435d0639..f38f52b9c 100644 --- a/web/components/issues/issue-layouts/list/list-view-types.d.ts +++ b/web/components/issues/issue-layouts/list/list-view-types.d.ts @@ -1,3 +1,4 @@ +import { Placement } from "@popperjs/core"; import { TIssue } from "@plane/types"; export interface IQuickActionProps { @@ -10,4 +11,5 @@ export interface IQuickActionProps { customActionButton?: React.ReactElement; portalElement?: HTMLDivElement | null; readOnly?: boolean; + placements?: Placement; } diff --git a/web/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx b/web/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx index d7ff21b84..eed0e0dc6 100644 --- a/web/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx +++ b/web/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx @@ -31,6 +31,7 @@ export const CycleIssueQuickActions: React.FC = observer((pro customActionButton, portalElement, readOnly = false, + placements = "bottom-start", } = props; // states const [createUpdateIssueModal, setCreateUpdateIssueModal] = useState(false); @@ -107,7 +108,7 @@ export const CycleIssueQuickActions: React.FC = observer((pro /> = observer((pr customActionButton, portalElement, readOnly = false, + placements = "bottom-start", } = props; // states const [createUpdateIssueModal, setCreateUpdateIssueModal] = useState(false); @@ -106,7 +107,7 @@ export const ModuleIssueQuickActions: React.FC = observer((pr /> = observer((p customActionButton, portalElement, readOnly = false, + placements = "bottom-start", } = props; // router const router = useRouter(); @@ -107,7 +108,7 @@ export const ProjectIssueQuickActions: React.FC = observer((p /> Date: Mon, 25 Mar 2024 14:18:24 +0530 Subject: [PATCH 31/53] chore(deps): bump django in /apiserver/requirements (#4055) Bumps [django](https://github.com/django/django) from 4.2.10 to 4.2.11. - [Commits](https://github.com/django/django/compare/4.2.10...4.2.11) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apiserver/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/requirements/base.txt b/apiserver/requirements/base.txt index 28b45adbe..2b7d383ba 100644 --- a/apiserver/requirements/base.txt +++ b/apiserver/requirements/base.txt @@ -1,6 +1,6 @@ # base requirements -Django==4.2.10 +Django==4.2.11 psycopg==3.1.12 djangorestframework==3.14.0 redis==4.6.0 From 564d64a30e83fab5267711ab883dee564563b4d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:19:02 +0530 Subject: [PATCH 32/53] chore(deps): bump follow-redirects from 1.15.4 to 1.15.6 (#4056) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 66fef83d1..c56d2280f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4773,9 +4773,9 @@ flatted@^3.2.9: integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" From 8205961d2a8adb7955efbee2961d5bd321cdd950 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:19:45 +0530 Subject: [PATCH 33/53] [WEB-826] chore: integrations (#4057) * fix: workspace integration page * chore: remove integrations and code refactor --- web/constants/project.ts | 8 -- web/constants/workspace.ts | 16 ---- .../[projectId]/settings/integrations.tsx | 86 ------------------- .../[workspaceSlug]/settings/imports.tsx | 58 ------------- .../[workspaceSlug]/settings/integrations.tsx | 82 ------------------ 5 files changed, 250 deletions(-) delete mode 100644 web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx delete mode 100644 web/pages/[workspaceSlug]/settings/imports.tsx delete mode 100644 web/pages/[workspaceSlug]/settings/integrations.tsx diff --git a/web/constants/project.ts b/web/constants/project.ts index c4ef817fd..1715c0e82 100644 --- a/web/constants/project.ts +++ b/web/constants/project.ts @@ -115,14 +115,6 @@ export const PROJECT_SETTINGS_LINKS: { highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/labels`, Icon: SettingIcon, }, - { - key: "integrations", - label: "Integrations", - href: `/settings/integrations`, - access: EUserProjectRoles.ADMIN, - highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/integrations`, - Icon: SettingIcon, - }, { key: "estimates", label: "Estimates", diff --git a/web/constants/workspace.ts b/web/constants/workspace.ts index 18cfac3a8..cbb8d2324 100644 --- a/web/constants/workspace.ts +++ b/web/constants/workspace.ts @@ -149,22 +149,6 @@ export const WORKSPACE_SETTINGS_LINKS: { highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/billing`, Icon: SettingIcon, }, - { - key: "integrations", - label: "Integrations", - href: `/settings/integrations`, - access: EUserWorkspaceRoles.ADMIN, - highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/integrations`, - Icon: SettingIcon, - }, - { - key: "import", - label: "Imports", - href: `/settings/imports`, - access: EUserWorkspaceRoles.ADMIN, - highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/imports`, - Icon: SettingIcon, - }, { key: "export", label: "Exports", diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx deleted file mode 100644 index a4d8c4dd7..000000000 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { ReactElement } from "react"; -import { observer } from "mobx-react"; -import { useRouter } from "next/router"; -import useSWR from "swr"; -import { IProject } from "@plane/types"; -// hooks -import { PageHead } from "@/components/core"; -import { EmptyState } from "@/components/empty-state"; -import { ProjectSettingHeader } from "@/components/headers"; -import { IntegrationCard } from "@/components/project"; -import { IntegrationsSettingsLoader } from "@/components/ui"; -// layouts -import { EmptyStateType } from "@/constants/empty-state"; -import { PROJECT_DETAILS, WORKSPACE_INTEGRATIONS } from "@/constants/fetch-keys"; -import { AppLayout } from "@/layouts/app-layout"; -import { ProjectSettingLayout } from "@/layouts/settings-layout"; -// services -import { NextPageWithLayout } from "@/lib/types"; -import { IntegrationService } from "@/services/integrations"; -import { ProjectService } from "@/services/project"; -// components -// ui -// types -// fetch-keys -// constants - -// services -const integrationService = new IntegrationService(); -const projectService = new ProjectService(); - -const ProjectIntegrationsPage: NextPageWithLayout = observer(() => { - const router = useRouter(); - const { workspaceSlug, projectId } = router.query; - // fetch project details - const { data: projectDetails } = useSWR( - workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, - workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null - ); - // fetch Integrations list - const { data: workspaceIntegrations } = useSWR( - workspaceSlug ? WORKSPACE_INTEGRATIONS(workspaceSlug as string) : null, - () => (workspaceSlug ? integrationService.getWorkspaceIntegrationsList(workspaceSlug as string) : null) - ); - // derived values - const isAdmin = projectDetails?.member_role === 20; - const pageTitle = projectDetails?.name ? `${projectDetails?.name} - Integrations` : undefined; - - return ( - <> - -
-
-

Integrations

-
- {workspaceIntegrations ? ( - workspaceIntegrations.length > 0 ? ( -
- {workspaceIntegrations.map((integration) => ( - - ))} -
- ) : ( -
- -
- ) - ) : ( - - )} -
- - ); -}); - -ProjectIntegrationsPage.getLayout = function getLayout(page: ReactElement) { - return ( - }> - {page} - - ); -}; - -export default ProjectIntegrationsPage; diff --git a/web/pages/[workspaceSlug]/settings/imports.tsx b/web/pages/[workspaceSlug]/settings/imports.tsx deleted file mode 100644 index caf958d38..000000000 --- a/web/pages/[workspaceSlug]/settings/imports.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { observer } from "mobx-react-lite"; -// hooks -import { PageHead } from "@/components/core"; -import { WorkspaceSettingHeader } from "@/components/headers"; -import IntegrationGuide from "@/components/integration/guide"; -import { EUserWorkspaceRoles } from "@/constants/workspace"; -import { useUser, useWorkspace } from "@/hooks/store"; -// layouts -import { AppLayout } from "@/layouts/app-layout"; -import { WorkspaceSettingLayout } from "@/layouts/settings-layout"; -// components -// types -import { NextPageWithLayout } from "@/lib/types"; -// constants - -const ImportsPage: NextPageWithLayout = observer(() => { - // store hooks - const { - membership: { currentWorkspaceRole }, - } = useUser(); - const { currentWorkspace } = useWorkspace(); - - // derived values - const isAdmin = currentWorkspaceRole === EUserWorkspaceRoles.ADMIN; - const pageTitle = currentWorkspace?.name ? `${currentWorkspace.name} - Imports` : undefined; - - if (!isAdmin) - return ( - <> - -
-

You are not authorized to access this page.

-
- - ); - - return ( - <> - -
-
-

Imports

-
- -
- - ); -}); - -ImportsPage.getLayout = function getLayout(page: React.ReactElement) { - return ( - }> - {page} - - ); -}; - -export default ImportsPage; diff --git a/web/pages/[workspaceSlug]/settings/integrations.tsx b/web/pages/[workspaceSlug]/settings/integrations.tsx deleted file mode 100644 index 7748f976d..000000000 --- a/web/pages/[workspaceSlug]/settings/integrations.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { ReactElement } from "react"; -import { observer } from "mobx-react-lite"; -import { useRouter } from "next/router"; -import useSWR from "swr"; -// hooks -// services -// layouts -// components -import { PageHead } from "@/components/core"; -import { WorkspaceSettingHeader } from "@/components/headers"; -import { SingleIntegrationCard } from "@/components/integration"; -// ui -import { IntegrationAndImportExportBanner, IntegrationsSettingsLoader } from "@/components/ui"; -// types -// fetch-keys -import { APP_INTEGRATIONS } from "@/constants/fetch-keys"; -// constants -import { EUserWorkspaceRoles } from "@/constants/workspace"; -import { useUser, useWorkspace } from "@/hooks/store"; -import { AppLayout } from "@/layouts/app-layout"; -import { WorkspaceSettingLayout } from "@/layouts/settings-layout"; -import { NextPageWithLayout } from "@/lib/types"; -import { IntegrationService } from "@/services/integrations"; - -const integrationService = new IntegrationService(); - -const WorkspaceIntegrationsPage: NextPageWithLayout = observer(() => { - // router - const router = useRouter(); - const { workspaceSlug } = router.query; - // store hooks - const { - membership: { currentWorkspaceRole }, - } = useUser(); - const { currentWorkspace } = useWorkspace(); - - // derived values - const isAdmin = currentWorkspaceRole === EUserWorkspaceRoles.ADMIN; - const pageTitle = currentWorkspace?.name ? `${currentWorkspace.name} - Integrations` : undefined; - - if (!isAdmin) - return ( - <> - -
-

You are not authorized to access this page.

-
- - ); - - const { data: appIntegrations } = useSWR(workspaceSlug && isAdmin ? APP_INTEGRATIONS : null, () => - workspaceSlug && isAdmin ? integrationService.getAppIntegrationsList() : null - ); - - return ( - <> - -
- -
- {appIntegrations ? ( - appIntegrations.map((integration) => ( - - )) - ) : ( - - )} -
-
- - ); -}); - -WorkspaceIntegrationsPage.getLayout = function getLayout(page: ReactElement) { - return ( - }> - {page} - - ); -}; - -export default WorkspaceIntegrationsPage; From 4b8a1353fcb404d5fdeb008183516108897130bb Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:20:26 +0530 Subject: [PATCH 34/53] fix: kanban layout quick add (#4058) --- .../issues/issue-layouts/properties/all-properties.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/issues/issue-layouts/properties/all-properties.tsx b/web/components/issues/issue-layouts/properties/all-properties.tsx index 1c63cb483..72614079a 100644 --- a/web/components/issues/issue-layouts/properties/all-properties.tsx +++ b/web/components/issues/issue-layouts/properties/all-properties.tsx @@ -341,7 +341,7 @@ export const IssueProperties: React.FC = observer((props) => { multiple buttonVariant={issue.assignee_ids?.length > 0 ? "transparent-without-text" : "border-without-text"} buttonClassName={issue.assignee_ids?.length > 0 ? "hover:bg-transparent px-0" : ""} - showTooltip={issue?.assignee_ids.length === 0} + showTooltip={issue?.assignee_ids?.length === 0} placeholder="Assignees" tooltipContent="" /> From 07106f916196c948bc4712ff70f6162c7fcdadf9 Mon Sep 17 00:00:00 2001 From: igeni Date: Mon, 25 Mar 2024 13:52:20 +0300 Subject: [PATCH 35/53] fixed bug with missed color #FFFFFF (#4050) --- apiserver/back_migration.py | 2 +- apiserver/plane/app/views/issue/label.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apiserver/back_migration.py b/apiserver/back_migration.py index a0e45416a..328b9db2b 100644 --- a/apiserver/back_migration.py +++ b/apiserver/back_migration.py @@ -182,7 +182,7 @@ def update_label_color(): labels = Label.objects.filter(color="") updated_labels = [] for label in labels: - label.color = "#" + "%06x" % random.randint(0, 0xFFFFFF) + label.color = f"#{random.randint(0, 0xFFFFFF+1):06X}" updated_labels.append(label) Label.objects.bulk_update(updated_labels, ["color"], batch_size=100) diff --git a/apiserver/plane/app/views/issue/label.py b/apiserver/plane/app/views/issue/label.py index 557c2018f..c5dc35809 100644 --- a/apiserver/plane/app/views/issue/label.py +++ b/apiserver/plane/app/views/issue/label.py @@ -87,7 +87,7 @@ class BulkCreateIssueLabelsEndpoint(BaseAPIView): Label( name=label.get("name", "Migrated"), description=label.get("description", "Migrated Issue"), - color="#" + "%06x" % random.randint(0, 0xFFFFFF), + color=f"#{random.randint(0, 0xFFFFFF+1):06X}", project_id=project_id, workspace_id=project.workspace_id, created_by=request.user, From 7e9daf8a206215065746f484db9ce2b831e944fc Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Mon, 25 Mar 2024 18:54:55 +0530 Subject: [PATCH 36/53] fix: bad html filtering regexp --- web/helpers/string.helper.ts | 20 ++++++++++---------- web/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/web/helpers/string.helper.ts b/web/helpers/string.helper.ts index ac0256731..03233a918 100644 --- a/web/helpers/string.helper.ts +++ b/web/helpers/string.helper.ts @@ -34,7 +34,7 @@ export const createSimilarString = (str: string) => { }; const fallbackCopyTextToClipboard = (text: string) => { - var textArea = document.createElement("textarea"); + const textArea = document.createElement("textarea"); textArea.value = text; // Avoid scrolling to bottom @@ -49,7 +49,7 @@ const fallbackCopyTextToClipboard = (text: string) => { try { // FIXME: Even though we are using this as a fallback, execCommand is deprecated 👎. We should find a better way to do this. // https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand - var successful = document.execCommand("copy"); + document.execCommand("copy"); } catch (err) {} document.body.removeChild(textArea); @@ -117,9 +117,9 @@ export const getFirstCharacters = (str: string) => { * console.log(text); // Some text */ -export const stripHTML = (html: string) => { - const strippedText = html.replace(/]*>[\s\S]*?<\/script>/gi, ""); // Remove script tags - return strippedText.replace(/<[^>]*>/g, ""); // Remove all other HTML tags +export const sanitizeHTML = (htmlString: string) => { + const sanitizedText = DOMPurify.sanitize(htmlString, { ALLOWED_TAGS: [] }); // sanitize the string to remove all HTML tags + return sanitizedText.trim(); // trim the string to remove leading and trailing whitespaces }; /** @@ -130,7 +130,7 @@ export const stripHTML = (html: string) => { * console.log(text); // Some text */ -export const stripAndTruncateHTML = (html: string, length: number = 55) => truncateText(stripHTML(html), length); +export const stripAndTruncateHTML = (html: string, length: number = 55) => truncateText(sanitizeHTML(html), length); /** * @description: This function return number count in string if number is more than 100 then it will return 99+ @@ -172,10 +172,10 @@ export const getFetchKeysForIssueMutation = (options: { const ganttFetchKey = cycleId ? { ganttFetchKey: CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), ganttParams) } : moduleId - ? { ganttFetchKey: MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), ganttParams) } - : viewId - ? { ganttFetchKey: VIEW_ISSUES(viewId.toString(), viewGanttParams) } - : { ganttFetchKey: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId?.toString() ?? "", ganttParams) }; + ? { ganttFetchKey: MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), ganttParams) } + : viewId + ? { ganttFetchKey: VIEW_ISSUES(viewId.toString(), viewGanttParams) } + : { ganttFetchKey: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId?.toString() ?? "", ganttParams) }; return { ...ganttFetchKey, diff --git a/web/package.json b/web/package.json index 99e351191..bdd880ce1 100644 --- a/web/package.json +++ b/web/package.json @@ -33,7 +33,7 @@ "clsx": "^2.0.0", "cmdk": "^0.2.0", "date-fns": "^2.30.0", - "dompurify": "^3.0.9", + "dompurify": "^3.0.11", "dotenv": "^16.0.3", "js-cookie": "^3.0.1", "lodash": "^4.17.21", diff --git a/yarn.lock b/yarn.lock index c56d2280f..6f50b05ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2722,7 +2722,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@18.2.42", "@types/react@^18.2.42": +"@types/react@*", "@types/react@^18.2.42": version "18.2.42" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.42.tgz#6f6b11a904f6d96dda3c2920328a97011a00aba7" integrity sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA== @@ -4024,10 +4024,10 @@ dom4@^2.1.5: resolved "https://registry.yarnpkg.com/dom4/-/dom4-2.1.6.tgz#c90df07134aa0dbd81ed4d6ba1237b36fc164770" integrity sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA== -dompurify@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.9.tgz#b3f362f24b99f53498c75d43ecbd784b0b3ad65e" - integrity sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ== +dompurify@^3.0.11: + version "3.0.11" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.11.tgz#c163f5816eaac6aeef35dae2b77fca0504564efe" + integrity sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg== dot-case@^3.0.4: version "3.0.4" From 20795db9e85c2bb78bf4b23a5efba7d9d2cc8e35 Mon Sep 17 00:00:00 2001 From: Ramesh Kumar Chandra <31303617+rameshkumarchandra@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:19:55 +0530 Subject: [PATCH 37/53] chore: readme update (#4060) --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6834199ff..11db5ceba 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@

- Website • - Releases • - Twitter • - Documentation + Website • + Releases • + Twitter • + Documentation

@@ -40,15 +40,15 @@

-Meet [Plane](https://plane.so). An open-source software development tool to manage issues, sprints, and product roadmaps with peace of mind. 🧘‍♀️ +Meet [Plane](https://dub.sh/plane-website-readme). An open-source software development tool to manage issues, sprints, and product roadmaps with peace of mind. 🧘‍♀️ -> Plane is still in its early days, not everything will be perfect yet, and hiccups may happen. Please let us know of any suggestions, ideas, or bugs that you encounter on our [Discord](https://discord.com/invite/A92xrEGCge) or GitHub issues, and we will use your feedback to improve on our upcoming releases. +> Plane is still in its early days, not everything will be perfect yet, and hiccups may happen. Please let us know of any suggestions, ideas, or bugs that you encounter on our [Discord](https://discord.com/invite/A92xrEGCge) or GitHub issues, and we will use your feedback to improve in our upcoming releases. ## ⚡ Installation The easiest way to get started with Plane is by creating a [Plane Cloud](https://app.plane.so) account where we offer a hosted solution for users. -If you want more control over your data prefer to self-host Plane, please refer to our [deployment documentation](https://docs.plane.so/docker-compose). +If you want more control over your data, prefer to self-host Plane, please refer to our [deployment documentation](https://docs.plane.so/docker-compose). | Installation Methods | Documentation Link | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -59,9 +59,9 @@ If you want more control over your data prefer to self-host Plane, please refer ## 🚀 Features -- **Issues**: Quickly create issues and add details using a powerful, rich text editor that supports file uploads. Add sub-properties and references to problems for better organization and tracking. +- **Issues**: Quickly create issues and add details using a powerful rich text editor that supports file uploads. Add sub-properties and references to problems for better organization and tracking. -- **Cycles** +- **Cycles**: Keep up your team's momentum with Cycles. Gain insights into your project's progress with burn-down charts and other valuable features. - **Modules**: Break down your large projects into smaller, more manageable modules. Assign modules between teams to track and plan your project's progress easily. @@ -74,11 +74,11 @@ If you want more control over your data prefer to self-host Plane, please refer - **Drive** (_coming soon_): The drive helps you share documents, images, videos, or any other files that make sense to you or your team and align on the problem/solution. -## 🛠️ Contributors Quick Start +## 🛠️ Quick start for contributors > Development system must have docker engine installed and running. -Setting up local environment is extremely easy and straight forward. Follow the below step and you will be ready to contribute +Setting up local environment is extremely easy and straight forward. Follow the below step and you will be ready to contribute - 1. Clone the code locally using: ``` From 11c3d4fbd86047a6881529d38e7e1862f8a322c8 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:20:33 +0530 Subject: [PATCH 38/53] chore: issue reaction keys (#4061) Co-authored-by: NarayanBavisetti --- apiserver/plane/app/serializers/issue.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apiserver/plane/app/serializers/issue.py b/apiserver/plane/app/serializers/issue.py index 45f844cf0..fc0e6f838 100644 --- a/apiserver/plane/app/serializers/issue.py +++ b/apiserver/plane/app/serializers/issue.py @@ -533,8 +533,8 @@ class IssueReactionLiteSerializer(DynamicBaseSerializer): model = IssueReaction fields = [ "id", - "actor_id", - "issue_id", + "actor", + "issue", "reaction", ] From ad5559afe490a4efaa5ec08ebd9ce79cf33b3248 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:21:00 +0530 Subject: [PATCH 39/53] fix: peek overview delete modal (#4062) --- web/components/issues/peek-overview/view.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/components/issues/peek-overview/view.tsx b/web/components/issues/peek-overview/view.tsx index 3723627a9..35925d6cd 100644 --- a/web/components/issues/peek-overview/view.tsx +++ b/web/components/issues/peek-overview/view.tsx @@ -96,10 +96,9 @@ export const IssueView: FC = observer((props) => { isOpen={!!isDeleteIssueModalOpen} handleClose={() => { toggleDeleteIssueModal(null); - removeRoutePeekId(); }} data={issue} - onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId)} + onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId).then(() => removeRoutePeekId())} /> )} From 599809dd2ea8a4d2c22d3478e6231b12df2cc13e Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:59:28 +0530 Subject: [PATCH 40/53] chore: removed project from workspace estimate (#4064) --- apiserver/plane/app/views/workspace/estimate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/plane/app/views/workspace/estimate.py b/apiserver/plane/app/views/workspace/estimate.py index 6b64d8c90..fa75d5b88 100644 --- a/apiserver/plane/app/views/workspace/estimate.py +++ b/apiserver/plane/app/views/workspace/estimate.py @@ -31,7 +31,7 @@ class WorkspaceEstimatesEndpoint(BaseAPIView): Prefetch( "points", queryset=Project.objects.select_related( - "estimate", "workspace", "project" + "estimate", "workspace" ), ) ) From 7452e401347114d8a9309b2d4d8d1dc5f5503d3e Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:08:00 +0530 Subject: [PATCH 41/53] fix: optimize cycles endpoint for sql (#4065) --- apiserver/plane/app/views/cycle/base.py | 188 ++++++++++-------------- 1 file changed, 77 insertions(+), 111 deletions(-) diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index 3246b0997..48e475a74 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -1,56 +1,56 @@ # Python imports import json -# Django imports -from django.db.models import ( - Func, - F, - Q, - Exists, - OuterRef, - Count, - Prefetch, - Case, - When, - Value, - CharField, - Subquery, - IntegerField, -) -from django.utils import timezone from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.fields import ArrayField -from django.db.models import UUIDField + +# Django imports +from django.db.models import ( + Case, + CharField, + Count, + Exists, + F, + Func, + OuterRef, + Prefetch, + Q, + UUIDField, + Value, + When, +) from django.db.models.functions import Coalesce +from django.utils import timezone +from rest_framework import status # Third party imports from rest_framework.response import Response -from rest_framework import status -# Module imports -from .. import BaseViewSet, BaseAPIView, WebhookMixin -from plane.app.serializers import ( - CycleSerializer, - CycleFavoriteSerializer, - CycleWriteSerializer, - CycleUserPropertiesSerializer, -) from plane.app.permissions import ( ProjectEntityPermission, ProjectLitePermission, ) -from plane.db.models import ( - User, - Cycle, - CycleIssue, - Issue, - CycleFavorite, - Label, - CycleUserProperties, +from plane.app.serializers import ( + CycleFavoriteSerializer, + CycleSerializer, + CycleUserPropertiesSerializer, + CycleWriteSerializer, ) from plane.bgtasks.issue_activites_task import issue_activity +from plane.db.models import ( + Cycle, + CycleFavorite, + CycleIssue, + CycleUserProperties, + Issue, + Label, + User, +) from plane.utils.analytics_plot import burndown_plot +# Module imports +from .. import BaseAPIView, BaseViewSet, WebhookMixin + class CycleViewSet(WebhookMixin, BaseViewSet): serializer_class = CycleSerializer @@ -73,60 +73,6 @@ class CycleViewSet(WebhookMixin, BaseViewSet): project_id=self.kwargs.get("project_id"), workspace__slug=self.kwargs.get("slug"), ) - cancelled_issues = ( - Issue.issue_objects.filter( - state__group="cancelled", - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - completed_issues = ( - Issue.issue_objects.filter( - state__group="completed", - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - started_issues = ( - Issue.issue_objects.filter( - state__group="started", - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - unstarted_issues = ( - Issue.issue_objects.filter( - state__group="unstarted", - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - backlog_issues = ( - Issue.issue_objects.filter( - state__group="backlog", - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - total_issues = ( - Issue.issue_objects.filter( - issue_cycle__cycle_id=OuterRef("pk"), - ) - .values("issue_cycle__cycle_id") - .annotate(cnt=Count("pk")) - .values("cnt") - ) - return self.filter_queryset( super() .get_queryset() @@ -156,39 +102,62 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate(is_favorite=Exists(favorite_subquery)) .annotate( - completed_issues=Coalesce( - Subquery(completed_issues[:1]), - Value(0, output_field=IntegerField()), + total_issues=Count( + "issue_cycle", + filter=Q( + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( - cancelled_issues=Coalesce( - Subquery(cancelled_issues[:1]), - Value(0, output_field=IntegerField()), + completed_issues=Count( + "issue_cycle__issue__state__group", + filter=Q( + issue_cycle__issue__state__group="completed", + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( - started_issues=Coalesce( - Subquery(started_issues[:1]), - Value(0, output_field=IntegerField()), + cancelled_issues=Count( + "issue_cycle__issue__state__group", + filter=Q( + issue_cycle__issue__state__group="cancelled", + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( - unstarted_issues=Coalesce( - Subquery(unstarted_issues[:1]), - Value(0, output_field=IntegerField()), + started_issues=Count( + "issue_cycle__issue__state__group", + filter=Q( + issue_cycle__issue__state__group="started", + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( - backlog_issues=Coalesce( - Subquery(backlog_issues[:1]), - Value(0, output_field=IntegerField()), + unstarted_issues=Count( + "issue_cycle__issue__state__group", + filter=Q( + issue_cycle__issue__state__group="unstarted", + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( - total_issues=Coalesce( - Subquery(total_issues[:1]), - Value(0, output_field=IntegerField()), + backlog_issues=Count( + "issue_cycle__issue__state__group", + filter=Q( + issue_cycle__issue__state__group="backlog", + issue_cycle__issue__archived_at__isnull=True, + issue_cycle__issue__is_draft=False, + ), ) ) .annotate( @@ -217,9 +186,6 @@ class CycleViewSet(WebhookMixin, BaseViewSet): distinct=True, filter=~Q( issue_cycle__issue__assignees__id__isnull=True - ) - & Q( - issue_cycle__issue__assignees__member_project__is_active=True ), ), Value([], output_field=ArrayField(UUIDField())), @@ -384,8 +350,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): "external_id", "progress_snapshot", # meta fields - "total_issues", "is_favorite", + "total_issues", "cancelled_issues", "completed_issues", "started_issues", From ea728a385ff509e9ae15353ba2df9ec6cee278e6 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:13:26 +0530 Subject: [PATCH 42/53] [WEB-831] fix: sentry issue and code refactor (#4063) * chore: unnecessary console log removed * chore: in_use sentry issue resolved * chore: detail sentry issue resolved * fix: updated project logo validation in project icon --------- Co-authored-by: gurusainath --- web/components/command-palette/command-palette.tsx | 2 -- web/components/cycles/modal.tsx | 4 ++-- .../issues/issue-layouts/calendar/base-calendar-root.tsx | 2 +- .../issues/issue-layouts/kanban/base-kanban-root.tsx | 2 +- web/components/modules/modal.tsx | 4 ++-- web/components/project/create-project-form.tsx | 6 ++++-- web/components/project/form.tsx | 6 ++++-- web/components/project/project-logo.tsx | 6 +++--- web/components/views/modal.tsx | 2 +- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/web/components/command-palette/command-palette.tsx b/web/components/command-palette/command-palette.tsx index 8d162f6ab..490d392e2 100644 --- a/web/components/command-palette/command-palette.tsx +++ b/web/components/command-palette/command-palette.tsx @@ -113,8 +113,6 @@ export const CommandPalette: FC = observer(() => { const canPerformWorkspaceCreateActions = useCallback( (showToast: boolean = true) => { const isAllowed = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER; - console.log("currentWorkspaceRole", currentWorkspaceRole); - console.log("isAllowed", isAllowed); if (!isAllowed && showToast) setToast({ type: TOAST_TYPE.ERROR, diff --git a/web/components/cycles/modal.tsx b/web/components/cycles/modal.tsx index 008cdcbde..6ed53eb32 100644 --- a/web/components/cycles/modal.tsx +++ b/web/components/cycles/modal.tsx @@ -56,7 +56,7 @@ export const CycleCreateUpdateModal: React.FC = (props) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: err.detail ?? "Error in creating cycle. Please try again.", + message: err?.detail ?? "Error in creating cycle. Please try again.", }); captureCycleEvent({ eventName: CYCLE_CREATED, @@ -90,7 +90,7 @@ export const CycleCreateUpdateModal: React.FC = (props) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: err.detail ?? "Error in updating cycle. Please try again.", + message: err?.detail ?? "Error in updating cycle. Please try again.", }); }); }; diff --git a/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx b/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx index 9e54d2cf7..d5b263776 100644 --- a/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx +++ b/web/components/issues/issue-layouts/calendar/base-calendar-root.tsx @@ -73,7 +73,7 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => { setToast({ title: "Error", type: TOAST_TYPE.ERROR, - message: err.detail ?? "Failed to perform this action", + message: err?.detail ?? "Failed to perform this action", }); }); } diff --git a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx index 21e47c1cd..410430853 100644 --- a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx +++ b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx @@ -143,7 +143,7 @@ export const BaseKanBanRoot: React.FC = observer((props: IBas setToast({ title: "Error", type: TOAST_TYPE.ERROR, - message: err.detail ?? "Failed to perform this action", + message: err?.detail ?? "Failed to perform this action", }); }); } diff --git a/web/components/modules/modal.tsx b/web/components/modules/modal.tsx index 7242073b1..89ae7f321 100644 --- a/web/components/modules/modal.tsx +++ b/web/components/modules/modal.tsx @@ -68,7 +68,7 @@ export const CreateUpdateModuleModal: React.FC = observer((props) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: err.detail ?? "Module could not be created. Please try again.", + message: err?.detail ?? "Module could not be created. Please try again.", }); captureModuleEvent({ eventName: MODULE_CREATED, @@ -99,7 +99,7 @@ export const CreateUpdateModuleModal: React.FC = observer((props) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: err.detail ?? "Module could not be updated. Please try again.", + message: err?.detail ?? "Module could not be updated. Please try again.", }); captureModuleEvent({ eventName: MODULE_UPDATED, diff --git a/web/components/project/create-project-form.tsx b/web/components/project/create-project-form.tsx index a9d76210d..14d723e6d 100644 --- a/web/components/project/create-project-form.tsx +++ b/web/components/project/create-project-form.tsx @@ -209,8 +209,10 @@ export const CreateProjectForm: FC = observer((props) => { [val.type]: logoValue, }); }} - defaultIconColor={value.in_use === "icon" ? value.icon?.color : undefined} - defaultOpen={value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON} + defaultIconColor={value.in_use && value.in_use === "icon" ? value.icon?.color : undefined} + defaultOpen={ + value.in_use && value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON + } /> )} /> diff --git a/web/components/project/form.tsx b/web/components/project/form.tsx index aaaaf03b3..3e770a618 100644 --- a/web/components/project/form.tsx +++ b/web/components/project/form.tsx @@ -166,8 +166,10 @@ export const ProjectDetailsForm: FC = (props) => { [val.type]: logoValue, }); }} - defaultIconColor={value.in_use === "icon" ? value.icon?.color : undefined} - defaultOpen={value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON} + defaultIconColor={value?.in_use && value.in_use === "icon" ? value?.icon?.color : undefined} + defaultOpen={ + value.in_use && value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON + } disabled={!isAdmin} /> )} diff --git a/web/components/project/project-logo.tsx b/web/components/project/project-logo.tsx index c06dc3061..fc90fdba3 100644 --- a/web/components/project/project-logo.tsx +++ b/web/components/project/project-logo.tsx @@ -11,7 +11,7 @@ type Props = { export const ProjectLogo: React.FC = (props) => { const { className, logo } = props; - if (logo && logo.in_use === "icon" && logo.icon) + if (logo?.in_use === "icon" && logo?.icon) return ( = (props) => { ); - if (logo && logo.in_use === "emoji" && logo.emoji) + if (logo?.in_use === "emoji" && logo?.emoji) return ( {logo.emoji.value?.split("-").map((emoji) => String.fromCodePoint(parseInt(emoji, 10)))} ); - return ; + return <>; }; diff --git a/web/components/views/modal.tsx b/web/components/views/modal.tsx index c7b9c9a31..6e30a76ec 100644 --- a/web/components/views/modal.tsx +++ b/web/components/views/modal.tsx @@ -54,7 +54,7 @@ export const CreateUpdateProjectViewModal: FC = observer((props) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: err.detail ?? "Something went wrong. Please try again.", + message: err?.detail ?? "Something went wrong. Please try again.", }) ); }; From fb189ca447bc4904dabb3c04e406459aea8f745f Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:49:44 +0530 Subject: [PATCH 43/53] fix: cycle issue subquery filter when adding multiple assignees (#4066) --- apiserver/plane/app/views/cycle/base.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index 48e475a74..d323a0f63 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -103,7 +103,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): .annotate(is_favorite=Exists(favorite_subquery)) .annotate( total_issues=Count( - "issue_cycle", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__archived_at__isnull=True, issue_cycle__issue__is_draft=False, @@ -112,7 +113,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate( completed_issues=Count( - "issue_cycle__issue__state__group", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__state__group="completed", issue_cycle__issue__archived_at__isnull=True, @@ -122,7 +124,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate( cancelled_issues=Count( - "issue_cycle__issue__state__group", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__state__group="cancelled", issue_cycle__issue__archived_at__isnull=True, @@ -132,7 +135,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate( started_issues=Count( - "issue_cycle__issue__state__group", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__state__group="started", issue_cycle__issue__archived_at__isnull=True, @@ -142,7 +146,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate( unstarted_issues=Count( - "issue_cycle__issue__state__group", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__state__group="unstarted", issue_cycle__issue__archived_at__isnull=True, @@ -152,7 +157,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet): ) .annotate( backlog_issues=Count( - "issue_cycle__issue__state__group", + "issue_cycle__issue__id", + distinct=True, filter=Q( issue_cycle__issue__state__group="backlog", issue_cycle__issue__archived_at__isnull=True, From 51683e6b2f45c8df96a6f82dc41567d9e207924d Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:53:52 +0530 Subject: [PATCH 44/53] fix: active cycle stats empty state (#4067) --- web/components/cycles/active-cycle/cycle-stats.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/components/cycles/active-cycle/cycle-stats.tsx b/web/components/cycles/active-cycle/cycle-stats.tsx index fd4bc9318..2eb128763 100644 --- a/web/components/cycles/active-cycle/cycle-stats.tsx +++ b/web/components/cycles/active-cycle/cycle-stats.tsx @@ -201,7 +201,7 @@ export const ActiveCycleStats: FC = observer((props) => { as="div" className="flex h-52 w-full flex-col gap-1 overflow-y-auto text-custom-text-200 vertical-scrollbar scrollbar-sm" > - {cycleIssues.length > 0 ? ( + {cycle?.distribution?.assignees && cycle.distribution.assignees.length > 0 ? ( cycle.distribution?.assignees?.map((assignee, index) => { if (assignee.assignee_id) return ( @@ -246,8 +246,8 @@ export const ActiveCycleStats: FC = observer((props) => { as="div" className="flex h-52 w-full flex-col gap-1 overflow-y-auto text-custom-text-200 vertical-scrollbar scrollbar-sm" > - {cycleIssues.length > 0 ? ( - cycle.distribution?.labels?.map((label, index) => ( + {cycle?.distribution?.labels && cycle.distribution.labels.length > 0 ? ( + cycle.distribution.labels?.map((label, index) => ( Date: Tue, 26 Mar 2024 15:55:47 +0530 Subject: [PATCH 45/53] fix: adding workflow dispatch to codeql --- .github/workflows/codeql.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 92b44af5b..a858bcc59 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,6 +1,7 @@ name: "CodeQL" on: + workflow_dispatch: push: branches: ["master"] pull_request: From f3fd48dd431541bd3f1ee400023792a7e183930f Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:30:57 +0530 Subject: [PATCH 46/53] chore: image picker popover improvement (#4068) --- web/components/core/image-picker-popover.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/core/image-picker-popover.tsx b/web/components/core/image-picker-popover.tsx index 53e1179dc..1397039d1 100644 --- a/web/components/core/image-picker-popover.tsx +++ b/web/components/core/image-picker-popover.tsx @@ -144,7 +144,7 @@ export const ImagePickerPopover: React.FC = observer((props) => { useEffect(() => { if (!unsplashImages || value !== null) return; - onChange(unsplashImages[0].urls.regular); + onChange(unsplashImages[0]?.urls.regular); }, [value, onChange, unsplashImages]); const handleClose = () => { From 1c3619a4d6d7416e1a9206cafa937c6e3d509e1f Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:59:23 +0530 Subject: [PATCH 47/53] chore: workspace estimate project filter (#4070) --- apiserver/plane/app/views/workspace/estimate.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/apiserver/plane/app/views/workspace/estimate.py b/apiserver/plane/app/views/workspace/estimate.py index fa75d5b88..8ca24efd7 100644 --- a/apiserver/plane/app/views/workspace/estimate.py +++ b/apiserver/plane/app/views/workspace/estimate.py @@ -25,15 +25,11 @@ class WorkspaceEstimatesEndpoint(BaseAPIView): estimate_ids = Project.objects.filter( workspace__slug=slug, estimate__isnull=False ).values_list("estimate_id", flat=True) - estimates = Estimate.objects.filter( - pk__in=estimate_ids - ).prefetch_related( - Prefetch( - "points", - queryset=Project.objects.select_related( - "estimate", "workspace" - ), - ) + estimates = ( + Estimate.objects.filter(pk__in=estimate_ids, workspace__slug=slug) + .prefetch_related("points") + .select_related("workspace", "project") ) + serializer = WorkspaceEstimateSerializer(estimates, many=True) return Response(serializer.data, status=status.HTTP_200_OK) From 5235b78cb8f205ce8a6b7ad181f07ba24a1cddae Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Tue, 26 Mar 2024 19:24:42 +0530 Subject: [PATCH 48/53] fix: sentry config fixes --- space/next.config.js | 8 +- space/package.json | 2 +- turbo.json | 24 ++---- web/next.config.js | 8 +- web/package.json | 2 +- yarn.lock | 189 +++++++++++++++++++++++-------------------- 6 files changed, 120 insertions(+), 113 deletions(-) diff --git a/space/next.config.js b/space/next.config.js index 18b9275a1..b36368720 100644 --- a/space/next.config.js +++ b/space/next.config.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ /** @type {import('next').NextConfig} */ require("dotenv").config({ path: ".env" }); const { withSentryConfig } = require("@sentry/nextjs"); @@ -26,8 +27,11 @@ const nextConfig = { output: "standalone", }; -if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0")) { - module.exports = withSentryConfig(nextConfig, { silent: true }, { hideSourceMaps: true }); +if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0"), 10) { + module.exports = withSentryConfig(nextConfig, + { silent: true, authToken: process.env.SENTRY_AUTH_TOKEN }, + { hideSourceMaps: true } + ); } else { module.exports = nextConfig; } diff --git a/space/package.json b/space/package.json index 4951d5e30..3d6127edb 100644 --- a/space/package.json +++ b/space/package.json @@ -22,7 +22,7 @@ "@plane/rich-text-editor": "*", "@plane/types": "*", "@plane/ui": "*", - "@sentry/nextjs": "^7.85.0", + "@sentry/nextjs": "^7.108.0", "axios": "^1.3.4", "clsx": "^2.0.0", "dotenv": "^16.3.1", diff --git a/turbo.json b/turbo.json index 9302a7183..4e8c4ee81 100644 --- a/turbo.json +++ b/turbo.json @@ -17,37 +17,25 @@ "NEXT_PUBLIC_POSTHOG_KEY", "NEXT_PUBLIC_POSTHOG_HOST", "NEXT_PUBLIC_POSTHOG_DEBUG", - "JITSU_TRACKER_ACCESS_KEY", - "JITSU_TRACKER_HOST" + "SENTRY_AUTH_TOKEN" ], "pipeline": { "build": { - "dependsOn": [ - "^build" - ], - "outputs": [ - ".next/**", - "dist/**" - ] + "dependsOn": ["^build"], + "outputs": [".next/**", "dist/**"] }, "develop": { "cache": false, "persistent": true, - "dependsOn": [ - "^build" - ] + "dependsOn": ["^build"] }, "dev": { "cache": false, "persistent": true, - "dependsOn": [ - "^build" - ] + "dependsOn": ["^build"] }, "test": { - "dependsOn": [ - "^build" - ], + "dependsOn": ["^build"], "outputs": [] }, "lint": { diff --git a/web/next.config.js b/web/next.config.js index e018ea317..a7c658b59 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ require("dotenv").config({ path: ".env" }); const { withSentryConfig } = require("@sentry/nextjs"); @@ -24,8 +25,11 @@ const nextConfig = { output: "standalone", }; -if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0")) { - module.exports = withSentryConfig(nextConfig, { silent: true }, { hideSourceMaps: true }); +if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0"), 10) { + module.exports = withSentryConfig(nextConfig, + { silent: true, authToken: process.env.SENTRY_AUTH_TOKEN }, + { hideSourceMaps: true } + ); } else { module.exports = nextConfig; } diff --git a/web/package.json b/web/package.json index bdd880ce1..3ec941b80 100644 --- a/web/package.json +++ b/web/package.json @@ -28,7 +28,7 @@ "@plane/types": "*", "@plane/ui": "*", "@popperjs/core": "^2.11.8", - "@sentry/nextjs": "^7.85.0", + "@sentry/nextjs": "^7.108.0", "axios": "^1.1.3", "clsx": "^2.0.0", "cmdk": "^0.2.0", diff --git a/yarn.lock b/yarn.lock index 6f50b05ac..4442a5cd5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2149,35 +2149,46 @@ dependencies: "@daybrush/utils" "^1.4.0" -"@sentry-internal/feedback@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.91.0.tgz#be09e5aec2959fcf503e2cf78496d5e2d263bc5a" - integrity sha512-SJKTSaz68F5YIwF79EttBm915M2LnacgZMYRnRumyTmMKnebGhYQLwWbZdpaDvOa1U18dgRajDX8Qed/8A3tXw== +"@sentry-internal/feedback@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.108.0.tgz#7033352abd304f1383ec47640e056a0dfd5132b7" + integrity sha512-8JcgZEnk1uWrXJhsd3iRvFtEiVeaWOEhN0NZwhwQXHfvODqep6JtrkY1yCIyxbpA37aZmrPc2JhyotRERGfUjg== dependencies: - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" -"@sentry-internal/tracing@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.91.0.tgz#fbb6e1e3383e1eeee08633384e004da73ac1c37d" - integrity sha512-JH5y6gs6BS0its7WF2DhySu7nkhPDfZcdpAXldxzIlJpqFkuwQKLU5nkYJpiIyZz1NHYYtW5aum2bV2oCOdDRA== +"@sentry-internal/replay-canvas@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.108.0.tgz#641133c19c0e1c423617b8d791f53d6cd0b0a862" + integrity sha512-R5tvjGqWUV5vSk0N1eBgVW7wIADinrkfDEBZ9FyKP2mXHBobsyNGt30heJDEqYmVqluRqjU2NuIRapsnnrpGnA== dependencies: - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/core" "7.108.0" + "@sentry/replay" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" -"@sentry/browser@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.91.0.tgz#de3b9ae3ca7716a35cfabc97ac376944a67e6e34" - integrity sha512-lJv3x/xekzC/biiyAsVCioq2XnKNOZhI6jY3ZzLJZClYV8eKRi7D3KCsHRvMiCdGak1d/6sVp8F4NYY+YiWy1Q== +"@sentry-internal/tracing@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.108.0.tgz#d1e660701fb860cfae72b6ebfa8fb267533421fa" + integrity sha512-zuK5XsTsb+U+hgn3SPetYDAogrXsM16U/LLoMW7+TlC6UjlHGYQvmX3o+M2vntejoU1QZS8m1bCAZSMWEypAEw== dependencies: - "@sentry-internal/feedback" "7.91.0" - "@sentry-internal/tracing" "7.91.0" - "@sentry/core" "7.91.0" - "@sentry/replay" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" + +"@sentry/browser@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.108.0.tgz#b95810bb6572b63781f253615896f5afb1a3a5c0" + integrity sha512-FNpzsdTvGvdHJMUelqEouUXMZU7jC+dpN7CdT6IoHVVFEkoAgrjMVUhXZoQ/dmCkdKWHmFSQhJ8Fm6V+e9Aq0A== + dependencies: + "@sentry-internal/feedback" "7.108.0" + "@sentry-internal/replay-canvas" "7.108.0" + "@sentry-internal/tracing" "7.108.0" + "@sentry/core" "7.108.0" + "@sentry/replay" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" "@sentry/cli@^1.77.1": version "1.77.1" @@ -2191,95 +2202,95 @@ proxy-from-env "^1.1.0" which "^2.0.2" -"@sentry/core@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.91.0.tgz#229334d7f03dd5d90a17495e61ce4215ab730b2a" - integrity sha512-tu+gYq4JrTdrR+YSh5IVHF0fJi/Pi9y0HZ5H9HnYy+UMcXIotxf6hIEaC6ZKGeLWkGXffz2gKpQLe/g6vy/lPA== +"@sentry/core@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.108.0.tgz#a27e8d6f85f59c5730ce86071474f15ac899fde0" + integrity sha512-I/VNZCFgLASxHZaD0EtxZRM34WG9w2gozqgrKGNMzAymwmQ3K9g/1qmBy4e6iS3YRptb7J5UhQkZQHrcwBbjWQ== dependencies: - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" -"@sentry/integrations@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.91.0.tgz#b0496c9e404783bc433b1d2464d8f9aa180ebc8e" - integrity sha512-LGRfb+WfG3FaWHtDnJIhtupweat0imCQr2z/5SSbQKzqxHhtlaEU+9IExBmBdzq90n4lRBaVQHA3zGuU02uOhg== +"@sentry/integrations@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.108.0.tgz#307c61966208f2a126c1a93e712277c8f86a3d3c" + integrity sha512-b/WbK1f3x2rQ4aJJSA4VSwpBXrXFm1Nzrca3Y9qW0MI1wjZEYsDDrh9m6ulLdVBl4YDc2VqYp1COwU/NjuHlog== dependencies: - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" localforage "^1.8.1" -"@sentry/nextjs@^7.85.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.91.0.tgz#42eb3af10ff230e8a3fe9f0e50cdbac94b7d290e" - integrity sha512-wE83+OTEH4yYnDrhMw9eVEARSfZc6xY5qJb9xyYm5rW3+gVjNQZQaUY+wkM61Xdo0T35BN+7U4T88HbwzGeMqA== +"@sentry/nextjs@^7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.108.0.tgz#31d903d75bbf4b4530046360daff4d51dcf62f53" + integrity sha512-etBrMSLRbNAzozetBeL6D+lR9lRAyHmV7NUBGCX9lQvgmcdxkQa15EX8pIKjsMejZ8xAZNsqYVIByIs67A77rg== dependencies: "@rollup/plugin-commonjs" "24.0.0" - "@sentry/core" "7.91.0" - "@sentry/integrations" "7.91.0" - "@sentry/node" "7.91.0" - "@sentry/react" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" - "@sentry/vercel-edge" "7.91.0" + "@sentry/core" "7.108.0" + "@sentry/integrations" "7.108.0" + "@sentry/node" "7.108.0" + "@sentry/react" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" + "@sentry/vercel-edge" "7.108.0" "@sentry/webpack-plugin" "1.21.0" chalk "3.0.0" resolve "1.22.8" rollup "2.78.0" stacktrace-parser "^0.1.10" -"@sentry/node@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.91.0.tgz#26bf13c3daf988f9725afd1a3cc38ba2ff90d62a" - integrity sha512-hTIfSQxD7L+AKIqyjoq8CWBRkEQrrMZmA3GSZgPI5JFWBHgO0HBo5TH/8TU81oEJh6kqqHAl2ObMhmcnaFqlzg== +"@sentry/node@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.108.0.tgz#ed113dc1d39aaae32f7e9f681dcea41cf28eb5f1" + integrity sha512-pMxc9txnDDkU4Z8k2Uw/DPSLPehNtWV3mjJ3+my0AMORGYrXLkJI93tddlE5z/7k+GEJdj1HsOLgxUN0OU+HGA== dependencies: - "@sentry-internal/tracing" "7.91.0" - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" - https-proxy-agent "^5.0.0" + "@sentry-internal/tracing" "7.108.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" -"@sentry/react@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.91.0.tgz#620e6ce9452af025d2cc1b2eca3dd1dd730dc439" - integrity sha512-7JH2rWaX3WKHHvBcZQ4f/KnkYIXTf7hMojRFncUwPocdtDlhJw/JUvjAYNpEysixXIgsMes3B32lmtZjGjRhwQ== +"@sentry/react@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.108.0.tgz#26a50324f6d7a9576f3753c099e7bcd8def94f3c" + integrity sha512-C60arh5/gtO42eMU9l34aWlKDLZUO+1j1goaEf/XRSwUcyJS9tbJrs+mT4nbKxUsEG714It2gRbfSEvh1eXmCg== dependencies: - "@sentry/browser" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry/browser" "7.108.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" hoist-non-react-statics "^3.3.2" -"@sentry/replay@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.91.0.tgz#95077868aee3c3cc670affe13156434f858e1755" - integrity sha512-XwbesnLLNtaVXKtDoyBB96GxJuhGi9zy3a662Ba/McmumCnkXrMQYpQPh08U7MgkTyDRgjDwm7PXDhiKpcb03g== +"@sentry/replay@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.108.0.tgz#baa679bd19b4e3729e607d3f84cff5048aeb3415" + integrity sha512-jo8fDOzcZJclP1+4n9jUtVxTlBFT9hXwxhAMrhrt70FV/nfmCtYQMD3bzIj79nwbhUtFP6pN39JH1o7Xqt1hxQ== dependencies: - "@sentry-internal/tracing" "7.91.0" - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry-internal/tracing" "7.108.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" -"@sentry/types@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.91.0.tgz#5b68954e08986fecb0d4bef168df58eef62c32c7" - integrity sha512-bcQnb7J3P3equbCUc+sPuHog2Y47yGD2sCkzmnZBjvBT0Z1B4f36fI/5WjyZhTjLSiOdg3F2otwvikbMjmBDew== +"@sentry/types@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.108.0.tgz#5ceb959c4dabe511fc441fec8c2465f2d624900f" + integrity sha512-bKtHITmBN3kqtqE5eVvL8mY8znM05vEodENwRpcm6TSrrBjC2RnwNWVwGstYDdHpNfFuKwC8mLY9bgMJcENo8g== -"@sentry/utils@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.91.0.tgz#3b1a94c053c885877908cd3e1365e3d23e21a73f" - integrity sha512-fvxjrEbk6T6Otu++Ax9ntlQ0sGRiwSC179w68aC3u26Wr30FAIRKqHTCCdc2jyWk7Gd9uWRT/cq+g8NG/8BfSg== +"@sentry/utils@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.108.0.tgz#0231042956aed2ef35809891592238530349dfd9" + integrity sha512-a45yEFD5qtgZaIFRAcFkG8C8lnDzn6t4LfLXuV4OafGAy/3ZAN3XN8wDnrruHkiUezSSANGsLg3bXaLW/JLvJw== dependencies: - "@sentry/types" "7.91.0" + "@sentry/types" "7.108.0" -"@sentry/vercel-edge@7.91.0": - version "7.91.0" - resolved "https://registry.yarnpkg.com/@sentry/vercel-edge/-/vercel-edge-7.91.0.tgz#df67ee39d10570b71eccf831a181c064974d62b1" - integrity sha512-CounqhXPwFh67zf6L/q4ACBHHqknT6YY9LdgIAnUd0GGgHzrJPyKcthvh8Je4lNdpo5LFg2gnR+6g6JS8DDYDQ== +"@sentry/vercel-edge@7.108.0": + version "7.108.0" + resolved "https://registry.yarnpkg.com/@sentry/vercel-edge/-/vercel-edge-7.108.0.tgz#c5ca35094bc46029ec5a72f7ee09fd3705582baa" + integrity sha512-dUuUEswaVIzsJnzTfaJxrvkfOowrlJxxHo2AybPDym2rob7CdaLdDJIYJa83X7QeAKMkTgLny/gYSQYC0E4UyA== dependencies: - "@sentry-internal/tracing" "7.91.0" - "@sentry/core" "7.91.0" - "@sentry/types" "7.91.0" - "@sentry/utils" "7.91.0" + "@sentry-internal/tracing" "7.108.0" + "@sentry/core" "7.108.0" + "@sentry/types" "7.108.0" + "@sentry/utils" "7.108.0" "@sentry/webpack-plugin@1.21.0": version "1.21.0" From a1369311685bd00aa1173dfad1402e0c9ade7678 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Tue, 26 Mar 2024 19:40:48 +0530 Subject: [PATCH 49/53] fix: codeql workflow push and pull request chanages --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a858bcc59..d7b94d245 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -3,7 +3,7 @@ name: "CodeQL" on: workflow_dispatch: push: - branches: ["master"] + branches: ["develop", "preview", "master"] pull_request: branches: ["develop", "preview", "master"] schedule: From f3d9053d81727a2e5a2a13659d2dd7546de42425 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Tue, 26 Mar 2024 19:43:22 +0530 Subject: [PATCH 50/53] fix: unsafe external link fixes --- .../invitations/project_invitation.html | 2146 ++++++++++++++--- 1 file changed, 1806 insertions(+), 340 deletions(-) diff --git a/apiserver/templates/emails/invitations/project_invitation.html b/apiserver/templates/emails/invitations/project_invitation.html index 630a5eab3..def576601 100644 --- a/apiserver/templates/emails/invitations/project_invitation.html +++ b/apiserver/templates/emails/invitations/project_invitation.html @@ -1,349 +1,1815 @@ - - - - - - - {{ first_name }} invited you to join {{ project_name }} on Plane - - - - - - - - + + + + - - - - - - + + + + + + From 4c46b075b44480a87e2ec8ce7fc20fcb6dda0506 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:48:52 +0530 Subject: [PATCH 51/53] fix: module endpoint validations (#4071) --- apiserver/plane/app/views/module/base.py | 75 ++++++++++--------- .../plane/app/views/workspace/estimate.py | 9 +-- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/apiserver/plane/app/views/module/base.py b/apiserver/plane/app/views/module/base.py index 7769aee3f..3fe3a078a 100644 --- a/apiserver/plane/app/views/module/base.py +++ b/apiserver/plane/app/views/module/base.py @@ -1,54 +1,57 @@ # Python imports import json -# Django Imports -from django.utils import timezone -from django.db.models import ( - Prefetch, - F, - OuterRef, - Exists, - Count, - Q, - Func, - Subquery, - IntegerField, -) from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.fields import ArrayField -from django.db.models import Value, UUIDField +from django.db.models import ( + Count, + Exists, + F, + Func, + IntegerField, + OuterRef, + Prefetch, + Q, + Subquery, + UUIDField, + Value, +) from django.db.models.functions import Coalesce +# Django Imports +from django.utils import timezone +from rest_framework import status + # Third party imports from rest_framework.response import Response -from rest_framework import status -# Module imports -from .. import BaseViewSet, BaseAPIView, WebhookMixin -from plane.app.serializers import ( - ModuleWriteSerializer, - ModuleSerializer, - ModuleLinkSerializer, - ModuleFavoriteSerializer, - ModuleUserPropertiesSerializer, - ModuleDetailSerializer, -) from plane.app.permissions import ( ProjectEntityPermission, ProjectLitePermission, ) -from plane.db.models import ( - Module, - ModuleIssue, - Project, - Issue, - ModuleLink, - ModuleFavorite, - ModuleUserProperties, +from plane.app.serializers import ( + ModuleDetailSerializer, + ModuleFavoriteSerializer, + ModuleLinkSerializer, + ModuleSerializer, + ModuleUserPropertiesSerializer, + ModuleWriteSerializer, ) from plane.bgtasks.issue_activites_task import issue_activity +from plane.db.models import ( + Issue, + Module, + ModuleFavorite, + ModuleIssue, + ModuleLink, + ModuleUserProperties, + Project, +) from plane.utils.analytics_plot import burndown_plot +# Module imports +from .. import BaseAPIView, BaseViewSet, WebhookMixin + class ModuleViewSet(WebhookMixin, BaseViewSet): model = Module @@ -392,9 +395,11 @@ class ModuleViewSet(WebhookMixin, BaseViewSet): "completion_chart": {}, } - if queryset.first().start_date and queryset.first().target_date: + # Fetch the modules + modules = queryset.first() + if modules and modules.start_date and modules.target_date: data["distribution"]["completion_chart"] = burndown_plot( - queryset=queryset.first(), + queryset=modules, slug=slug, project_id=project_id, module_id=pk, diff --git a/apiserver/plane/app/views/workspace/estimate.py b/apiserver/plane/app/views/workspace/estimate.py index 8ca24efd7..59a23d867 100644 --- a/apiserver/plane/app/views/workspace/estimate.py +++ b/apiserver/plane/app/views/workspace/estimate.py @@ -3,15 +3,10 @@ from rest_framework import status from rest_framework.response import Response # Module imports +from plane.app.permissions import WorkspaceEntityPermission from plane.app.serializers import WorkspaceEstimateSerializer from plane.app.views.base import BaseAPIView -from plane.db.models import Project, Estimate -from plane.app.permissions import WorkspaceEntityPermission - -# Django imports -from django.db.models import ( - Prefetch, -) +from plane.db.models import Estimate, Project from plane.utils.cache import cache_response From 30cee781702a4354ad1fd44d5e23a74e26d380b1 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:38:25 +0530 Subject: [PATCH 52/53] dev: fix api security error (#4072) --- apiserver/plane/api/serializers/issue.py | 31 ++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/apiserver/plane/api/serializers/issue.py b/apiserver/plane/api/serializers/issue.py index b8f194b32..c78b109ef 100644 --- a/apiserver/plane/api/serializers/issue.py +++ b/apiserver/plane/api/serializers/issue.py @@ -1,32 +1,33 @@ -from lxml import html +from django.core.exceptions import ValidationError +from django.core.validators import URLValidator # Django imports from django.utils import timezone -from django.core.validators import URLValidator -from django.core.exceptions import ValidationError +from lxml import html # Third party imports from rest_framework import serializers # Module imports from plane.db.models import ( - User, Issue, - State, + IssueActivity, IssueAssignee, - Label, + IssueAttachment, + IssueComment, IssueLabel, IssueLink, - IssueComment, - IssueAttachment, - IssueActivity, + Label, ProjectMember, + State, + User, ) + from .base import BaseSerializer -from .cycle import CycleSerializer, CycleLiteSerializer -from .module import ModuleSerializer, ModuleLiteSerializer -from .user import UserLiteSerializer +from .cycle import CycleLiteSerializer, CycleSerializer +from .module import ModuleLiteSerializer, ModuleSerializer from .state import StateLiteSerializer +from .user import UserLiteSerializer class IssueSerializer(BaseSerializer): @@ -79,7 +80,7 @@ class IssueSerializer(BaseSerializer): data["description_html"] = parsed_str except Exception as e: - raise serializers.ValidationError(f"Invalid HTML: {str(e)}") + raise serializers.ValidationError("Invalid HTML passed") # Validate assignees are from project if data.get("assignees", []): @@ -294,7 +295,7 @@ class IssueLinkSerializer(BaseSerializer): raise serializers.ValidationError("Invalid URL format.") # Check URL scheme - if not value.startswith(('http://', 'https://')): + if not value.startswith(("http://", "https://")): raise serializers.ValidationError("Invalid URL scheme.") return value @@ -366,7 +367,7 @@ class IssueCommentSerializer(BaseSerializer): data["comment_html"] = parsed_str except Exception as e: - raise serializers.ValidationError(f"Invalid HTML: {str(e)}") + raise serializers.ValidationError("Invalid HTML passed") return data From 9249e6d5b9e66f28603b1e440104a91df87cac20 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:38:54 +0530 Subject: [PATCH 53/53] [WEB-849] fix: issue detail identifier and workspace settings (#4073) * fix: issue detail identifier * fix: workspace settings user role validation --- web/components/issues/issue-update-status.tsx | 5 +++-- web/layouts/settings-layout/workspace/sidebar.tsx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/components/issues/issue-update-status.tsx b/web/components/issues/issue-update-status.tsx index 277404dfa..a3a8ca83b 100644 --- a/web/components/issues/issue-update-status.tsx +++ b/web/components/issues/issue-update-status.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { observer } from "mobx-react"; import { RefreshCw } from "lucide-react"; import { TIssue } from "@plane/types"; // types @@ -9,7 +10,7 @@ type Props = { issueDetail?: TIssue; }; -export const IssueUpdateStatus: React.FC = (props) => { +export const IssueUpdateStatus: React.FC = observer((props) => { const { isSubmitting, issueDetail } = props; // hooks const { getProjectById } = useProject(); @@ -33,4 +34,4 @@ export const IssueUpdateStatus: React.FC = (props) => {
); -}; +}); diff --git a/web/layouts/settings-layout/workspace/sidebar.tsx b/web/layouts/settings-layout/workspace/sidebar.tsx index d6cb77cf9..f49eb84d9 100644 --- a/web/layouts/settings-layout/workspace/sidebar.tsx +++ b/web/layouts/settings-layout/workspace/sidebar.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { observer } from "mobx-react"; import Link from "next/link"; import { useRouter } from "next/router"; // hooks @@ -6,7 +7,7 @@ import { EUserWorkspaceRoles, WORKSPACE_SETTINGS_LINKS } from "@/constants/works import { useUser } from "@/hooks/store"; // constants -export const WorkspaceSettingsSidebar = () => { +export const WorkspaceSettingsSidebar = observer(() => { // router const router = useRouter(); const { workspaceSlug } = router.query; @@ -44,4 +45,4 @@ export const WorkspaceSettingsSidebar = () => {
); -}; +});