-
-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/s3 file browser v1 #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dklOrdix
wants to merge
178
commits into
main
Choose a base branch
from
feat/s3-file-browser-v1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
178 commits
Select commit
Hold shift + click to select a range
161ce0e
refactor(frontend): clean up and restructure app
dklOrdix d2de208
fix: add lint:fix script to package.json and clean up trailing comma …
dklOrdix c81b4d0
docs: update AGENTS.md to include Material UI icon library usage
dklOrdix 9add069
refactor(header): move components for header into own directory
dklOrdix 8343022
chore: dedupe lockfile
dklOrdix 4bc8e93
fix(sidebar): add hover cursor style to toggle button
dklOrdix 952dc80
chore(types): centralise navigation and auth types; update header/sid…
dklOrdix cba7866
feat(storage): initial Filebrowser UI implementation
dklOrdix 5de8d9f
refactor(storage): extract service layer and consolidate storage type…
dklOrdix 20909ae
Merge branch 'feat/s3-file-browser' into feat/s3-file-browser-ui
dklOrdix 2b33533
chore(storage): remove outdated STORAGE_REORG_PLAN.md
dklOrdix aeac85d
fix(lint): resolve errors
dklOrdix f2ba284
refactor(tests): update ThemeToggle tests to use checkbox role
dklOrdix af9b651
style: format code
dklOrdix 8373974
fix(tests): update theme toggle role from button to checkbox
dklOrdix 7aff59b
fix: revert changes to Theme Toggle
dklOrdix 266a045
fix: revert changes to Theme Toggle
dklOrdix 805f693
Merge pull request #90 from stackabletech/feat/s3-file-browser-ui
dklOrdix 3386182
#80 use pagination controls to navigate the file browser
F3l1x1vo b77bcfa
#80 show page counter for pagination control
F3l1x1vo 48b552e
#80 fix lint and svelte check
F3l1x1vo 7c9733f
fix lint error
F3l1x1vo 9d85f57
Merge pull request #100 from stackabletech/feat/s3-file-browser-pagin…
F3l1x1vo b4e25ec
File Browser: Feature Flag (#105)
F3l1x1vo c36f1c8
Rename option STACKABLE_UI_COMPLETION_DISABLED (#106)
F3l1x1vo ff43b22
S3 File Browser: Shared Pagination Component (#103)
F3l1x1vo ed9be69
Merge branch 'main' into feat/s3-file-browser
dklOrdix 21bb0f2
#93 S3 File Browser: Document Preview (#113)
F3l1x1vo 184fa84
Feat/s3 file browser refactor object table (#120)
dklOrdix 8886814
#91 - Feat/s3 filebrowser downloads (#116)
dklOrdix d8e7d2a
#121 check multiselect checkbox on ctrl click to enable multiselect (…
F3l1x1vo 3f5231b
#144 remove trailing slash on directory name
F3l1x1vo 5f8c739
#94 S3 File Browser: Delete Action (#137)
F3l1x1vo 0342366
#118 S3 File Browser: Pinned and Recent Access (#126)
F3l1x1vo 079cee9
#140 Add tooltips to BucketList (#145)
dklOrdix 567da57
#108 Store S3 Bucket Credentials in localStorage (#117)
F3l1x1vo 7625c66
#146 Bugfix: Deleting Directories (#147)
F3l1x1vo 45f61ef
#138 add svelte best practices (#139)
F3l1x1vo d7ed9d0
chore: remove package duplicates with npm dedupe
dklOrdix 1b37cfd
feat: Add support for path-style and VirtualHosted addressing in S3 c…
dklOrdix 110d588
#92 S3 File Browser: Upload (#141)
dklOrdix b02c803
chore: remove package duplicates with npm dedupe
dklOrdix 98500e5
#130 improve various ux issues from this ticket (#150)
F3l1x1vo 7d50dbd
Filebrowser: Refactor Filebrowser by using global state (#163)
dklOrdix 2d81027
#135 Add s3 Garage instance for e2e tests (#162)
F3l1x1vo 134b88f
#135 Add E2E Tests to S3 File Browser (#166)
F3l1x1vo b6ab288
#93 fix non translated error message, #89 remove unnecessary key handler
F3l1x1vo d3aecd6
Feat/add component tests (#170)
dklOrdix 6ac766e
#94 #118 bugfix deleting a path removes it from recent access (#174)
F3l1x1vo 4daae3a
#154 Add Refresh Button (#169)
F3l1x1vo de1aa62
#127 Env Variables for Preview Limits, Recent Items, Page Size (#177)
F3l1x1vo c14d734
Merge remote-tracking branch 'origin/main' into feat/s3-file-browser
dklOrdix bf13b71
#185 move saved s3 connection from backend to frontend
F3l1x1vo 6ea6b16
#185 update e2e tests for browser connections
F3l1x1vo c07a3bc
#185 fix unit test
F3l1x1vo 3dbcd2b
#185 fix lint
F3l1x1vo 028b416
Filebrowser: Rename Stackable UI to Stackable Cockpit (#191)
F3l1x1vo 99e7d62
#185 move request handling to middleware
F3l1x1vo b7197b7
Merge branch 'feat/file-browser-save-connection-in-browser' into refa…
dklOrdix e4b8b84
refactor: move service logic into StorageProvider interface and imple…
dklOrdix 54971d2
merge: origin/feat/file-browser-save-connection-in-browser — use loca…
dklOrdix 739fbdb
refactor: rename listBuckets to listContainers across storage provide…
dklOrdix 265654a
refactor: centralize S3 error handling with withS3Errors function
dklOrdix f8e7f2d
#185 Save Connection in Browser (#189)
F3l1x1vo f2b9111
Merge branch 'feat/s3-file-browser' into refactor/service-into-storag…
dklOrdix 80b75d5
#79 implement all requested changes
F3l1x1vo d82cbe1
Merge origin/main into feat/s3-file-browser
Copilot 9abd491
#79 revert remove mobile e2e tests, fix mobile tests
F3l1x1vo dae8f8e
feat(database): integrate Drizzle ORM with PostgreSQL 18 (#200)
dklOrdix 7878805
Merge branch 'feat/s3-file-browser' into feat/s3-file-browser-v1
dklOrdix 04758db
Feat/more file icons (#197)
dklOrdix f390bb7
#98 simplified garage access key retrieval
F3l1x1vo 7902156
fix format on templates
F3l1x1vo 78b6446
#98 fix limiting deleting keys, reset pagination on bucket switch
F3l1x1vo bf20c7c
#98 fix pagination inside the same bucket
F3l1x1vo 87f9a1c
add svelte check to lint command
F3l1x1vo 44791d0
#153 Allow Upload of Empty Files (#171)
F3l1x1vo d8d9d68
Merge remote-tracking branch 'origin/feat/s3-file-browser' into feat/…
Copilot 9a96d47
update lock
F3l1x1vo b7aad81
#98 swap order of action and selection bar
F3l1x1vo 17ed09c
#98 allow for resizing sidebar
F3l1x1vo e0c6aa0
#98 add copy path and full path actions
F3l1x1vo 079638e
#98 close modals by clicking outside of them
F3l1x1vo 0a4f465
#98 add disconnect confirmation box
F3l1x1vo 433a41f
#98 move api paths to /<app>/api
F3l1x1vo 42709ea
#98 add skip and replace all buttons for upload conflicts
F3l1x1vo cbe1c15
#98 fix trino unit tests, limit upload concurrency, fix sidebar z index
F3l1x1vo 047ccb8
#98 fix e2e tests
F3l1x1vo 1a66e94
Merge remote-tracking branch 'origin/feat/s3-file-browser' into feat/…
Copilot b33923b
rebuild server for e2e tests
F3l1x1vo c636494
Add code editor (#209)
F3l1x1vo 58e4b9c
Add minor visual improvements (#205)
F3l1x1vo 80e7aa6
Feat/s3 file browser preview parquet (#202)
F3l1x1vo 2463e0d
S3 File Browser: Tab View (#178)
F3l1x1vo 6397e0d
fix unconfirmed save button size
F3l1x1vo d06fba7
Feat/s3 file browser csv zip preview (#203)
F3l1x1vo d75bf31
#98 add possible checksum calculation to s3 client
F3l1x1vo f476802
fix unit test
F3l1x1vo 5835bef
#98 fix e2e tests
F3l1x1vo afd6b7d
fix e2e test, add error message for copy file path
F3l1x1vo a7f9ffa
Feat/connection editing (#227)
dklOrdix 21e7cbb
Merge branch 'main' into feat/s3-file-browser
dklOrdix 4c1c13e
Merge branch 'feat/s3-file-browser' into feat/s3-file-browser-v1
dklOrdix 1ad6b09
fix: e2e tests
dklOrdix b48ea63
Merge branch 'feat/s3-file-browser' into feat/s3-file-browser-v1
dklOrdix f1937bf
#98 add possible checksum calculation to s3 client
F3l1x1vo d4d177d
fix unit test
F3l1x1vo 5e8635e
#98 fix text truncation, use env for csv max rows, clamp page size
F3l1x1vo 9026983
#98 fix multi select behavior, add image preview limit fallback
F3l1x1vo f4de415
#98 limit max columns in CSV preview
F3l1x1vo 7e49fa0
fix e2e test, fix replacement character in text editor due to truncation
F3l1x1vo 80ef600
#98 allow overwrites again
F3l1x1vo f443c9b
#98 fix text preview of binary files
F3l1x1vo e830d33
#98 csv max columns use feature flag instead of magic number
F3l1x1vo c2ce945
move tooltips to own component, add orientation, add tooltips to stor…
F3l1x1vo 38e4317
#208 show different connection error messages
F3l1x1vo 5e6c5be
minor spelling change
F3l1x1vo 7ba94c0
fix unit tests
F3l1x1vo eee9036
fix lint
F3l1x1vo a78e19d
Refactor/migrate to db (#221)
dklOrdix 1f35d8b
#233 Add JSON Preview via Prettify Processing (#241)
F3l1x1vo 40f3698
#222 add infinite scrolling to CSV, add feature flag for infinite scr…
F3l1x1vo 52d3a60
Feat/s3 file browser copy move rename (#228)
F3l1x1vo 98e5d41
Feat/s3 file browser details pane (#237)
F3l1x1vo a490fa2
fix: redirect to /storage from bucket page when no active connection …
dklOrdix 34757b4
Filebrowser: Support users explicitly stating S3 bucket names (#186)
dklOrdix 3449abb
Merge branch 'feat/s3-file-browser' into feat/s3-file-browser-v1
dklOrdix 69684f4
Refactor v1 (#247)
dklOrdix 9f19563
refactor: modularize dev setup script and improve logging (#246)
dklOrdix 747be6c
Update Tests to current Feature Set (#256)
F3l1x1vo b195deb
#223 add copy name and path actions to tab and breadcrumb context men…
F3l1x1vo 4cec1c9
Fix loading error states in storage UI (#259)
dklOrdix 785f253
Keep tabs after page reload (#258)
F3l1x1vo 86f9fcb
#220 #236 bind keys to font size inside code editor, add select all f…
F3l1x1vo df8629e
CSV column horizontal scrolling (#261)
F3l1x1vo fcf7bde
fix unicode quotes
F3l1x1vo 208310e
Fitness Function (updated) (#267)
F3l1x1vo b2e3901
Merge branch 'origin/main' into feat/s3-file-browser-v1
F3l1x1vo c4d043b
fix saving newly created files
F3l1x1vo 286a7fb
open connection options on right click as well as button
F3l1x1vo db0dcea
Add loading bar, use prefetch on main navigation (#285)
F3l1x1vo 4ac24e7
#224 add tooltips to many locations (#286)
F3l1x1vo ea867b6
#208 fix actions tooltip, show parquet line number only on data tab
F3l1x1vo 416e78c
use tabs by default, fix tooltips, rename storage routes, operations …
F3l1x1vo f9bd54d
fix tab and bucket switching behavior
F3l1x1vo c3da477
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo 6737272
remove close button
F3l1x1vo f29eedf
fix lint
F3l1x1vo b0ada4c
fix history.pushState
F3l1x1vo 84df7be
add nvm version
F3l1x1vo 297fcc6
fix unit and e2e tests
F3l1x1vo aac2e50
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo b828fb6
remove mobile e2e test config
F3l1x1vo 4f42efb
fix e2e tests
F3l1x1vo e53d280
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo 22bbf4c
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo cc88897
Merge origin/main into feat/s3-file-browser-v1
F3l1x1vo cb1eec5
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo cc979f0
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo e582f1d
fix tab switching issue of not being able to navigate inside multiple…
F3l1x1vo 18190cd
Merge remote-tracking branch 'origin/main' into feat/s3-file-browser-v1
F3l1x1vo bcad89b
#208 fix bucket shared data, solve i18n violations, remove comment
F3l1x1vo 0ea15e0
Merge branch 'main' into feat/s3-file-browser-v1
F3l1x1vo 6380967
fix e2e test
F3l1x1vo c1ccfb0
#278 implement changes suggested in code review
F3l1x1vo 5a2a7e7
update comment
F3l1x1vo ccf16d6
fix unit test
F3l1x1vo 8271e55
fix e2e test
F3l1x1vo cc43ef3
#278 implement changes suggested in code review
F3l1x1vo b94619d
#278 strengthen e2e tests to be less flaky
F3l1x1vo 5121fcb
#208 remove TECH_DEBT mentions
F3l1x1vo 5db9aaf
#208 implement changes suggested in code review
F3l1x1vo 71d8828
#208 use eslint size limits
F3l1x1vo acda359
#208 use eslint check-file
F3l1x1vo ec02386
#208 merge db migrations
F3l1x1vo 17bdaa9
#208 implement changes suggested in code review
F3l1x1vo 063f694
Merge main into feat/s3-file-browser-v1
F3l1x1vo 98b4f20
#208 fix broken tests and lint from merge
F3l1x1vo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 24.13.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,3 +33,4 @@ coverage/ | |
| # Helm templates | ||
| deploy/helm/ | ||
| dev/garage/ | ||
| dev/postgresql/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -188,10 +188,10 @@ The application uses **Paraglide-JS v2** for type-safe, compiler-based internati | |
|
|
||
| ### Node.js Version | ||
|
|
||
| The required Node.js version is pinned in `.node-version`. Use `nvm` to install and activate it before running any `npm` commands — `npm` will hard-fail with engine errors otherwise (`.npmrc` sets `engine-strict=true`). | ||
| The required Node.js version is pinned in `.node-version` for CI and `.nvmrc` for NVM. Keep both files synchronised. Use `nvm` to install and activate it before running any `npm` commands — `npm` will hard-fail with engine errors otherwise (`.npmrc` sets `engine-strict=true`). | ||
|
|
||
| ```bash | ||
| nvm install # installs the version from .node-version | ||
| nvm install # installs the version from .nvmrc | ||
| nvm use # activates it in the current shell | ||
| ``` | ||
|
|
||
|
|
@@ -224,6 +224,37 @@ pre-commit run --all-files # Run all checks: lint (prettier + eslint), type ch | |
| # markdownlint, yamllint, shellcheck, actionlint, hadolint, helm lint | ||
| ``` | ||
|
|
||
| ### Architecture Fitness Functions | ||
|
|
||
| ```bash | ||
| npm run test:arch # Run all architecture fitness function tests (~5 s) | ||
| npm run test:arch:report # Same, plus generate HTML dependency/metrics reports in /reports/ | ||
| ``` | ||
|
|
||
| Architecture tests live in `src/architecture/*.spec.ts` and use [ArchUnitTS](https://github.com/LukasNiessen/ArchUnitTS) together with plain Node.js `fs` checks. They run in CI and must remain **green at all times**. | ||
|
|
||
| **Run `npm run test:arch` whenever you:** | ||
|
|
||
| - Add a new file to `src/lib/server/` (verify it doesn't break client-boundary rules) | ||
| - Add a new Svelte component (PascalCase naming, no raw `<dialog>`, no hardcoded colours) | ||
| - Add or remove message keys in `messages/en.json` (both locale files must stay in sync) | ||
| - Refactor the Trino sub-layer (circular-dependency rules) | ||
|
|
||
| **What the fitness functions enforce:** | ||
|
|
||
| | Category | What is checked | | ||
| | ------------------------ | -------------------------------------------------------------------------------------------------------------------- | | ||
| | Server / Client Boundary | `src/lib/client`, `stores`, `storage`, `editor`, `types` must not import `src/lib/server/**` | | ||
| | No Circular Dependencies | `src/lib/**` (excluding Trino) and `src/routes/**` must be cycle-free | | ||
| | Naming Conventions | Stores → `*.svelte.ts`; lib components → PascalCase `.svelte`; server files → no `.svelte.ts` extension | | ||
| | Code Size Limits | `.ts` files < 2 400 LOC; `.svelte` files < 1 100 LOC; test files < 1 000 LOC | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. outdated |
||
| | UI Pattern Enforcement | No hardcoded Tailwind colours; no raw `<dialog>`; no native date inputs; `<img>` must have `alt`; no `<div onclick>` | | ||
| | Server Logging | Server files must use pino logger, not `console.*` | | ||
| | i18n Compliance | `messages/en.json` and `messages/de.json` must have the same keys; no static `aria-label="English text"` | | ||
|
|
||
| **Extending the fitness functions:** | ||
| When you add a new architectural rule (e.g., a new layer, a new naming convention), add a new `.spec.ts` file in `src/architecture/` following the existing patterns. Use archunit for TypeScript dependency/cycle rules and plain Node.js `fs` for content checks on Svelte files. | ||
|
|
||
| ### E2E Testing | ||
|
|
||
| ```bash | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # shellcheck shell=bash | ||
| k8s::node_ip() { | ||
| local ip | ||
| ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}') | ||
| if [ -z "$ip" ]; then | ||
| log::error "Could not detect kind node IP." | ||
| fi | ||
| echo "$ip" | ||
| } | ||
|
|
||
| k8s::wait_for_deployment() { | ||
| local name=$1 timeout=${2:-120} | ||
| kubectl wait --for=condition=available "deployment/$name" --timeout="${timeout}s" | ||
| } | ||
|
|
||
| k8s::wait_for_statefulset() { | ||
| local name=$1 timeout=${2:-300} | ||
| kubectl rollout status "statefulset/$name" --timeout="${timeout}s" | ||
| } | ||
|
|
||
| k8s::wait_for_pod() { | ||
| local label=$1 timeout=${2:-60} | ||
| kubectl wait --for=condition=ready pod -l "$label" --timeout="${timeout}s" | ||
| } | ||
|
|
||
| k8s::get_pod_name() { | ||
| local label=$1 | ||
| kubectl get pod -l "$label" -o jsonpath='{.items[0].metadata.name}' | ||
| } | ||
|
|
||
| k8s::get_node_port() { | ||
| local service=$1 | ||
| kubectl get svc "$service" -o jsonpath='{.spec.ports[0].nodePort}' | ||
| } | ||
|
|
||
| k8s::template_and_apply() { | ||
| local file=$1 | ||
| shift | ||
| local sed_exprs=() | ||
| for pair in "$@"; do | ||
| local key="${pair%%=*}" val="${pair#*=}" | ||
| sed_exprs+=(-e "s/\${${key}}/${val}/g") | ||
| done | ||
| sed "${sed_exprs[@]}" "$file" | kubectl apply -f - | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # shellcheck shell=bash | ||
| log::info() { | ||
| echo " [INFO] $*" | ||
| } | ||
|
|
||
| log::warn() { | ||
| echo " [WARN] $*" >&2 | ||
| } | ||
|
|
||
| log::error() { | ||
| echo " [ERROR] $*" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| log::ok() { | ||
| echo " [OK] $*" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # shellcheck shell=bash | ||
| probe::url() { | ||
| local port=$1 path=$2 | ||
| local scheme=${3:-http} | ||
| local timeout=${4:-120} | ||
| shift 4 | ||
|
|
||
| local deadline url candidate | ||
| deadline=$(( $(date +%s) + timeout )) | ||
| url="" | ||
| while [ -z "$url" ] && [ "$(date +%s)" -lt "$deadline" ]; do | ||
| for candidate in "${scheme}://${NODE_IP}:${port}" "${scheme}://127.0.0.1:${port}" "${scheme}://localhost:${port}"; do | ||
| if curl -sf --max-time 2 "$@" "${candidate}${path}" >/dev/null 2>&1; then | ||
| url="$candidate" | ||
| break | ||
| fi | ||
| done | ||
| [ -z "$url" ] && sleep 2 | ||
| done | ||
|
|
||
| if [ -z "$url" ]; then | ||
| return 1 | ||
| fi | ||
| echo "$url" | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.