Compare commits

..
Author SHA1 Message Date
Aaryan Khandelwal f32458eb7b chore: add reload logic 2026-01-29 14:38:05 +05:30
Aaryan Khandelwal 5a31c6449d feat: comments draft 2026-01-29 13:29:56 +05:30
sriram veeraghantaandGitHub 02d0ee3e0f chore: add copyright (#8584)
* feat: adding new copyright info on all files

* chore: adding CI
2026-01-27 13:54:22 +05:30
Ship itandGitHub 66decf6617 fully translated into Ukrainian language (#8579) 2026-01-27 01:29:56 +05:30
Prateek ShouryaandGitHub 32a2584578 [GIT-66] improvement: prevent disabling last enabled authentication method (#8570) 2026-01-27 00:47:37 +05:30
SangeethaandGitHub f7d5200ed8 migration: back migrate all product tour fields to set true (#8575) 2026-01-27 00:47:02 +05:30
b31c0195bc fix: pdf export (#8564)
* feat: pdf export

* fix: tests

* fix: tests

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2026-01-26 22:08:10 +05:30
M. PalanikannanandGitHub 20e266c9bb fix: node view renders (#8559)
* fix node renders

* fix handlers

* fix: duplicate id
2026-01-23 13:47:49 +05:30
puntoandGitHub 57806f9bd5 [GIT-45] fix: allow markdown file attachments (#8524)
* fix: allow markdown file attachments

- Add text/markdown to ATTACHMENT_MIME_TYPES
- Fixes issue where .md files were rejected with 'Invalid file type' error

* added the support for frontend mime type too
2026-01-23 13:38:47 +05:30
Aaryan KhandelwalandGitHub db8b67102d [WEB-5860] [WEB-5861] [WEB-5862] style: improved settings interface (#8520)
* style: improved profile settings

* chore: minor improvements

* style: improved workspace settings

* style: workspace settings content

* style: improved project settings

* fix: project settings flat map

* chore: add back navigation from settings pages

* style: settings content

* style: estimates list

* refactor: remove old code

* refactor: removed unnecessary line breaks

* refactor: create a common component for page header

* chore: add fade-in animation to sidebar

* fix: formatting

* fix: project settings sidebar header

* fix: workspace settings sidebar header

* fix: settings content wrapper scroll

* chore: separate project settings features

* fix: formatting

* refactor: custom theme selector

* refactor: settings headings

* refactor: settings headings

* fix: project settings sidebar padding

* fix: sidebar header padding

* fix: sidebar item permissions

* fix: missing editable check

* refactor: remove unused files

* chore: remove unnecessary code

* chore: add missing translations

* fix: formatting
2026-01-23 13:34:20 +05:30
SangeethaandGitHub ba5ba5bf54 [GIT-61] chore: allow .md files to be uploaded (#8571)
* chore: allow .md files to be uploaded

* chore: allow .md files to be uploaded
2026-01-23 13:33:20 +05:30
yyandGitHub bb4f172e26 chore: fix typos in comments (#8553) 2026-01-23 13:32:04 +05:30
2a29ab8d4a [WEB-5845] chore: changing description field to description json (#8230)
* chore: migrating description to description json

* chore: replace description with description_json

* chore: updated migration file

* chore: updated the migration file

* chore: added description key in external endpoint

* chore: updated the migration file

* chore: updated the typo

---------

Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
2026-01-22 18:23:59 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6c8779c8d3 chore(deps): bump lodash-es in the npm_and_yarn group across 1 directory (#8573)
Bumps the npm_and_yarn group with 1 update in the / directory: [lodash-es](https://github.com/lodash/lodash).


Updates `lodash-es` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash-es
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-22 15:47:30 +05:30
Aaryan KhandelwalandGitHub f7debcde79 [WEB-5898] chore: update tailwind config #8516 2026-01-19 20:42:44 +05:30
Aaryan KhandelwalandGitHub 3de76206b5 [WIKI-735] fix: table insert handle z-index #8545 2026-01-19 20:41:50 +05:30
Vamsi KrishnaandGitHub f783447796 [WEB-5907] fix: magic code sign-in at Space app. #8552 2026-01-19 20:41:00 +05:30
SangeethaandGitHub fa1b4a102a [WEB-5890] migration: added getting_started_checklist, tips, explored_feature fields on the workspace member table (#8489)
* migration: added getting_started_checklist and tips field

* fix: remove defaults and added explored_features field

* fix: added user table migration
2026-01-15 14:25:31 +05:30
sriramveeraghanta 8399f64bee chore(deps): react router upgraded 2026-01-09 14:43:36 +05:30
Bavisetti NarayanandGitHub 5f3f9d2623 chore: updated migration file name (#8515) 2026-01-09 14:36:45 +05:30
Prateek ShouryaandGitHub 110dbd9acd [VPAT-50] chore(security): add X-Frame-Options header to nginx configuration to prevent clickjacking attacks (#8507)
* [VPAT-50] chore(security): add X-Frame-Options header to nginx configuration to prevent clickjacking attacks

* [SECURITY] chore: enhance nginx configuration with additional security headers
2026-01-09 04:03:41 +05:30
Vipin ChaudharyandGitHub b83d460938 [WIKI-826] chore: add unique id as key to logo selector (#8494) 2026-01-07 15:05:14 +05:30
ea1f92e0c6 [WEB-5537]refactor: rename IssueUserProperty to ProjectUserProperty and update related references (#8206)
* refactor: rename IssueUserProperty to ProjectUserProperty and update related references across the codebase

* migrate: move issue user properties to project user properties and update related fields and constraints

* refactor: rename IssueUserPropertySerializer and IssueUserDisplayPropertyEndpoint to ProjectUserPropertySerializer and ProjectUserDisplayPropertyEndpoint, updating all related references

* fix: enhance ProjectUserDisplayPropertyEndpoint to handle missing properties by creating new entries and improve response handling

* fix: correct formatting in migration for ProjectUserProperty model options

* migrate: add migration to update existing non-service API tokens to remove workspace association

* migrate: refine migration to update existing non-service API tokens by excluding bot users from workspace removal

* chore: changed the project sort order in project user property

* chore: remove allowed_rate_limit from APIToken

* chore: updated user-properties endpoint for frontend

* chore: removed the extra projectuserproperty

* chore: updated the migration file

* chore: code refactor

* fix: type error

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sangeethailango <sangeethailango21@gmail.com>
Co-authored-by: vamsikrishnamathala <matalav55@gmail.com>
Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2026-01-06 15:37:19 +05:30
Prateek ShouryaandGitHub 3d5e427894 chore: remove unused right sidebar component and clean up workspace member settings (#8477) 2025-12-31 00:08:40 +05:30
sriram veeraghantaandGitHub 6129e8e53b Revert "[WEB-4959]chore: refactor project member page #8464" (#8476)
This reverts commit c97e418515.
2025-12-30 21:46:32 +05:30
sriram veeraghantaandGitHub d61b157929 chore: remove posthog events (#8465)
* chore: remove posthog events

* chore: remove event tracking

* chore: lint errors

* chore: minor changes based on comments

* fix: type errors
2025-12-30 19:59:50 +05:30
NikhilandGitHub a37e5e2f6a [WEB-5598] refactor: streamline object creation in workspace seed task and improve error handling in workspace creation #8264 2025-12-30 17:28:33 +05:30
lifandGitHub a976bea5af fix: correct spelling error in database.ts log message (#8452)
Fix "convertion" -> "conversion" in error log message.

Signed-off-by: majiayu000 <1835304752@qq.com>
2025-12-30 17:23:42 +05:30
1072509642 migration: added webhook version, navigation related fields and allowed_rate_limit for APIToken (#8339)
* migration: added version field in webhook

* chore: add max_length

* chore: added product tour fields

* chore: updated the migration file

* chore: removed the duplicated migration file

* chore: added allowed_rate_limit for api_tokens

* chore: changed key feature tour to product tour

* chore: added is_subscribed_to_changelog field

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2025-12-30 16:18:58 +05:30
Jayash TripathyandGitHub dcd8d27eae [WEB-5472] refactor: project form #8472 2025-12-30 15:57:33 +05:30
b-saikrishnakanthandGitHub c97e418515 [WEB-4959]chore: refactor project member page #8464 2025-12-30 14:59:16 +05:30
Aaryan KhandelwalandGitHub 031baaa162 [WEB-857] regression: image uploader error state #8471 2025-12-30 14:35:52 +05:30
Jayash TripathyandGitHub 9141a9377f [WEB-5472] refactor: components of project creation flow (#8462) 2025-12-30 14:32:48 +05:30
Anmol Singh BhatiaandGitHub 866338289e chore: navigation preference enhancements (#8468) 2025-12-30 13:22:28 +05:30
Prateek ShouryaandGitHub 8d479ac24c [WEB-5822] fix: migrate ImagePickerPopover to Propel Tabs component and render only enabled tabs #8290
- Replace custom tab implementation with Propel Tabs
- Dynamically render only enabled tabs based on configuration
- Filter tabs by isEnabled property for cleaner conditional rendering
- Improve tab navigation and accessibility with Propel components
2025-12-29 19:54:32 +05:30
lifandGitHub 94d5779f3a chore: remove unused get_client_ip import (#8453)
Remove unused import `get_client_ip` from workspace/invite.py.
Identified by ruff linter (F401 error).

Signed-off-by: majiayu000 <1835304752@qq.com>
2025-12-29 18:39:54 +05:30
b-saikrishnakanthandGitHub 20492ffa75 [WEB-5790] feat: new email templates (#8423) 2025-12-29 16:17:29 +05:30
Anmol Singh BhatiaandGitHub 630d2b9600 [WEB-5179] chore: icon utils code refactor #8458 2025-12-29 13:31:27 +05:30
Shaikh NaasirandGitHub ec215bb3b1 Typo: database extension error message (#8461) 2025-12-29 13:26:09 +05:30
Bavisetti NarayanandGitHub 3241693d6d [WEB-5815] chore: removed the deleted states (#8457) 2025-12-26 20:28:33 +05:30
Aaryan KhandelwalandGitHub 6cc5c1946a regression: red and green color backgrounds (#8456) 2025-12-26 19:17:03 +05:30
Anmol Singh BhatiaandGitHub 2980c2d76b refactor: actions icon migration (#8219)
* chore: gitignore updated

* chore: check icon added to propel package

* feat: search icon migration

* chore: check icon migration

* chore: plus icon added to propel package

* chore: code refactor

* chore: plus icon migration and code refactor

* chore: trash icon added to propel package

* chore: code refactor

* chore: trash icon migration

* chore: edit icon added to propel package

* chore: new tab icon added to propel package

* chore: edit icon migration

* chore: newtab icon migration

* chore: lock icon added to propel package

* chore: lock icon migration

* chore: globe icon added to propel package

* chore: globe icon migration

* chore: copy icon added to propel package

* chore: copy icon migration

* chore: link icon added to propel package

* chore: link icon migration

* chore: link icon migration

* chore: info icon added to propel package

* chore: code refactor

* chore: code refactor

* chore: code refactor

* chore: code refactor
2025-12-26 17:19:15 +05:30
Aaryan KhandelwalandGitHub 92ac28fcb8 [WEB-5809] refactor: tailwind config inline variables (#8437) 2025-12-26 16:36:29 +05:30
Vamsi KrishnaandGitHub e3ba7c2889 [WEB-5781]chore: removed info banner for preferences #8442 2025-12-26 13:40:15 +05:30
Vamsi KrishnaandGitHub 78eeb9ce0d [WEB-5785]fix: favorites icon size #8449 2025-12-26 13:38:46 +05:30
Prateek ShouryaandGitHub f04be48f61 [WEB-5804] refactor: decouple filter value types from filter configurations (#8441)
* [WEB-5804] refactor: decouple filter value types from filter configurations

Remove value type constraints from filter configurations to support
operator-specific value types. Different operators can accept different
value types for the same filter property, so value types should be
determined at the operator level rather than the filter level.

- Remove generic value type parameter from TFilterConfig
- Update TOperatorConfigMap to accept union of all value types
- Simplify filter config factory signatures across all filter types
- Add forceUpdate parameter to updateConditionValue method

* refactor: remove filter value type constraints from filter configurations

Eliminate the generic value type parameter from filter configurations to allow for operator-specific value types. This change enhances flexibility by enabling different operators to accept various value types for the same filter property.

- Updated TFilterConfig and related interfaces to remove value type constraints
- Adjusted filter configuration methods and types accordingly
- Refactored date operator support to align with the new structure
2025-12-24 21:03:22 +05:30
Vamsi KrishnaandGitHub 5499e49b72 [WEB-5574]chore: notification card refactor (#8234)
* chore: notification card refactor

* chore: moved base activity types to constants package
2025-12-24 20:32:50 +05:30
Prateek ShouryaandGitHub 3c8624b1ba [WEB-5324] refactor: add Unified OAuth Configuration and Missing Gitea Options (#8050)
* refactor: add Unified OAuth Configuration and Missing Gitea Options

- Replaced the AuthenticationModes component with a more streamlined implementation using AuthenticationMethodCard.
- Removed obsolete authentication modes files from the codebase.
- Enhanced the AuthRoot component to utilize the new OAuth configuration hook for better management of authentication options.
- Updated type definitions for instance authentication modes to reflect the new structure.

* refactor: update OAuth type imports and remove obsolete types

- Replaced local type imports with centralized imports from @plane/types in core, extended, and index OAuth hooks.
- Removed the now redundant types.ts file as its definitions have been migrated.
- Enhanced type definitions for OAuth options to improve consistency across the application.

* feat: add new Gitea logo and update OAuth icon imports to use standard HTML img tags

* chore: remove unused authentication logos and upgrade button component
2025-12-24 20:20:12 +05:30
Anmol Singh BhatiaandGitHub 55c49cc633 [WEB-5808] chore: sidebar project list enhancements (#8451)
* chore: sidebar project list enhancements

* chore: code refactor

* chore: code refactor
2025-12-24 19:53:00 +05:30
Vamsi KrishnaandGitHub 5b28327551 [WEB-5782]chore: migrated modals to @plane/ui (#8420)
* chore: migrated modal to @plane/ui

* chore: fixed spacings
2025-12-24 19:45:55 +05:30
39728d4cc4 [WEB-5779] fix: handle loading state while fetching project cover image (#8419)
* refactor: replace cover image handling with CoverImage component across profile and project forms

* fix: extend CoverImage component to accept additional img props

* Update apps/web/core/components/common/cover-image.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: handle undefined cover image URL in ProfileSidebar component

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-24 19:30:01 +05:30
Bavisetti NarayanandGitHub 59f26a80bb [WEB-5667] fix: estimate value display in analytics #8448 2025-12-24 17:34:58 +05:30
SangeethaandGitHub 1a7c537ee5 [WEB-5791] fix: broken favicon in links (#8396)
* fix: using base url of a redirect url

* chore: internal networks check for the final_url

* fix: none final_url

* fix: exception handling

* fix: exception handling

* chore: remove unused imports

* refactor: moved ip address check logic into separate function

* fix: ValueError logic
2025-12-24 17:33:46 +05:30
Prateek ShouryaandGitHub 27a7cdcfc3 [WEB-5581] fix: resolve logo spinner hydration and theme loading issues (#8450)
- Fix hydration mismatch by lazy loading components that depend on theme
- Ensure LogoSpinner renders with correct theme on initial load
2025-12-24 17:29:27 +05:30
4224 changed files with 40690 additions and 17215 deletions
+45
View File
@@ -0,0 +1,45 @@
name: Copy Right Check
on:
workflow_dispatch:
pull_request:
branches:
- "preview"
types:
- "opened"
- "synchronize"
- "ready_for_review"
- "review_requested"
- "reopened"
jobs:
license-check:
name: Copy Right Check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: Install addlicense
run: |
go install github.com/google/addlicense@latest
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
- name: Check Copyright For Python Files
run: |
set -e
echo "Running copyright check..."
addlicense -check -f COPYRIGHT.txt -ignore "**/migrations/**" $(git ls-files '*.py')
echo "Copyright check passed."
- name: Check Copyright For TypeScript Files
run: |
set -e
echo "Running copyright check..."
addlicense -check -f COPYRIGHT.txt -ignore "**/*.config.ts" -ignore "**/*.d.ts" $(git ls-files '*.ts' '*.tsx')
echo "Copyright check passed."
+3
View File
@@ -0,0 +1,3 @@
Copyright (c) 2023-present Plane Software, Inc. and contributors
SPDX-License-Identifier: AGPL-3.0-only
See the LICENSE file for details.
+34
View File
@@ -0,0 +1,34 @@
## Copyright check
To verify that all tracked Python files contain the correct copyright header for **Plane Software Inc.** for the year **2023**, run this command from the repository root:
```bash
addlicense --check -f COPYRIGHT.txt -ignore "**/migrations/**" $(git ls-files '*.py')
```
#### To Apply Changes
python files
```bash
addlicense -v -f COPYRIGHT.txt -ignore "**/migrations/**" $(git ls-files '*.py')
```
ts and tsx files in a specific app
```bash
addlicense -v -f COPYRIGHT.txt \
-ignore "**/*.config.ts" \
-ignore "**/*.d.ts" \
$(git ls-files 'packages/*.ts')
```
Note: Please make sure ts command is running on specific folder, running it for the whole mono repo is crashing os processes.
#### Other Options
- **`addlicense -check`**: runs in check-only mode and fails if any file is missing or has an incorrect header.
- **`-c "Plane Software Inc."`**: sets the copyright holder.
- **`-f LICENSE.txt`**: uses the contents and format defined in `LICENSE.txt` as the header template.
- **`-y 2023`**: sets the year in the header.
- **`$(git ls-files '*.py')`**: restricts the check to Python files tracked in git.
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useForm } from "react-hook-form";
import { Lightbulb } from "lucide-react";
import { Button } from "@plane/propel/button";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import useSWR from "swr";
import { Loader } from "@plane/ui";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
@@ -1,16 +1,24 @@
import { useState } from "react";
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useCallback, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
import useSWR from "swr";
// plane internal packages
import { setPromiseToast } from "@plane/propel/toast";
import type { TInstanceConfigurationKeys } from "@plane/types";
import { setPromiseToast, setToast, TOAST_TYPE } from "@plane/propel/toast";
import type { TInstanceConfigurationKeys, TInstanceAuthenticationModes } from "@plane/types";
import { Loader, ToggleSwitch } from "@plane/ui";
import { cn, resolveGeneralTheme } from "@plane/utils";
// components
import { PageWrapper } from "@/components/common/page-wrapper";
// hooks
import { AuthenticationMethodCard } from "@/components/authentication/authentication-method-card";
// helpers
import { canDisableAuthMethod } from "@/helpers/authentication";
// hooks
import { useAuthenticationModes } from "@/hooks/oauth";
import { useInstance } from "@/hooks/store";
// types
@@ -19,48 +27,87 @@ import type { Route } from "./+types/page";
const InstanceAuthenticationPage = observer(function InstanceAuthenticationPage(_props: Route.ComponentProps) {
// theme
const { resolvedTheme: resolvedThemeAdmin } = useTheme();
// store
const { fetchInstanceConfigurations, formattedConfig, updateInstanceConfigurations } = useInstance();
const resolvedTheme = resolveGeneralTheme(resolvedThemeAdmin);
// Ref to store authentication modes for validation (avoids circular dependency)
const authenticationModesRef = useRef<TInstanceAuthenticationModes[]>([]);
// state
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
// store hooks
const { fetchInstanceConfigurations, formattedConfig, updateInstanceConfigurations } = useInstance();
// derived values
const enableSignUpConfig = formattedConfig?.ENABLE_SIGNUP ?? "";
const resolvedTheme = resolveGeneralTheme(resolvedThemeAdmin);
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
const updateConfig = async (key: TInstanceConfigurationKeys, value: string) => {
setIsSubmitting(true);
// Create updateConfig with validation - uses authenticationModesRef for current modes
const updateConfig = useCallback(
(key: TInstanceConfigurationKeys, value: string): void => {
// Check if trying to disable (value === "0")
if (value === "0") {
// Check if this key is an authentication method key
const currentAuthModes = authenticationModesRef.current;
const isAuthMethodKey = currentAuthModes.some((method) => method.enabledConfigKey === key);
const payload = {
[key]: value,
};
// Only validate if this is an authentication method key
if (isAuthMethodKey) {
const canDisable = canDisableAuthMethod(key, currentAuthModes, formattedConfig);
const updateConfigPromise = updateInstanceConfigurations(payload);
if (!canDisable) {
setToast({
type: TOAST_TYPE.ERROR,
title: "Cannot disable authentication",
message:
"At least one authentication method must remain enabled. Please enable another method before disabling this one.",
});
return;
}
}
}
setPromiseToast(updateConfigPromise, {
loading: "Saving configuration",
success: {
title: "Success",
message: () => "Configuration saved successfully",
},
error: {
title: "Error",
message: () => "Failed to save configuration",
},
});
// Proceed with the update
setIsSubmitting(true);
await updateConfigPromise
.then(() => {
setIsSubmitting(false);
})
.catch((err) => {
console.error(err);
setIsSubmitting(false);
const payload = {
[key]: value,
};
const updateConfigPromise = updateInstanceConfigurations(payload);
setPromiseToast(updateConfigPromise, {
loading: "Saving configuration",
success: {
title: "Success",
message: () => "Configuration saved successfully",
},
error: {
title: "Error",
message: () => "Failed to save configuration",
},
});
};
const authenticationModes = useAuthenticationModes({ disabled: isSubmitting, updateConfig, resolvedTheme });
void updateConfigPromise
.then(() => {
setIsSubmitting(false);
return undefined;
})
.catch((err) => {
console.error(err);
setIsSubmitting(false);
});
},
[formattedConfig, updateInstanceConfigurations]
);
// Get authentication modes - this will use updateConfig which includes validation
const authenticationModes = useAuthenticationModes({
disabled: isSubmitting,
updateConfig,
resolvedTheme,
});
// Update ref with latest authentication modes
authenticationModesRef.current = authenticationModes;
return (
<PageWrapper
header={{
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useMemo, useState } from "react";
import { useForm } from "react-hook-form";
// types
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
@@ -60,7 +66,7 @@ const InstanceEmailPage = observer(function InstanceEmailPage(_props: Route.Comp
Plane can send useful emails to you and your users from your own instance without talking to the Internet.
<div className="text-13 font-regular text-tertiary">
Set it up below and please test your settings before you save them.&nbsp;
<span className="text-danger">Misconfigs can lead to email bounces and errors.</span>
<span className="text-danger-primary">Misconfigs can lead to email bounces and errors.</span>
</div>
</>
),
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useState, Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
// plane imports
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import { Controller, useForm } from "react-hook-form";
import { Telescope } from "lucide-react";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
// components
import { PageWrapper } from "@/components/common/page-wrapper";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useForm } from "react-hook-form";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import useSWR from "swr";
import { Loader } from "@plane/ui";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect } from "react";
import { observer } from "mobx-react";
import { useRouter } from "next/navigation";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { Fragment, useEffect, useState } from "react";
import { observer } from "mobx-react";
import { useTheme as useNextTheme } from "next-themes";
@@ -1,11 +1,17 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState, useRef } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { ExternalLink, HelpCircle, MoveLeft } from "lucide-react";
import { HelpCircle, MoveLeft } from "lucide-react";
import { Transition } from "@headlessui/react";
// plane internal packages
import { WEB_BASE_URL } from "@plane/constants";
import { DiscordIcon, GithubIcon, PageIcon } from "@plane/propel/icons";
// plane internal packages
import { DiscordIcon, GithubIcon, NewTabIcon, PageIcon } from "@plane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
import { cn } from "@plane/utils";
// hooks
@@ -56,7 +62,7 @@ export const AdminSidebarHelpSection = observer(function AdminSidebarHelpSection
href={redirectionLink}
className={`relative px-2 py-1 flex items-center gap-1 rounded-sm bg-layer-1 text-body-xs-medium text-secondary whitespace-nowrap`}
>
<ExternalLink size={16} />
<NewTabIcon width={14} height={14} />
{!isSidebarCollapsed && "Redirect to Plane"}
</a>
</Tooltip>
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useRef } from "react";
import { observer } from "mobx-react";
// plane helpers
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
@@ -118,7 +124,7 @@ export function WorkspaceCreateForm() {
/>
)}
/>
<span className="text-11 text-red-500">{errors?.name?.message}</span>
<span className="text-11 text-danger-primary">{errors?.name?.message}</span>
</div>
</div>
<div className="flex flex-col gap-1">
@@ -153,11 +159,11 @@ export function WorkspaceCreateForm() {
)}
/>
</div>
{slugError && <p className="text-13 text-red-500">This URL is taken. Try something else.</p>}
{slugError && <p className="text-13 text-danger-primary">This URL is taken. Try something else.</p>}
{invalidSlug && (
<p className="text-13 text-red-500">{`URLs can contain only ( - ), ( _ ) and alphanumeric characters.`}</p>
<p className="text-13 text-danger-primary">{`URLs can contain only ( - ), ( _ ) and alphanumeric characters.`}</p>
)}
{errors.slug && <span className="text-11 text-red-500">{errors.slug.message}</span>}
{errors.slug && <span className="text-11 text-danger-primary">{errors.slug.message}</span>}
</div>
<div className="flex flex-col gap-1">
<h4 className="text-13 text-tertiary">How many people will use this workspace?</h4>
@@ -187,7 +193,7 @@ export function WorkspaceCreateForm() {
)}
/>
{errors.organization_size && (
<span className="text-13 text-red-500">{errors.organization_size.message}</span>
<span className="text-13 text-danger-primary">{errors.organization_size.message}</span>
)}
</div>
</div>
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
// components
import { PageWrapper } from "@/components/common/page-wrapper";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { Info } from "lucide-react";
// plane constants
import type { TAdminAuthErrorInfo } from "@plane/constants";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import Link from "next/link";
import { PlaneLockup } from "@plane/propel/icons";
+6 -64
View File
@@ -1,21 +1,13 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import Link from "next/link";
import { KeyRound, Mails } from "lucide-react";
// plane packages
import type { TAdminAuthErrorInfo } from "@plane/constants";
import { SUPPORT_EMAIL, EAdminAuthErrorCodes } from "@plane/constants";
import type { TGetBaseAuthenticationModeProps, TInstanceAuthenticationModes } from "@plane/types";
import { resolveGeneralTheme } from "@plane/utils";
// components
import githubLightModeImage from "@/app/assets/logos/github-black.png?url";
import githubDarkModeImage from "@/app/assets/logos/github-white.png?url";
import GitlabLogo from "@/app/assets/logos/gitlab-logo.svg?url";
import GoogleLogo from "@/app/assets/logos/google-logo.svg?url";
import { EmailCodesConfiguration } from "@/components/authentication/email-config-switch";
import { GithubConfiguration } from "@/components/authentication/github-config";
import { GitlabConfiguration } from "@/components/authentication/gitlab-config";
import { GoogleConfiguration } from "@/components/authentication/google-config";
import { PasswordLoginConfiguration } from "@/components/authentication/password-config-switch";
// images
export enum EErrorAlertType {
BANNER_ALERT = "BANNER_ALERT",
@@ -106,53 +98,3 @@ export const authErrorHandler = (errorCode: EAdminAuthErrorCodes, email?: string
return undefined;
};
export const getBaseAuthenticationModes: (props: TGetBaseAuthenticationModeProps) => TInstanceAuthenticationModes[] = ({
disabled,
updateConfig,
resolvedTheme,
}) => [
{
key: "unique-codes",
name: "Unique codes",
description:
"Log in or sign up for Plane using codes sent via email. You need to have set up SMTP to use this method.",
icon: <Mails className="h-6 w-6 p-0.5 text-tertiary" />,
config: <EmailCodesConfiguration disabled={disabled} updateConfig={updateConfig} />,
},
{
key: "passwords-login",
name: "Passwords",
description: "Allow members to create accounts with passwords and use it with their email addresses to sign in.",
icon: <KeyRound className="h-6 w-6 p-0.5 text-tertiary" />,
config: <PasswordLoginConfiguration disabled={disabled} updateConfig={updateConfig} />,
},
{
key: "google",
name: "Google",
description: "Allow members to log in or sign up for Plane with their Google accounts.",
icon: <img src={GoogleLogo} height={20} width={20} alt="Google Logo" />,
config: <GoogleConfiguration disabled={disabled} updateConfig={updateConfig} />,
},
{
key: "github",
name: "GitHub",
description: "Allow members to log in or sign up for Plane with their GitHub accounts.",
icon: (
<img
src={resolveGeneralTheme(resolvedTheme) === "dark" ? githubDarkModeImage : githubLightModeImage}
height={20}
width={20}
alt="GitHub Logo"
/>
),
config: <GithubConfiguration disabled={disabled} updateConfig={updateConfig} />,
},
{
key: "gitlab",
name: "GitLab",
description: "Allow members to log in or sign up to plane with their GitLab accounts.",
icon: <img src={GitlabLogo} height={20} width={20} alt="GitLab Logo" />,
config: <GitlabConfiguration disabled={disabled} updateConfig={updateConfig} />,
},
];
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect } from "react";
import { observer } from "mobx-react";
import { useRouter } from "next/navigation";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
// components
import { LogoSpinner } from "@/components/common/logo-spinner";
+8 -2
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { Eye, EyeOff } from "lucide-react";
@@ -129,7 +135,7 @@ export function InstanceSignInForm() {
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="email">
Email <span className="text-red-500">*</span>
Email <span className="text-danger-primary">*</span>
</label>
<Input
className="w-full border border-subtle !bg-surface-1 placeholder:text-placeholder"
@@ -147,7 +153,7 @@ export function InstanceSignInForm() {
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="password">
Password <span className="text-red-500">*</span>
Password <span className="text-danger-primary">*</span>
</label>
<div className="relative">
<Input
-11
View File
@@ -1,11 +0,0 @@
<svg width="92" height="84" viewBox="0 0 92 84" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3695_11896)">
<path d="M83.0398 32.6876C74.2901 27.2397 62.0735 23.8553 48.7013 23.8553C21.7918 23.8553 0 37.3101 0 53.9016C0 69.0898 18.1598 81.554 41.685 83.7001V74.9504C25.8364 72.9693 13.95 64.3022 13.95 53.9016C13.95 42.0977 29.4684 32.44 48.7013 32.44C58.2765 32.44 66.9436 34.8338 73.217 38.7134L64.3022 44.2439H92.1197V27.0746L83.0398 32.6876Z" fill="#CCCCCC"/>
<path d="M41.6846 8.99736V74.9504V83.7002L55.6346 74.9504V0L41.6846 8.99736Z" fill="#FF6200"/>
</g>
<defs>
<clipPath id="clip0_3695_11896">
<rect width="92" height="84" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 702 B

-17
View File
@@ -1,17 +0,0 @@
<svg width="700" height="650" viewBox="0 0 700 650" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3262_5767)">
<mask id="mask0_3262_5767" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="700" height="650">
<path d="M700 0H0V650H700V0Z" fill="white"/>
</mask>
<g mask="url(#mask0_3262_5767)">
<path d="M337.682 0L360.832 20.5C377.982 35.7 395.182 50.85 412.132 66.25C521.982 166 614.982 278.25 684.982 407.45C688.582 414.05 691.832 420.85 695.082 427.6L699.982 437.75L694.582 440.6L690.532 434.85L680.032 419.9L672.682 409.2C621.732 335.25 570.682 261.2 500.582 201.95C479.373 183.995 455.969 168.807 430.932 156.75C380.232 132.5 335.132 142.2 296.432 182C259.632 219.85 240.532 266.85 223.282 314.65C221.032 320.8 218.682 326.9 216.332 333L212.232 343.75L203.632 341C208.632 323.6 213.232 306.1 217.832 288.55C228.332 248.8 238.832 209.05 253.432 170.75C268.932 129.95 288.532 90.6 308.082 51.25C316.532 34.2 324.982 17.15 333.082 0H337.682Z" fill="#C22E33"/>
<path d="M372.382 491.1C291.082 529.6 94.3829 569.3 1.08287 559.1C-14.1671 478.8 135.482 102.5 208.982 45.5L204.232 56.4C202.115 61.531 199.813 66.5842 197.332 71.55L194.032 78C156.032 151.1 118.082 224.3 98.6329 304.5C91.6287 332.124 87.8038 360.458 87.2328 388.95C86.7328 455.95 128.432 501.55 198.082 504.4C231.582 505.75 265.432 502.25 299.232 498.7C313.932 497.2 328.582 495.65 343.232 494.5C348.632 494.1 353.932 493.45 360.832 492.55L372.382 491.15V491.1Z" fill="#C22E33"/>
<path d="M141.233 639.05C118.983 640.75 96.733 642.45 74.583 644.45C279.433 663.95 476.083 630.6 670.083 562.25C606.833 450.75 521.583 362.7 422.483 286.15C423.783 291.05 426.683 294.6 429.533 298.1L431.933 301.1C440.433 312.4 449.333 323.5 458.283 334.6C478.733 360.05 499.183 385.5 514.583 413.5C553.483 484.5 532.383 545.9 456.183 578.3C406.083 599.65 351.333 614.2 297.183 622.9C245.683 631.1 193.433 635.05 141.233 639.05Z" fill="#C22E33"/>
</g>
</g>
<defs>
<clipPath id="clip0_3262_5767">
<rect width="700" height="650" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
/**
* Ensures that a URL has a trailing slash while preserving query parameters and fragments
* @param url - The URL to process
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
// Minimal shim so code using next/image compiles under React Router + Vite
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import { Link as RRLink } from "react-router";
import { ensureTrailingSlash } from "./helper";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useMemo } from "react";
import { useLocation, useNavigate, useSearchParams as useSearchParamsRR } from "react-router";
import { ensureTrailingSlash } from "./helper";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import { Link } from "react-router";
// ui
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import * as Sentry from "@sentry/react-router";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { ReactNode } from "react";
import { Links, Meta, Outlet, Scripts } from "react-router";
import type { LinksFunction } from "react-router";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { index, layout, route } from "@react-router/dev/routes";
import type { RouteConfig } from "@react-router/dev/routes";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { enableStaticRendering } from "mobx-react";
// stores
import { CoreRootStore } from "@/store/root.store";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
// helpers
import { cn } from "@plane/utils";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import { observer } from "mobx-react";
// hooks
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
// icons
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
// icons
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
// icons
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
// icons
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import { observer } from "mobx-react";
// hooks
+12 -4
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { AlertCircle, CheckCircle2 } from "lucide-react";
type TBanner = {
@@ -10,20 +16,22 @@ export function Banner(props: TBanner) {
return (
<div
className={`rounded-md p-2 w-full border ${type === "error" ? "bg-red-500/5 border-red-400" : "bg-green-500/5 border-green-400"}`}
className={`rounded-md p-2 w-full border ${type === "error" ? "bg-danger-subtle border-danger-strong" : "bg-success-subtle border-success-strong"}`}
>
<div className="flex items-center justify-center">
<div className="flex-shrink-0">
{type === "error" ? (
<span className="flex items-center justify-center h-6 w-6 rounded-full">
<AlertCircle className="h-5 w-5 text-red-600" aria-hidden="true" />
<AlertCircle className="h-5 w-5 text-danger-primary" aria-hidden="true" />
</span>
) : (
<CheckCircle2 className="h-5 w-5 text-green-600" aria-hidden="true" />
<CheckCircle2 className="h-5 w-5 text-success-primary" aria-hidden="true" />
)}
</div>
<div className="ml-1">
<p className={`text-13 font-medium ${type === "error" ? "text-red-600" : "text-green-600"}`}>{message}</p>
<p className={`text-13 font-medium ${type === "error" ? "text-danger-primary" : "text-success-primary"}`}>
{message}
</p>
</div>
</div>
</div>
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import Link from "next/link";
import { Tooltip } from "@plane/propel/tooltip";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { cn } from "@plane/utils";
type TProps = {
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import Link from "next/link";
// headless ui
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React, { useState } from "react";
import type { Control } from "react-hook-form";
import { Controller } from "react-hook-form";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { Control, FieldPath, FieldValues } from "react-hook-form";
import { Controller } from "react-hook-form";
// plane internal packages
@@ -1,7 +1,13 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
// ui
import { Copy } from "lucide-react";
import { Button } from "@plane/propel/button";
import { CopyIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
type Props = {
@@ -37,7 +43,7 @@ export function CopyField(props: Props) {
}}
>
<p className="text-13 font-medium">{url}</p>
<Copy size={18} color="#B9B9B9" />
<CopyIcon width={18} height={18} color="#B9B9B9" />
</Button>
<div className="text-11 text-tertiary">{description}</div>
</div>
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import React from "react";
import { Button } from "@plane/propel/button";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export const CORE_HEADER_SEGMENT_LABELS: Record<string, string> = {
general: "General",
ai: "Artificial Intelligence",
@@ -1 +1,7 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export const EXTENDED_HEADER_SEGMENT_LABELS: Record<string, string> = {};
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import { usePathname } from "next/navigation";
import { Menu, Settings } from "lucide-react";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useTheme } from "next-themes";
import LogoSpinnerDark from "@/app/assets/images/logo-spinner-dark.gif?url";
import LogoSpinnerLight from "@/app/assets/images/logo-spinner-light.gif?url";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
type TPageHeader = {
title?: string;
description?: string;
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { ReactNode } from "react";
// plane imports
import { cn } from "@plane/utils";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
import { Button } from "@plane/propel/button";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export function FormHeader({ heading, subHeading }: { heading: string; subHeading: string }) {
return (
<div className="flex flex-col gap-1">
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import Link from "next/link";
import { Button } from "@plane/propel/button";
// assets
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useTheme } from "next-themes";
// assets
import LogoSpinnerDark from "@/app/assets/images/logo-spinner-dark.gif?url";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
// icons
@@ -157,7 +163,7 @@ export function InstanceSetupForm() {
<div className="flex flex-col sm:flex-row items-center gap-4">
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="first_name">
First name <span className="text-red-500">*</span>
First name <span className="text-danger-primary">*</span>
</label>
<Input
className="w-full border border-subtle !bg-surface-1 placeholder:text-placeholder"
@@ -174,7 +180,7 @@ export function InstanceSetupForm() {
</div>
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="last_name">
Last name <span className="text-red-500">*</span>
Last name <span className="text-danger-primary">*</span>
</label>
<Input
className="w-full border border-subtle !bg-surface-1 placeholder:text-placeholder"
@@ -192,7 +198,7 @@ export function InstanceSetupForm() {
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="email">
Email <span className="text-red-500">*</span>
Email <span className="text-danger-primary">*</span>
</label>
<Input
className="w-full border border-subtle !bg-surface-1 placeholder:text-placeholder"
@@ -207,13 +213,13 @@ export function InstanceSetupForm() {
autoComplete="on"
/>
{errorData.type && errorData.type === EErrorCodes.INVALID_EMAIL && errorData.message && (
<p className="px-1 text-11 text-red-500">{errorData.message}</p>
<p className="px-1 text-11 text-danger-primary">{errorData.message}</p>
)}
</div>
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="company_name">
Company name <span className="text-red-500">*</span>
Company name <span className="text-danger-primary">*</span>
</label>
<Input
className="w-full border border-subtle !bg-surface-1 placeholder:text-placeholder"
@@ -229,7 +235,7 @@ export function InstanceSetupForm() {
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="password">
Set a password <span className="text-red-500">*</span>
Set a password <span className="text-danger-primary">*</span>
</label>
<div className="relative">
<Input
@@ -267,14 +273,14 @@ export function InstanceSetupForm() {
)}
</div>
{errorData.type && errorData.type === EErrorCodes.INVALID_PASSWORD && errorData.message && (
<p className="px-1 text-11 text-red-500">{errorData.message}</p>
<p className="px-1 text-11 text-danger-primary">{errorData.message}</p>
)}
<PasswordStrengthIndicator password={formData.password} isFocused={isPasswordInputFocused} />
</div>
<div className="w-full space-y-1">
<label className="text-13 text-tertiary font-medium" htmlFor="confirm_password">
Confirm password <span className="text-red-500">*</span>
Confirm password <span className="text-danger-primary">*</span>
</label>
<div className="relative">
<Input
@@ -311,7 +317,9 @@ export function InstanceSetupForm() {
</div>
{!!formData.confirm_password &&
formData.password !== formData.confirm_password &&
renderPasswordMatchError && <span className="text-13 text-red-500">Passwords don{"'"}t match</span>}
renderPasswordMatchError && (
<span className="text-13 text-danger-primary">Passwords don{"'"}t match</span>
)}
</div>
<div className="relative flex gap-2">
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import Link from "next/link";
import { useTheme as useNextTheme } from "next-themes";
@@ -1,7 +1,14 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import { ExternalLink } from "lucide-react";
// plane internal packages
import { WEB_BASE_URL } from "@plane/constants";
import { NewTabIcon } from "@plane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
import { getFileURL } from "@plane/utils";
// hooks
@@ -75,7 +82,7 @@ export const WorkspaceListItem = observer(function WorkspaceListItem({ workspace
</div>
</div>
<div className="flex-shrink-0">
<ExternalLink size={16} className="text-placeholder group-hover:text-secondary" />
<NewTabIcon width={14} height={16} className="text-placeholder group-hover:text-secondary" />
</div>
</a>
);
+36
View File
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type {
IFormattedInstanceConfiguration,
TInstanceAuthenticationModes,
TInstanceConfigurationKeys,
} from "@plane/types";
/**
* Checks if a given authentication method can be disabled.
* @param configKey - The configuration key to check.
* @param authModes - The authentication modes to check.
* @param formattedConfig - The formatted configuration to check.
* @returns True if the authentication method can be disabled, false otherwise.
*/
export const canDisableAuthMethod = (
configKey: TInstanceConfigurationKeys,
authModes: TInstanceAuthenticationModes[],
formattedConfig: IFormattedInstanceConfiguration | undefined
): boolean => {
// Count currently enabled methods
const enabledCount = authModes.reduce((count, method) => {
const enabledKey = method.enabledConfigKey;
if (!enabledKey || !formattedConfig) return count;
const isEnabled = Boolean(parseInt(formattedConfig[enabledKey] ?? "0"));
return isEnabled ? count + 1 : count;
}, 0);
// If trying to disable and only 1 method is enabled, prevent it
const isCurrentlyEnabled = Boolean(parseInt(formattedConfig?.[configKey] ?? "0"));
return !(isCurrentlyEnabled && enabledCount === 1);
};
+12
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { KeyRound, Mails } from "lucide-react";
// types
import type {
@@ -34,6 +40,7 @@ export const getCoreAuthenticationModesMap: (
"Log in or sign up for Plane using codes sent via email. You need to have set up SMTP to use this method.",
icon: <Mails className="h-6 w-6 p-0.5 text-tertiary" />,
config: <EmailCodesConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "ENABLE_MAGIC_LINK_LOGIN",
},
"passwords-login": {
key: "passwords-login",
@@ -41,6 +48,7 @@ export const getCoreAuthenticationModesMap: (
description: "Allow members to create accounts with passwords and use it with their email addresses to sign in.",
icon: <KeyRound className="h-6 w-6 p-0.5 text-tertiary" />,
config: <PasswordLoginConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "ENABLE_EMAIL_PASSWORD",
},
google: {
key: "google",
@@ -48,6 +56,7 @@ export const getCoreAuthenticationModesMap: (
description: "Allow members to log in or sign up for Plane with their Google accounts.",
icon: <img src={googleLogo} height={20} width={20} alt="Google Logo" />,
config: <GoogleConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "IS_GOOGLE_ENABLED",
},
github: {
key: "github",
@@ -62,6 +71,7 @@ export const getCoreAuthenticationModesMap: (
/>
),
config: <GithubConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "IS_GITHUB_ENABLED",
},
gitlab: {
key: "gitlab",
@@ -69,6 +79,7 @@ export const getCoreAuthenticationModesMap: (
description: "Allow members to log in or sign up to plane with their GitLab accounts.",
icon: <img src={gitlabLogo} height={20} width={20} alt="GitLab Logo" />,
config: <GitlabConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "IS_GITLAB_ENABLED",
},
gitea: {
key: "gitea",
@@ -76,5 +87,6 @@ export const getCoreAuthenticationModesMap: (
description: "Allow members to log in or sign up to plane with their Gitea accounts.",
icon: <img src={giteaLogo} height={20} width={20} alt="Gitea Logo" />,
config: <GiteaConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "IS_GITEA_ENABLED",
},
});
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { TInstanceAuthenticationModes } from "@plane/types";
import { getCoreAuthenticationModesMap } from "./core";
import type { TGetAuthenticationModeProps } from "./types";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { TInstanceAuthenticationMethodKeys } from "@plane/types";
export type TGetAuthenticationModeProps = {
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export * from "./use-theme";
export * from "./use-instance";
export * from "./use-user";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useContext } from "react";
// store
import { StoreContext } from "@/providers/store.provider";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useContext } from "react";
// store
import { StoreContext } from "@/providers/store.provider";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useContext } from "react";
// store
import { StoreContext } from "@/providers/store.provider";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useContext } from "react";
// store
import { StoreContext } from "@/providers/store.provider";
@@ -1,6 +1,12 @@
import { Image, BrainCog, Cog, Lock, Mail } from "lucide-react";
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { Image, BrainCog, Cog, Mail } from "lucide-react";
// plane imports
import { WorkspaceIcon } from "@plane/propel/icons";
import { LockIcon, WorkspaceIcon } from "@plane/propel/icons";
// types
import type { TSidebarMenuItem } from "./types";
@@ -26,7 +32,7 @@ export const coreSidebarMenuLinks: Record<TCoreSidebarMenuKey, TSidebarMenuItem>
href: `/workspace/`,
},
authentication: {
Icon: Lock,
Icon: LockIcon,
name: "Authentication",
description: "Configure authentication modes.",
href: `/authentication/`,
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
// local imports
import { coreSidebarMenuLinks } from "./core";
import type { TSidebarMenuItem } from "./types";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { LucideIcon } from "lucide-react";
export type TSidebarMenuItem = {
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect, useRef } from "react";
import { BProgress } from "@bprogress/core";
import { useNavigation } from "react-router";
+6
View File
@@ -1 +1,7 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export * from "./AppProgressBar";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { ThemeProvider } from "next-themes";
import { SWRConfig } from "swr";
import { AppProgressBar } from "@/lib/b-progress";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export function ExtendedProviders({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { CoreProviders } from "./core";
import { ExtendedProviders } from "./extended";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
import useSWR from "swr";
// hooks
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { createContext } from "react";
// plane admin store
import { RootStore } from "@/plane-admin/store/root.store";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useTheme } from "next-themes";
import { Toast } from "@plane/propel/toast";
import { resolveGeneralTheme } from "@plane/utils";
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { set } from "lodash-es";
import { observable, action, computed, makeObservable, runInAction } from "mobx";
// plane internal packages
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { enableStaticRendering } from "mobx-react";
// stores
import type { IInstanceStore } from "./instance.store";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { action, observable, makeObservable } from "mobx";
// root store
import type { CoreRootStore } from "@/store/root.store";
+6
View File
@@ -1,3 +1,9 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { action, observable, runInAction, makeObservable } from "mobx";
// plane internal packages
import type { TUserStatus } from "@plane/constants";

Some files were not shown because too many files have changed in this diff Show More