mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-12-07 14:09:47 +00:00
- Implementation of milestone 6. from **Task F. Moderation features: Reporting** (part of [amendment of the workplan](https://codeberg.org/forgejo/sustainability/src/branch/main/2022-12-01-nlnet/2025-02-07-extended-workplan.md#task-f-moderation-features-reporting) for NLnet 2022-12-035): `6. Forgejo admins can perform common actions on the listed reports (content deletion, locking of user account)` --- Follow-up of !7905 (and !6977) --- This adds some action buttons within the _Moderation reports_ section (/admin/moderation/reports) within the _Site administration_ page, so that administrators can: - mark a report as Handled or as Ignored (without performing any action on the reported content); - mark a user account as suspended (set `prohibit_login` = true); - delete (and purge) a user / organization and mark the linked reports as Handled; - delete a repository and mark the linked reports as Handled; - delete an issue / pull request and mark the linked reports as Handled; - delete a comment and mark the linked reports as Handled; The buttons were added on the sight side of each report from the overview, below the existing counter (that show how many times the content was reported and opens the details page). Only the buttons for updating the status of the report are directly visible - as `✓` and `✗` icons with some tooltips - while the content actions are hidden under a `⋯` dropdown. The implementation was done using HTMX so that the page is not refreshed after each action. Some discussions regarding the UI/UX started with https://codeberg.org/forgejo/design/issues/30#issuecomment-5958634 ### Manual testing - First make sure that moderation in enabled ([moderation] ENABLED config is set as true within app.ini). - Report multiple users, organizations, repositories, issues, pull requests and comments. - Go to _Moderation reports_ overview section section and make sure the buttons are visible; - The `✓` and `✗` should be available for each shown report; - The horizontal dropdown menu (`⋯`) should not be visible for reports linked to already deleted content. - The actions available within the dropdown menu should correspond to the reported content type (e.g. 'Suspend account' and 'Delete account' for users/organizations, 'Delete repository' for repositories, etc.). - When an action is successful a flash message should be displayed above the overview. - Warnings should be displayed (as flash messages) when trying to suspend or delete your account (in case someone reported you) or an organization. - An info (flash message) should be displayed when trying to suspend a user that is already suspended. - Mark a report as Handled / Ignored and observe that a success flash message confirms the action and the report is removed from the list without reloading the page; - Refresh the page to make sure the report will not be loaded again (also check in the DB that the status was updated and the resolved timestamp is correctly set). - Suspend a user account and make sure the report remains in the list (it is not resolved); - Make sure the above user gets the 'Suspended account' notice after login. - Delete a user account and observe that a success flash message confirms the action and the report is removed from the list without reloading the page; - Make sure that all owned organizations and repositories as well as all the issues, PRs and comments posted in other repositories were deleted; - Make sure the linked abuse reports are marked as Handled (and resolved timestamp is set). - Delete an organization and make sure that owned repositories were also deleted. - Similarly, delete a repository / issue / PR / comment and check that the contents are not available any more and the linked reports are resolved. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8716 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: floss4good <floss4good@disroot.org> Co-committed-by: floss4good <floss4good@disroot.org>
233 lines
17 KiB
JSON
233 lines
17 KiB
JSON
{
|
|
"home.welcome.no_activity": "No activity",
|
|
"home.welcome.activity_hint": "There is nothing in your feed yet. Your actions and activity from repositories that you watch will show up here.",
|
|
"home.explore_repos": "Explore repositories",
|
|
"home.explore_users": "Explore users",
|
|
"home.explore_orgs": "Explore organizations",
|
|
"fork.n_forks": {
|
|
"one": "%s fork",
|
|
"other": "%s forks"
|
|
},
|
|
"stars.list.none": "No one starred this repo.",
|
|
"stars.n_stars": {
|
|
"one": "%s star",
|
|
"other": "%s stars"
|
|
},
|
|
"watch.list.none": "No one is watching this repo.",
|
|
"watch.n_watchers": {
|
|
"one": "%s watcher",
|
|
"other": "%s watchers"
|
|
},
|
|
"followers.incoming.list.self.none": "No one is following your profile.",
|
|
"followers.incoming.list.none": "No one is following this user.",
|
|
"followers.outgoing.list.self.none": "You are not following anyone.",
|
|
"followers.outgoing.list.none": "%s isn't following anyone.",
|
|
"relativetime.now": "now",
|
|
"relativetime.future": "in future",
|
|
"relativetime.mins": {
|
|
"one": "%d minute ago",
|
|
"other": "%d minutes ago"
|
|
},
|
|
"relativetime.hours": {
|
|
"one": "%d hour ago",
|
|
"other": "%d hours ago"
|
|
},
|
|
"relativetime.days": {
|
|
"one": "%d day ago",
|
|
"other": "%d days ago"
|
|
},
|
|
"relativetime.weeks": {
|
|
"one": "%d week ago",
|
|
"other": "%d weeks ago"
|
|
},
|
|
"relativetime.months": {
|
|
"one": "%d month ago",
|
|
"other": "%d months ago"
|
|
},
|
|
"relativetime.years": {
|
|
"one": "%d year ago",
|
|
"other": "%d years ago"
|
|
},
|
|
"relativetime.1day": "yesterday",
|
|
"relativetime.2days": "two days ago",
|
|
"relativetime.1week": "last week",
|
|
"relativetime.2weeks": "two weeks ago",
|
|
"relativetime.1month": "last month",
|
|
"relativetime.2months": "two months ago",
|
|
"relativetime.1year": "last year",
|
|
"relativetime.2years": "two years ago",
|
|
"repo.issues.filter_poster.hint": "Filter by the author",
|
|
"repo.issues.filter_assignee.hint": "Filter by assigned user",
|
|
"repo.issues.filter_reviewers.hint": "Filter by user who reviewed",
|
|
"repo.issues.filter_mention.hint": "Filter by mentioned user",
|
|
"repo.issues.filter_modified.hint": "Filter by last modified date",
|
|
"repo.issues.filter_sort.hint": "Sort by: created/comments/updated/deadline",
|
|
"repo.pulls.poster_manage_approval": "Manage approval",
|
|
"repo.pulls.poster_requires_approval": "Some workflows are <a href=\"%[1]s\">waiting to be reviewed.</a>",
|
|
"repo.pulls.poster_requires_approval.tooltip": "The author of this pull request is not trusted to run workflows triggered by a pull request created from a forked repository or with AGit. The workflows triggered by a `pull_request` event will not run until they are approved.",
|
|
"repo.pulls.poster_is_trusted": "The author of this pull request is <a href=\"%[1]s\">always trusted to run workflows.</a>",
|
|
"repo.pulls.poster_is_trusted.tooltip": "The author of this pull request is explicitly trusted to run workflows triggered by `pull_request` events.",
|
|
"repo.pulls.poster_trust_deny": "Deny",
|
|
"repo.pulls.poster_trust_deny.tooltip": "The workflows waiting approval will be canceled.",
|
|
"repo.pulls.poster_trust_once": "Approve once",
|
|
"repo.pulls.poster_trust_once.tooltip": "The workflows triggered by a `pull_request` event will run on this commit but will need to be approved for all future commits pushed to this pull request.",
|
|
"repo.pulls.poster_trust_always": "Approve always",
|
|
"repo.pulls.poster_trust_always.tooltip": "The workflows triggered by a `pull_request` event will run on this commit and there will be no need to approve runs from this pull request or future pull requests authored by the same user.",
|
|
"repo.pulls.poster_trust_revoke": "Revoke",
|
|
"repo.pulls.poster_trust_revoke.tooltip": "The author of this pull request will no longer be trusted to run workflows triggered by a `pull_request` event, each run will have to be manually approved.",
|
|
"repo.pulls.already_merged": "Merge failed: This pull request has already been merged.",
|
|
"repo.pulls.merged_title_desc": {
|
|
"one": "merged %[1]d commit from <code>%[2]s</code> into <code>%[3]s</code> %[4]s",
|
|
"other": "merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s"
|
|
},
|
|
"repo.pulls.title_desc": {
|
|
"one": "wants to merge %[1]d commit from <code>%[2]s</code> into <code id=\"%[4]s\">%[3]s</code>",
|
|
"other": "wants to merge %[1]d commits from <code>%[2]s</code> into <code id=\"%[4]s\">%[3]s</code>"
|
|
},
|
|
"repo.pulls.maintainers_can_edit": "Maintainers can edit this pull request.",
|
|
"repo.pulls.maintainers_cannot_edit": "Maintainers cannot edit this pull request.",
|
|
"repo.form.cannot_create": "All spaces in which you can create repositories have reached the limit of repositories.",
|
|
"migrate.form.error.url_credentials": "The URL contains credentials, put them in the username and password fields respectively",
|
|
"migrate.github.description": "Migrate data from github.com or GitHub Enterprise server.",
|
|
"migrate.git.description": "Migrate a repository only from any Git service.",
|
|
"migrate.gitea.description": "Migrate data from gitea.com or other Gitea instances.",
|
|
"migrate.gitlab.description": "Migrate data from gitlab.com or other GitLab instances.",
|
|
"migrate.gogs.description": "Migrate data from notabug.org or other Gogs instances.",
|
|
"migrate.onedev.description": "Migrate data from code.onedev.io or other OneDev instances.",
|
|
"migrate.gitbucket.description": "Migrate data from GitBucket instances.",
|
|
"migrate.codebase.description": "Migrate data from codebasehq.com.",
|
|
"migrate.forgejo.description": "Migrate data from codeberg.org or other Forgejo instances.",
|
|
"repo.issue_indexer.title": "Issue Indexer",
|
|
"search.milestone_kind": "Search milestones…",
|
|
"search.syntax": "Search syntax",
|
|
"repo.settings.push_mirror.branch_filter.label": "Branch filter (optional)",
|
|
"repo.settings.push_mirror.branch_filter.description": "Branches to be mirrored. Leave blank to mirror all branches. See <a href=\"%[1]s\">%[2]s documentation</a> for syntax. Examples: <code>main, release/*</code>",
|
|
"incorrect_root_url": "This Forgejo instance is configured to be served on \"%s\". You are currently viewing Forgejo through a different URL, which may cause parts of the application to break. The canonical URL is controlled by Forgejo admins via the ROOT_URL setting in the app.ini.",
|
|
"themes.names.forgejo-auto": "Forgejo (follow system theme)",
|
|
"themes.names.forgejo-light": "Forgejo light",
|
|
"themes.names.forgejo-dark": "Forgejo dark",
|
|
"error.not_found.title": "Page not found",
|
|
"warning.repository.out_of_sync": "The database representation of this repository is out of synchronization. If this warning is still shown after pushing a commit to this repository contact the administrator.",
|
|
"alert.asset_load_failed": "Failed to load asset files from {path}. Please make sure the asset files can be accessed.",
|
|
"alert.range_error": " must be a number between %[1]s and %[2]s.",
|
|
"install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s",
|
|
"profile.actions.tooltip": "More actions",
|
|
"profile.edit.link": "Edit profile",
|
|
"feed.atom.link": "Atom feed",
|
|
"keys.ssh.link": "SSH keys",
|
|
"keys.gpg.link": "GPG keys",
|
|
"keys.verify.token.hint": "The token is only valid for 1 minute. <a href=\"%[1]s\">Get a new one if it expired</a>.",
|
|
"admin.config.moderation_config": "Moderation configuration",
|
|
"admin.moderation.moderation_reports": "Moderation reports",
|
|
"admin.moderation.reports": "Reports",
|
|
"admin.moderation.no_open_reports": "There are currently no open reports.",
|
|
"admin.moderation.deleted_content_ref": "Reported content with type %[1]v and id %[2]d no longer exists",
|
|
"moderation.report.mark_as_handled": "Mark as handled",
|
|
"moderation.report.mark_as_ignored": "Mark as ignored",
|
|
"moderation.action.account.delete": "Delete account",
|
|
"moderation.action.account.suspend": "Suspend account",
|
|
"moderation.action.repo.delete": "Delete repository",
|
|
"moderation.action.issue.delete": "Delete issue",
|
|
"moderation.action.comment.delete": "Delete comment",
|
|
"moderation.unknown_action": "Unknown action",
|
|
"moderation.users.cannot_suspend_self": "You cannot suspend yourself.",
|
|
"moderation.users.cannot_suspend_admins": "Users with admin privileges cannot be suspended.",
|
|
"moderation.users.cannot_suspend_org": "Organizations cannot be suspended.",
|
|
"moderation.users.already_suspended": "User account is already suspended.",
|
|
"moderation.users.suspend_success": "The user account has been suspended.",
|
|
"moderation.users.cannot_delete_admins": "Users with admin privileges cannot be deleted.",
|
|
"moderation.issue.deletion_success": "The issue has been deleted.",
|
|
"moderation.comment.deletion_success": "The comment has been deleted.",
|
|
"moderation.report_abuse": "Report abuse",
|
|
"moderation.report_content": "Report content",
|
|
"moderation.report_abuse_form.header": "Report abuse to administrator",
|
|
"moderation.report_abuse_form.details": "This form should be used to report users who create spam profiles, repositories, issues, comments or behave inappropriately.",
|
|
"moderation.report_abuse_form.invalid": "Invalid arguments",
|
|
"moderation.report_abuse_form.already_reported": "You've already reported this content",
|
|
"moderation.abuse_category": "Category",
|
|
"moderation.abuse_category.placeholder": "Select a category",
|
|
"moderation.abuse_category.spam": "Spam",
|
|
"moderation.abuse_category.malware": "Malware",
|
|
"moderation.abuse_category.illegal_content": "Illegal content",
|
|
"moderation.abuse_category.other_violations": "Other violations of platform rules",
|
|
"moderation.report_remarks": "Remarks",
|
|
"moderation.report_remarks.placeholder": "Please provide some details regarding the abuse you are reporting.",
|
|
"moderation.submit_report": "Submit report",
|
|
"moderation.reporting_failed": "Unable to submit the new abuse report: %v",
|
|
"moderation.reported_thank_you": "Thank you for your report. The administration has been made aware of it.",
|
|
"mail.actions.successful_run_after_failure_subject": "Workflow %[1]s recovered in repository %[2]s",
|
|
"mail.actions.not_successful_run_subject": "Workflow %[1]s failed in repository %[2]s",
|
|
"mail.actions.successful_run_after_failure": "Workflow %[1]s recovered in repository %[2]s",
|
|
"mail.actions.not_successful_run": "Workflow %[1]s failed in repository %[2]s",
|
|
"mail.actions.run_info_cur_status": "This Run's Status: %[1]s (just updated from %[2]s)",
|
|
"mail.actions.run_info_previous_status": "Previous Run's Status: %[1]s",
|
|
"mail.actions.run_info_sha": "Commit: %[1]s",
|
|
"mail.actions.run_info_trigger": "Triggered because: %[1]s by: %[2]s",
|
|
"mail.issue.action.close_by_commit": "%[1]s closed %[2]s in commit %[3]s.",
|
|
"repo.diff.commit.next-short": "Next",
|
|
"repo.diff.commit.previous-short": "Prev",
|
|
"discussion.locked": "This discussion has been locked. Commenting is limited to contributors.",
|
|
"discussion.sidebar.reference": "Reference",
|
|
"editor.textarea.tab_hint": "Line already indented. Press <kbd>Tab</kbd> again or <kbd>Escape</kbd> to leave the editor.",
|
|
"editor.textarea.shift_tab_hint": "No indentation on this line. Press <kbd>Shift</kbd> + <kbd>Tab</kbd> again or <kbd>Escape</kbd> to leave the editor.",
|
|
"admin.auths.allow_username_change": "Allow username change",
|
|
"admin.auths.allow_username_change.description": "Allow users to change their username in the profile settings",
|
|
"admin.dashboard.cleanup_offline_runners": "Cleanup offline runners",
|
|
"admin.dashboard.remove_resolved_reports": "Remove resolved reports",
|
|
"admin.dashboard.actions_action_user": "Revoke Forgejo Actions trust for inactive users",
|
|
"admin.dashboard.transfer_lingering_logs": "Transfer actions logs of finished actions jobs from the database to storage",
|
|
"admin.config.security": "Security configuration",
|
|
"admin.config.global_2fa_requirement.title": "Global two-factor requirement",
|
|
"admin.config.global_2fa_requirement.none": "No",
|
|
"admin.config.global_2fa_requirement.all": "All users",
|
|
"admin.config.global_2fa_requirement.admin": "Administrators",
|
|
"settings.visibility.description": "Profile visibility affects others' ability to access your non-private repositories. <a href=\"%s\" target=\"_blank\">Learn more</a>.",
|
|
"settings.twofa_unroll_unavailable": "Two-factor authentication is required for your account and cannot be disabled.",
|
|
"settings.twofa_reenroll": "Re-enroll two-factor authentication",
|
|
"settings.twofa_reenroll.description": "Re-enroll your two-factor authentication",
|
|
"settings.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts.",
|
|
"error.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts. Enable it at: %s",
|
|
"avatar.constraints_hint": "Custom avatar may not exceed %[1]s in size or be larger than %[2]dx%[3]d pixels",
|
|
"user.ghost.tooltip": "This user has been deleted, or cannot be matched.",
|
|
"og.repo.summary_card.alt_description": "Summary card of repository %[1]s, described as: %[2]s",
|
|
"repo.commit.load_tags_failed": "Load tags failed because of internal error",
|
|
"compare.branches.title": "Compare branches",
|
|
"migrate.pagure.description": "Migrate data from pagure.io or other Pagure instances.",
|
|
"migrate.pagure.incorrect_url": "Incorrect source repository URL has been provided",
|
|
"migrate.pagure.project_url": "Pagure project URL",
|
|
"migrate.pagure.project_example": "The Pagure project URL, e.g. https://pagure.io/pagure",
|
|
"migrate.pagure.token_label": "Pagure API Token",
|
|
"migrate.pagure.private_issues.summary": "Private Issues (Optional)",
|
|
"migrate.pagure.private_issues.description": "This feature is designed to create a second repository containing only private issues from your Pagure project for archive purposes. First, perform a normal migration (without a token) to import all public content. Then, if you have private issues to preserve, create a separate repository using this token option to archive those private issues.",
|
|
"migrate.pagure.private_issues.warning": "Be sure to set the repository visibility above to Private if you are using the API key to import private issues. This prevents accidentally exposing private content in a public repository.",
|
|
"migrate.pagure.token.placeholder": "Only for creating private issues archive",
|
|
"release.n_downloads": {
|
|
"one": "%s download",
|
|
"other": "%s downloads"
|
|
},
|
|
"actions.status.diagnostics.waiting": {
|
|
"one": "Waiting for a runner with the following label: %s",
|
|
"other": "Waiting for a runner with the following labels: %s"
|
|
},
|
|
"actions.runs.run_attempt_label": "Run attempt #%[1]s (%[2]s)",
|
|
"actions.runs.viewing_out_of_date_run": "You are viewing an out-of-date run of this job that was executed %[1]s.",
|
|
"actions.runs.view_most_recent_run": "View most recent run",
|
|
"actions.workflow.job_parsing_error": "Unable to parse jobs in workflow: %v",
|
|
"actions.workflow.event_detection_error": "Unable to parse supported events in workflow: %v",
|
|
"actions.workflow.persistent_incomplete_matrix": "Unable to evaluate `strategy.matrix` of job %[1]s due to a `needs` expression that was invalid. It may reference a job that is not in it's 'needs' list (%[2]s), or an output that doesn't exist on one of those jobs.",
|
|
"actions.workflow.pre_execution_error": "Workflow was not executed due to an error that blocked the execution attempt.",
|
|
"pulse.n_active_issues": {
|
|
"one": "%s active issue",
|
|
"other": "%s active issues"
|
|
},
|
|
"pulse.n_active_prs": {
|
|
"one": "%s active pull request",
|
|
"other": "%s active pull requests"
|
|
},
|
|
"teams.add_all_repos.modal.header": "Add all repositories",
|
|
"teams.remove_all_repos.modal.header": "Remove all repositories",
|
|
"admin.auths.oauth2_quota_group_claim_name": "Claim name providing group names for this source to be used for quota management. (Optional)",
|
|
"admin.auths.oauth2_quota_group_map": "Map claimed groups to quota groups. (Optional - requires claim name above)",
|
|
"admin.auths.oauth2_quota_group_map_removal": "Remove users from synchronized quota groups if user does not belong to corresponding group.",
|
|
"meta.last_line": "Thank you for translating Forgejo! This line isn't seen by the users but it serves other purposes in the translation management. You can place a fun fact in the translation instead of translating it."
|
|
}
|