-
Notifications
You must be signed in to change notification settings - Fork 14k
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
Can superset fromat currency dynamically according to the user's setting #18938
Comments
@dorachen123 This is a good request and reminds me of MSTR's experience. Unfortunately, Superset doesn't have these settings right now. BTW, You can try to customize d3 locale in |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. For admin, please label this issue |
We actually managed to do that with a bunch of tweaks & hacks. First of all, you'll need a custom def custom_static(self, filename): # vendored from flask and modified to support our static files
# Ensure get_send_file_max_age is called in all cases.
# Here, we ensure get_send_file_max_age is called for Blueprints.
cache_timeout = self.get_send_file_max_age(filename)
with contextlib.suppress(NotFound):
# here you mutate static files
mutated, render, mutated_filename = get_mutated_static(self.static_folder, filename)
response = send_from_directory(
self.static_folder, mutated_filename, cache_timeout=0 if mutated else cache_timeout
)
if mutated:
os.remove(os.path.join(self.static_folder, mutated_filename))
return response
raise NotFound Then you set it as current static views in your app.view_functions["static"] = MethodType(custom_static, app) # hack Here's the def get_mutated_static(static_dir, filename):
file_path = os.path.join(static_dir, filename)
for mutator_spec in MUTATED_STATIC:
if static_dir in mutator_spec.static_dirs and mutator_spec.predicate(file_path):
file_content = mutator_spec.mutator(file_path)
break
else:
return False, False, filename
_, suffix = os.path.splitext(filename)
with tempfile.NamedTemporaryFile(dir=static_dir, mode="w", delete=False, suffix=suffix) as temp_fp:
temp_fp.write(file_content)
return True, mutator_spec.render, os.path.relpath(temp_fp.name, static_dir) In a nutshell, you mutate your static, write it to a temp file, make a response based on a temp file, you remove the temp file. Here we register our mutated static: class MutatedStaticSpec(NamedTuple):
predicate: Callable[[str], bool]
mutator: Callable[[str], Union[str, bytes]]
static_dirs: List[str] = ["default dir here (the superset's one)"]
# mutate static file at runtime
# you match the file in `predicate` within the `static_dirs` folders, mutate the content in `mutator`,
MUTATED_STATIC = (
MutatedStaticSpec(
predicate=lambda file_path: (
# we don't know the exact filename, as it may change any time
file_path.endswith(".js")
and any(placeholder in open(file_path).read() for placeholder in JS_CURRENCY_LOCALE_PLACEHOLDERS)
),
mutator=_set_currency_placeholder,
static_dirs=[os.path.join("/app/superset", "static")],
),
) Here's js currency locale placeholder (you don't need to change it): # [0] minimized js version, [1] formatted (we need this for compatibility between superset 1.4 and 1.5)
JS_CURRENCY_LOCALE_PLACEHOLDERS = ("currency:[\"$\",\"\"]", "currency: [\"$\", \"\"]") And here's def _set_currency_placeholder(file_path):
with open(file_path) as fp:
file_content = fp.read()
for placeholder in JS_CURRENCY_LOCALE_PLACEHOLDERS:
file_content = file_content.replace(
placeholder,
render_template_string("currency:[\"{{ currency_symbol }}\",\"\"]")
)
return file_content As you can see here, we render a single string def get_currency():
# use any currency symbol here, you'd probably want to get it somewhere from the settings
return {"currency_symbol": "$"} Then register that context processor in CONTEXT_PROCESSORS = (get_client_currency,) When you access a chart/dashboard, static will mutate during that process, so the currency symbol gets replaced, and you'll see it in the UI. Here's an example of how it looks if you change the currency to Euros: Keep in mind that the currency symbol will get changed everywhere, no further actions are needed. |
Thanks for sharing such a way of customization @ypankovych ! I wonder if this is possible to have a truly dynamic currency on the dashboard, let's say we have different currencies attached to the Organisation. And a dashboard which is shown for multiple Organizations. Any ideas on how can we achieve this? |
hey @ypankovych, i am struggling to implement the method you came up can you share the screenshots of the code with file you put it in so that i can also implement it, a quick answer would be appreciated. |
Closing this out since it's gone silent for a good long while. Also since we're moving feature requests over to GitHub discussions, and leaving Issues for bugs (which this isn't). We'd love to see proposals or PRs for this (perhaps another formatted input in the dataset editor like we do for time formatters?) but to answer your question - nope, it's not (yet) supported. Happy to migrate this whole thread to a Discussion if folks want to keep it going. Thanks! |
Is your feature request related to a problem? Please describe.
When I create a report on superset and share to different customers using different currencies, except customers from US could see money being format correctly, other can not. Even though we can add more money format to superset. But it doesn't change the fact that one report could only use one kind of currency format which is frustrated.
Describe the solution you'd like
What we need is if superset could dynamically apply currency format to report's columns according to login user's setting. So different user could see one report in different currency format.
The text was updated successfully, but these errors were encountered: