diff --git a/.github/workflows/frontend-deploy.yml b/.github/workflows/frontend-deploy.yml index 0d9d80be621..6e260251e57 100644 --- a/.github/workflows/frontend-deploy.yml +++ b/.github/workflows/frontend-deploy.yml @@ -126,6 +126,12 @@ jobs: BUILD_ENV: ${{ steps.meta.outputs.env }} PREVIEW: ${{ inputs.preview && 'true' || 'false' }} + - name: Disable server source map uploads for previews + if: ${{ inputs.preview }} + working-directory: ./apps/frontend + run: | + sed -i 's/"upload_source_maps": true/"upload_source_maps": false/g' wrangler.jsonc + - name: Install Wrangler CLI uses: cloudflare/wrangler-action@953926a2e2182532811c01a25e53647d93bf07c0 # v4.1.3 with: diff --git a/Cargo.lock b/Cargo.lock index 045a26a5e6f..9046d7f754f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -396,6 +396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "const-random", "getrandom 0.3.4", "once_cell", "version_check", @@ -2945,6 +2946,20 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "compact_str" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79fcda08c33bb58b97008b2cdada6622500e949e060f5913361763121abd2416" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "serde", + "static_assertions", + "zmij", +] + [[package]] name = "component-derive" version = "0.0.0" @@ -6785,6 +6800,7 @@ dependencies = [ "redis", "regex", "reqwest 0.13.5", + "rhai", "rust_decimal", "rust_iso3166", "rustls 0.23.46", @@ -6818,6 +6834,7 @@ dependencies = [ "url", "urlencoding", "utoipa", + "utoipa-actix-web", "uuid 1.28.0", "validator", "webauthn-rs", @@ -8524,6 +8541,15 @@ dependencies = [ "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +dependencies = [ + "spin 0.5.2", +] + [[package]] name = "no_std_io2" version = "0.9.4" @@ -11137,6 +11163,37 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "rhai" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3925b784c0bee6542637e425ed7511a63257bf11b7ecf51ffd845e2d24d9163" +dependencies = [ + "ahash", + "bitflags 2.13.2", + "compact_str 0.10.0", + "no-std-compat", + "num-traits", + "once_cell", + "rhai_codegen", + "serde", + "smallvec", + "smartstring", + "thin-vec", + "web-time", +] + +[[package]] +name = "rhai_codegen" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d9661edb4a4b8145b017582d634c5eb88ff1a5284a5aa701f83a28f0657a826" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "ring" version = "0.17.14" @@ -11539,7 +11596,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e80413b9a35e9d33217b3dcac04cf95f6559d15944b93887a08be5496c4a4" dependencies = [ - "compact_str", + "compact_str 0.7.1", ] [[package]] @@ -12399,6 +12456,17 @@ dependencies = [ "serde", ] +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "smol_str" version = "0.3.7" @@ -12492,6 +12560,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.9" @@ -13876,6 +13950,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "thin-vec" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a4b9ba8738cb4a4f399d37e266becfd475e75eb73425b87a05a2f2039ba63e" + [[package]] name = "thiserror" version = "1.0.69" @@ -15404,6 +15484,17 @@ dependencies = [ "utoipa-gen", ] +[[package]] +name = "utoipa-actix-web" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af2eb471d6791cfead324a893342eb73530d48bd37c485dd6296bc9fd8101ed" +dependencies = [ + "actix-service", + "actix-web", + "utoipa", +] + [[package]] name = "utoipa-gen" version = "6.0.1" diff --git a/Cargo.toml b/Cargo.toml index a6a0fe00e35..0f466dd01a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,6 +182,7 @@ redis = "1.7.1" regex = "1.13.1" reqwest = { version = "0.13.5", default-features = false, features = ["form", "query"] } rgb = "0.8.53" +rhai = "1.27.0" rust_decimal = { version = "1.43.0", features = ["serde-with-float", "serde-with-str"] } rust_iso3166 = "0.2.0" rust-s3 = { version = "0.38.0", default-features = false, features = [ @@ -263,6 +264,7 @@ unicode-segmentation = "1.13.3" url = "2.5.8" urlencoding = "2.1.3" utoipa = { version = "6.0.0", features = ["actix_extras", "chrono", "decimal"] } +utoipa-actix-web = "0.2.0" uuid = "1.28.0" validator = "0.21.0" webauthn-rs = "0.5.5" diff --git a/apps/frontend/src/components/project-review/flag-list/flag-card.vue b/apps/frontend/src/components/project-review/flag-list/flag-card.vue new file mode 100644 index 00000000000..38a597789d5 --- /dev/null +++ b/apps/frontend/src/components/project-review/flag-list/flag-card.vue @@ -0,0 +1,47 @@ + + + diff --git a/apps/frontend/src/components/project-review/flag-list/index.vue b/apps/frontend/src/components/project-review/flag-list/index.vue new file mode 100644 index 00000000000..b1b8167bbc0 --- /dev/null +++ b/apps/frontend/src/components/project-review/flag-list/index.vue @@ -0,0 +1,31 @@ + + + diff --git a/apps/frontend/src/components/project-review/index.vue b/apps/frontend/src/components/project-review/index.vue index a28cf5962d3..21672abb249 100644 --- a/apps/frontend/src/components/project-review/index.vue +++ b/apps/frontend/src/components/project-review/index.vue @@ -70,6 +70,7 @@ + @@ -105,6 +106,7 @@ import { import { isStaff } from '~/helpers/users.js' import { injectProjectReviewPageContext } from '~/providers/project-review' import { previousReviewLinkUrls } from '~/providers/project-review/project-links' +import { createReviewFlags, provideReviewFlags } from '~/providers/project-review/review-flags' import { createReviewMessages, provideReviewMessages, @@ -126,6 +128,7 @@ import { import Description from './description/index.vue' import Disclosures from './disclosures/index.vue' +import FlagList from './flag-list/index.vue' import Gallery from './gallery/index.vue' import IssueList from './issue-list/index.vue' import IssuePicker from './issue-list/issue-picker.vue' @@ -177,6 +180,7 @@ const visibleTabs = computed((previousTabs) => { ) }) const reviewProjectId = computed(() => project.value?.id) +const reviewFlags = provideReviewFlags(createReviewFlags(reviewProjectId)) const session = provideReviewSession(createReviewSession()) const settings = useModerationSettings() const panels = provideReviewPanels( @@ -298,6 +302,7 @@ const rightPanelTabs = computed(() => [ value: 'issues', label: `Issues (${issueCount.value})`, }, + { value: 'flags', label: `Flags (${reviewFlags.flags.value.length})` }, ]) watch( @@ -313,7 +318,12 @@ watch(projectId, () => { }) useShortcut('cycle-conversation', () => { - const tabs = ['issues', 'thread', ...(hasPreviousStructuredIssues.value ? ['re-review'] : [])] + const tabs = [ + 'issues', + 'flags', + 'thread', + ...(hasPreviousStructuredIssues.value ? ['re-review'] : []), + ] activeReviewTab.value = tabs[(tabs.indexOf(activeReviewTab.value) + 1) % tabs.length] shortcuts.run('reveal-right') }) diff --git a/apps/frontend/src/components/project-review/project-info/section.vue b/apps/frontend/src/components/project-review/project-info/section.vue index 556137c6943..cc5c98023f9 100644 --- a/apps/frontend/src/components/project-review/project-info/section.vue +++ b/apps/frontend/src/components/project-review/project-info/section.vue @@ -12,10 +12,11 @@
+
@@ -28,10 +29,12 @@ import { computed } from 'vue' import type { ReviewTarget } from '~/providers/project-review/review' +import { injectReviewFlags } from '~/providers/project-review/review-flags' import { injectReviewPanels } from '~/providers/project-review/review-panels' import { injectReviewPreviousIssues } from '~/providers/project-review/review-previous-issues' import FindingsCountBadge from '../review-panel/findings-count-badge.vue' +import FlagsCountBadge from '../review-panel/flags-count-badge.vue' import ReviewPanel from '../review-panel/index.vue' import ReReviewFindingsCountBadge from '../review-panel/re-review-findings-count-badge.vue' @@ -41,6 +44,11 @@ const props = defineProps<{ }>() const panels = injectReviewPanels() const previousIssues = injectReviewPreviousIssues() +const reviewFlags = injectReviewFlags(null) +const flagCount = computed(() => { + const binding = props.target ? panels.resolve(props.target) : undefined + return binding ? (reviewFlags?.forPanel(binding.key).length ?? 0) : 0 +}) const reReviewFindingCount = computed(() => { const binding = props.target ? panels.resolve(props.target) : undefined return binding ? previousIssues.reReviewFindingCount(binding) : 0 diff --git a/apps/frontend/src/components/project-review/review-panel/anchor.vue b/apps/frontend/src/components/project-review/review-panel/anchor.vue index 5634ba05012..99b15ee0c7b 100644 --- a/apps/frontend/src/components/project-review/review-panel/anchor.vue +++ b/apps/frontend/src/components/project-review/review-panel/anchor.vue @@ -19,6 +19,7 @@ >
+
@@ -37,6 +38,7 @@ import { injectReviewPreviousIssues } from '~/providers/project-review/review-pr import { injectReviewContext } from './context' import FindingsCountBadge from './findings-count-badge.vue' +import FlagsCountBadge from './flags-count-badge.vue' import Highlight from './highlight.vue' import ReReviewFindingsCountBadge from './re-review-findings-count-badge.vue' diff --git a/apps/frontend/src/components/project-review/review-panel/flags-count-badge.vue b/apps/frontend/src/components/project-review/review-panel/flags-count-badge.vue new file mode 100644 index 00000000000..76de6571820 --- /dev/null +++ b/apps/frontend/src/components/project-review/review-panel/flags-count-badge.vue @@ -0,0 +1,21 @@ + + + diff --git a/apps/frontend/src/components/project-review/review-panel/flags.vue b/apps/frontend/src/components/project-review/review-panel/flags.vue new file mode 100644 index 00000000000..74b0a9876ac --- /dev/null +++ b/apps/frontend/src/components/project-review/review-panel/flags.vue @@ -0,0 +1,56 @@ + + + diff --git a/apps/frontend/src/components/project-review/review-panel/index.vue b/apps/frontend/src/components/project-review/review-panel/index.vue index 455615302a4..b759f5eab0b 100644 --- a/apps/frontend/src/components/project-review/review-panel/index.vue +++ b/apps/frontend/src/components/project-review/review-panel/index.vue @@ -43,6 +43,7 @@ +