Show Strings waiting for review on project page/component list page
Is your feature request related to a problem? If so, please describe. I'm running a weblate instance with about 2,000 components in a project. And Dedicated reviewers mode is enabled. However, when a reviewer wants to do his work, he can't find the components that need to be reviewed efficiently.
Describe the solution you'd like I wonder if weblate can show the "Strings waiting for review" column on the project page. Thus a reviewer can sort by this number and find out which components need to be reviewed.
Describe alternatives you've considered
I tried to use REST API (https://docs.weblate.org/en/latest/api.html#get--api-translations-(string-project)-(string-component)-(string-language)-) to get String status number for a component language but with no luck. fuzzy is always zero and there is no approved like property.
Additional context Add any other context or screenshots about the feature request here.
The more useful endpoint would be https://docs.weblate.org/en/latest/api.html#get--api-translations-(string-project)-(string-component)-(string-language)-statistics-, but the approved stats are not there either. I will add it right now. As for the UI, it would really deserve a different view for reviewers...
This issue has been added to the backlog. It is not scheduled on the Weblate roadmap, but it eventually might be implemented. In case you need this feature soon, please consider helping or push it by funding the development.
Well, I did another hack here.. https://github.com/exzhawk/weblate/commit/5aa192ce038bfe8c62980199cc97b4f36b07e68f
And https://github.com/exzhawk/weblate/commit/bd2ee7e3dd5fdbd99bda9fdfa2448ebdacbcb26d to sort by descending order first, to make users clicking one time to find the component to contribute.
Screenshot
To add suggestions permission: Sort by "Strings needing action without suggestions"
To accept suggestions: Sort by "Suggestion"
To review translation: Sort by "Strings waiting for review"
A configurable table header is better, but this is enough for my single purpose weblate instance.
Shortages of this implementation: Headers are too long. Occasionally get exceptions
[2021-01-16 16:51:58,885: ERROR/29450] Internal Server Error: /projects/mod/
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 829, in _resolve_lookup
current = current[bit]
TypeError: 'GhostProjectLanguageStats' object is not subscriptable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.7/dist-packages/sentry_sdk/integrations/django/views.py", line 67, in sentry_wrapped_callback
return callback(request, *args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/weblate/trans/views/basic.py", line 203, in show_project
"licenses": obj.component_set.exclude(license="").order_by("license"),
File "/usr/local/lib/python3.7/dist-packages/weblate/trans/util.py", line 222, in render
return django_render(request, template, context, status=status)
File "/usr/local/lib/python3.7/dist-packages/django/shortcuts.py", line 19, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "/usr/local/lib/python3.7/dist-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
File "/usr/local/lib/python3.7/dist-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 170, in render
return self._render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/loader_tags.py", line 192, in render
return template.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 172, in render
return self._render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/defaulttags.py", line 312, in render
return nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/defaulttags.py", line 211, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/defaulttags.py", line 312, in render
return nodelist.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/loader_tags.py", line 187, in render
for name, var in self.extra_context.items()
File "/usr/local/lib/python3.7/dist-packages/django/template/loader_tags.py", line 187, in <dictcomp>
for name, var in self.extra_context.items()
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 671, in resolve
obj = self.var.resolve(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 796, in resolve
value = self._resolve_lookup(context)
File "/usr/local/lib/python3.7/dist-packages/django/template/base.py", line 837, in _resolve_lookup
current = getattr(current, bit)
File "/usr/local/lib/python3.7/dist-packages/weblate/utils/stats.py", line 210, in __getattr__
return self._data[name]
KeyError: 'nosuggestions'
Well, just figure out exceptions are caused by deleted items. They don't have nosuggestions stat. More hack https://github.com/exzhawk/weblate/commit/da84c75ebd7757f0b78891fb9fcf79b182411160 Hopefully return -1 hurt nobody...
@exzhawk The proper solution for that is adding the stat globally, see 94a0487473546329c695e545d9dbc267f961e839
Wow, I'm looking forward to the next release!