New UI Design for Frappe & ERPNext 🌈

Hi Community,

After dedicated efforts of around 6 months for the project, we are pleased to announce that the new UI design for Frappe & ERPNext has been merged today :tada:

Huge shout out to the following people for making this happen!

Few screenshots of new design

Workspace

Screenshot 2021-02-01 at 2 55 45 PM

Form View

Screenshot 2021-01-28 at 7 26 10 PM

Print View

Screenshot 2021-01-28 at 5 23 25 PM

Point of Sale

image

Dark Mode :crescent_moon:

(cmd + shift + g)

Screenshot 2021-02-01 at 2 50 47 PM

Please try it out, and let us know your feedback!

Also, check out this blog :fire: by Rushabh to know more about our design journey so far.

Best,
Suraj

74 Likes

Brilliant…!!

2 Likes

The dark mode is FAB.
ERPNext was always world-class in terms of code, but with this design update, it truly is on par with design also.

Also appreciate, the changes in routing, etc. that team did. They were trully necessary.

4 Likes

Great UI. Looks clean and tidy.
Will this new UI appear in V13 latest patch ?

3 Likes

Mind Blowing!! Kudos @surajshetty & the Frappe Team :partying_face::heart_eyes::clap::+1:

3 Likes

Milestone! Really appreciate all your work team!

2 Likes

This looks really really nice. I am so incredibly excited to try this out. Really appreciate all the effort in this guys.

3 Likes

bench update is breaking

Executing execute:frappe.delete_doc("Report", "Quoted Item Comparison") in test.com (_5f543afdb6ba8aee)
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 99, in <module>
    main()
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 26, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/commands/site.py", line 293, in migrate
    migrate(
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/migrate.py", line 67, in migrate
    frappe.modules.patch_handler.run_all(skip_failing)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 41, in run_all
    run_patch(patch)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 30, in run_patch
    if not run_single(patchmodule = patch):
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 71, in run_single
    return execute_patch(patchmodule, method, methodargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 89, in execute_patch
    exec(patchmodule.split("execute:")[1],globals())
  File "<string>", line 1, in <module>
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/__init__.py", line 855, in delete_doc
    frappe.model.delete_doc.delete_doc(doctype, name, force, ignore_doctypes, for_reload,
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/model/delete_doc.py", line 106, in delete_doc
    check_if_doc_is_dynamically_linked(doc)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/model/delete_doc.py", line 280, in check_if_doc_is_dynamically_linked
    for refdoc in frappe.db.sql("""select `name`, `docstatus` {table} from `tab{parent}` where
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/database/database.py", line 147, in sql
    self._cursor.execute(query, values)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1146, "Table '_5f543afdb6ba8aee.tabDesk Shortcut' doesn't exist")
Executing execute:frappe.rename_doc("Workspace", "Loan", "Loan Management", ignore_if_exists=True, force=True) in test.com (_5f543afdb6ba8aee)
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 99, in <module>
    main()
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 26, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/commands/site.py", line 293, in migrate
    migrate(
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/migrate.py", line 67, in migrate
    frappe.modules.patch_handler.run_all(skip_failing)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 41, in run_all
    run_patch(patch)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 30, in run_patch
    if not run_single(patchmodule = patch):
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 71, in run_single
    return execute_patch(patchmodule, method, methodargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 89, in execute_patch
    exec(patchmodule.split("execute:")[1],globals())
  File "<string>", line 1, in <module>
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/__init__.py", line 891, in rename_doc
    return rename_doc(*args, **kwargs)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 63, in rename_doc
    rename_parent_and_child(doctype, old, new, meta)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 186, in rename_parent_and_child
    update_child_docs(old, new, meta)
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 239, in update_child_docs
    frappe.db.sql("update `tab%s` set parent=%s where parent=%s" \
  File "/home/mujeerhashmi/erpnext/frappe-bench/apps/frappe/frappe/database/database.py", line 147, in sql
    self._cursor.execute(query, values)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/home/mujeerhashmi/erpnext/frappe-bench/env/lib/python3.8/site-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1146, "Table '_5f543afdb6ba8aee.tabWorkspace Link' doesn't exist")

Amazing Work!! Looking forward to trying it out

1 Like

Great. It is looking very elegant. Good work Frappe Team.

1 Like

Update is breaking at patch

Stack Trace
Migrating comfoy
Executing execute:frappe.rename_doc("Workspace", "Loan", "Loan Management", ignore_if_exists=True, force=True) in comfoy (_717b7af2f72e3633)
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 99, in <module>
    main()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 26, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 296, in migrate
    skip_search_index=skip_search_index
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 67, in migrate
    frappe.modules.patch_handler.run_all(skip_failing)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 41, in run_all
    run_patch(patch)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 30, in run_patch
    if not run_single(patchmodule = patch):
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 71, in run_single
    return execute_patch(patchmodule, method, methodargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 89, in execute_patch
    exec(patchmodule.split("execute:")[1],globals())
  File "<string>", line 1, in <module>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 891, in rename_doc
    return rename_doc(*args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 63, in rename_doc
    rename_parent_and_child(doctype, old, new, meta)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 186, in rename_parent_and_child
    update_child_docs(old, new, meta)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/rename_doc.py", line 240, in update_child_docs
    % (df.options, '%s', '%s'), (new, old))
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 147, in sql
    self._cursor.execute(query, values)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/cursors.py", line 170, in execute    result = self._query(query)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1146, "Table '_717b7af2f72e3633.tabWorkspace Link' doesn't exist")

Looks nice & clean !!

Great work guys. And thank you for your efforts.
I upgraded to
ERPNext: v13.0.0-beta.9 (version-13-beta)
Frappe Framework: v13.0.0-beta.9 (version-13-beta)

Not sure if this is the latest. Would like to know how to enable dark mode on Windows PC. Tried Ctrl+Shift+g . Using Chrome browser

@mujeerhashmi, @Max_Fun

https://github.com/frappe/frappe/pull/12301
This should fix the issue… can you pull and try again?

1 Like

Hi @Muzzy & @Witton,

We merged the new design to develop. We have not made a beta release for it yet.

You can switch to develop if you want try out the new design.

1 Like

Thank you for the quick response.

@surajshetty What happens for those of us using version-13-beta branch? We have to merge locally to use it? Or not compatible with Version 13 yet? The screenshots seemed to be version 13.

When is it going to be merged into version 13?

You can just do bench switch-to-branch develop