Merge branch 'rebrand-ui' of https://github.com/frappe/frappe into rebrand-ui
This commit is contained in:
commit
9ff0b86f6d
44 changed files with 117 additions and 139 deletions
|
|
@ -6,7 +6,7 @@ context('Awesome Bar', () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.navbar-header .navbar-home').click();
|
||||
cy.get('.navbar .navbar-home').click();
|
||||
});
|
||||
|
||||
it('navigates to doctype list', () => {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ context('Control Link', () => {
|
|||
cy.get('.frappe-control[data-fieldname=link] .link-btn')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.location('hash').should('eq', `/app/Form/ToDo/${todos[0]}`);
|
||||
cy.location('hash').should('eq', `/app/todo/${todos[0]}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ context('Form', () => {
|
|||
});
|
||||
});
|
||||
it('create a new form', () => {
|
||||
cy.visit('/app/Form/ToDo/New ToDo 1');
|
||||
cy.visit('/app/todo/new');
|
||||
cy.fill_field('description', 'this is a test todo', 'Text Editor').blur();
|
||||
cy.wait(300);
|
||||
cy.get('.page-title').should('contain', 'Not Saved');
|
||||
|
|
@ -18,20 +18,18 @@ context('Form', () => {
|
|||
}).as('form_save');
|
||||
cy.get('.primary-action').click();
|
||||
cy.wait('@form_save').its('status').should('eq', 200);
|
||||
cy.visit('/app/List/ToDo');
|
||||
cy.location('hash').should('eq', '/app/List/ToDo/List');
|
||||
cy.visit('/app/todo');
|
||||
cy.get('h1').should('be.visible').and('contain', 'To Do');
|
||||
cy.get('.list-row').should('contain', 'this is a test todo');
|
||||
});
|
||||
it('navigates between documents with child table list filters applied', () => {
|
||||
cy.visit('/app/List/Contact');
|
||||
cy.location('hash').should('eq', '/app/List/Contact/List');
|
||||
cy.visit('/app/contact');
|
||||
cy.get('.tag-filters-area .btn:contains("Add Filter")').click();
|
||||
cy.get('.fieldname-select-area').should('exist');
|
||||
cy.get('.fieldname-select-area input').type('Number{enter}', { force: true });
|
||||
cy.get('.filter-field .input-with-feedback.form-control').type('123', { force: true });
|
||||
cy.get('.filter-box .btn:contains("Apply")').click({ force: true });
|
||||
cy.visit('/app/Form/Contact/Test Form Contact 3');
|
||||
cy.visit('/app/contact/Test Form Contact 3');
|
||||
cy.get('.prev-doc').should('be.visible').click();
|
||||
cy.get('.msgprint-dialog .modal-body').contains('No further records').should('be.visible');
|
||||
cy.get('.btn-modal-close:visible').click();
|
||||
|
|
@ -50,7 +48,7 @@ context('Form', () => {
|
|||
let website_input = 'website.in';
|
||||
let expectBackgroundColor = 'rgb(255, 220, 220)';
|
||||
|
||||
cy.visit('/app/Form/Contact/New Contact 1');
|
||||
cy.visit('/app/contact/new');
|
||||
cy.get('.frappe-control[data-fieldname="email_ids"]').as('table');
|
||||
cy.get('@table').find('button.grid-add-row').click();
|
||||
cy.get('.grid-body .rows [data-fieldname="email_id"]').click();
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ context('Grid Pagination', () => {
|
|||
});
|
||||
});
|
||||
it('creates pages for child table', () => {
|
||||
cy.visit('/app/Form/Contact/Test Contact');
|
||||
cy.visit('/app/contact/Test Contact');
|
||||
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
|
||||
cy.get('@table').find('.current-page-number').should('contain', '1');
|
||||
cy.get('@table').find('.total-page-number').should('contain', '20');
|
||||
cy.get('@table').find('.grid-body .grid-row').should('have.length', 50);
|
||||
});
|
||||
it('goes to the next and previous page', () => {
|
||||
cy.visit('/app/Form/Contact/Test Contact');
|
||||
cy.visit('/app/contact/Test Contact');
|
||||
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
|
||||
cy.get('@table').find('.next-page').click();
|
||||
cy.get('@table').find('.current-page-number').should('contain', '2');
|
||||
|
|
@ -28,7 +28,7 @@ context('Grid Pagination', () => {
|
|||
cy.get('@table').find('.grid-body .grid-row').first().should('have.attr', 'data-idx', '1');
|
||||
});
|
||||
it('adds and deletes rows and changes page', () => {
|
||||
cy.visit('/app/Form/Contact/Test Contact');
|
||||
cy.visit('/app/contact/Test Contact');
|
||||
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
|
||||
cy.get('@table').find('button.grid-add-row').click();
|
||||
cy.get('@table').find('.grid-body .row-index').should('contain', 1001);
|
||||
|
|
@ -41,7 +41,7 @@ context('Grid Pagination', () => {
|
|||
cy.get('@table').find('.total-page-number').should('contain', '20');
|
||||
});
|
||||
// it('deletes all rows', ()=> {
|
||||
// cy.visit('/app/Form/Contact/Test Contact');
|
||||
// cy.visit('/app/contact/Test Contact');
|
||||
// cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
|
||||
// cy.get('@table').find('.grid-heading-row .grid-row-check').click({force: true});
|
||||
// cy.get('@table').find('button.grid-remove-all-rows').click();
|
||||
|
|
|
|||
|
|
@ -46,6 +46,6 @@ context('Table MultiSelect', () => {
|
|||
cy.get(`.list-subject:contains("table multiselect")`).last().find('a').click();
|
||||
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').as('existing_value');
|
||||
cy.get('@existing_value').find('.btn-link-to-form').click();
|
||||
cy.location('hash').should('contain', 'Form/User/test@erpnext.com');
|
||||
cy.location('pathname').should('contain', '/user/test@erpnext.com');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ Cypress.Commands.add('awesomebar', text => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add('new_form', doctype => {
|
||||
let route = `form/${doctype}/new`;
|
||||
let route = `${doctype.toLowerCase().replace(' ', '-')}/new`;
|
||||
cy.visit(`/app/${route}`);
|
||||
cy.get('body').should('have.attr', 'data-route', route);
|
||||
cy.get('body').should('have.attr', 'data-ajax-state', 'complete');
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ frappe.ui.form.on('Auto Repeat', {
|
|||
refresh: function(frm) {
|
||||
// auto repeat message
|
||||
if (frm.is_new()) {
|
||||
let customize_form_link = `<a href="/app/Form/Customize Form">${__('Customize Form')}</a>`;
|
||||
let customize_form_link = `<a href="/app/customize form">${__('Customize Form')}</a>`;
|
||||
frm.dashboard.set_headline(__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [customize_form_link]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ frappe.listview_settings["Deleted Document"] = {
|
|||
if (r.message) {
|
||||
function body(docnames) {
|
||||
const html = docnames.map(docname => {
|
||||
return `<li><a href='/app/Form/Deleted Document/${docname}'>${docname}</a></li>`;
|
||||
return `<li><a href='/app/deleted-document/${docname}'>${docname}</a></li>`;
|
||||
});
|
||||
return "<br><ul>" + html.join("");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ frappe.ui.form.on('DocType', {
|
|||
if (!frm.is_new() && !frm.doc.istable) {
|
||||
if (frm.doc.issingle) {
|
||||
frm.add_custom_button(__('Go to {0}', [frm.doc.name]), () => {
|
||||
window.open(`/app/form/${frm.doc.name}`);
|
||||
window.open(`/app/${frappe.router.slug(frm.doc.name)}`);
|
||||
});
|
||||
} else {
|
||||
frm.add_custom_button(__('Go to {0} List', [frm.doc.name]), () => {
|
||||
window.open(`/app/list/${frm.doc.name}/list`);
|
||||
window.open(`/app/${frappe.router.slug(frm.doc.name)}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ from frappe.database.schema import validate_column_name, validate_column_length
|
|||
from frappe.model.docfield import supports_translation
|
||||
from frappe.modules.import_file import get_file_path
|
||||
from frappe.model.meta import Meta
|
||||
from frappe.desk.utils import get_doctype_route
|
||||
|
||||
|
||||
class InvalidFieldNameError(frappe.ValidationError): pass
|
||||
class UniqueFieldnameError(frappe.ValidationError): pass
|
||||
|
|
@ -79,7 +77,7 @@ class DocType(Document):
|
|||
self.make_repeatable()
|
||||
self.validate_nestedset()
|
||||
self.validate_website()
|
||||
self.validate_links_table_fieldnames()
|
||||
validate_links_table_fieldnames(self)
|
||||
|
||||
if not self.is_new():
|
||||
self.before_update = frappe.get_doc('DocType', self.name)
|
||||
|
|
@ -190,9 +188,6 @@ class DocType(Document):
|
|||
|
||||
def validate_website(self):
|
||||
"""Ensure that website generator has field 'route'"""
|
||||
if not self.istable and not self.route:
|
||||
self.route = get_doctype_route(self.name)
|
||||
|
||||
if self.route:
|
||||
self.route = self.route.strip('/')
|
||||
|
||||
|
|
@ -282,7 +277,6 @@ class DocType(Document):
|
|||
|
||||
def on_update(self):
|
||||
"""Update database schema, make controller templates if `custom` is not set and clear cache."""
|
||||
self.delete_duplicate_custom_fields()
|
||||
try:
|
||||
frappe.db.updatedb(self.name, Meta(self))
|
||||
except Exception as e:
|
||||
|
|
@ -321,18 +315,6 @@ class DocType(Document):
|
|||
|
||||
clear_linked_doctype_cache()
|
||||
|
||||
def delete_duplicate_custom_fields(self):
|
||||
if not (frappe.db.table_exists(self.name) and frappe.db.table_exists("Custom Field")):
|
||||
return
|
||||
|
||||
fields = [d.fieldname for d in self.fields if d.fieldtype in data_fieldtypes]
|
||||
if fields:
|
||||
frappe.db.sql('''delete from
|
||||
`tabCustom Field`
|
||||
where
|
||||
dt = {0} and fieldname in ({1})
|
||||
'''.format('%s', ', '.join(['%s'] * len(fields))), tuple([self.name] + fields), as_dict=True)
|
||||
|
||||
def sync_global_search(self):
|
||||
'''If global search settings are changed, rebuild search properties for this table'''
|
||||
global_search_fields_before_update = [d.fieldname for d in
|
||||
|
|
@ -666,24 +648,22 @@ class DocType(Document):
|
|||
if not re.match("^(?![\W])[^\d_\s][\w ]+$", name, **flags):
|
||||
frappe.throw(_("DocType's name should start with a letter and it can only consist of letters, numbers, spaces and underscores"), frappe.NameError)
|
||||
|
||||
def validate_links_table_fieldnames(self):
|
||||
"""Validate fieldnames in Links table"""
|
||||
if frappe.flags.in_patch: return
|
||||
if frappe.flags.in_fixtures: return
|
||||
if not self.links: return
|
||||
|
||||
for index, link in enumerate(self.links):
|
||||
meta = frappe.get_meta(link.link_doctype)
|
||||
if not meta.get_field(link.link_fieldname):
|
||||
message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype))
|
||||
frappe.throw(message, InvalidFieldNameError, _("Invalid Fieldname"))
|
||||
|
||||
def validate_links_table_fieldnames(meta):
|
||||
"""Validate fieldnames in Links table"""
|
||||
if frappe.flags.in_patch: return
|
||||
if frappe.flags.in_fixtures: return
|
||||
if not meta.links: return
|
||||
|
||||
for index, link in enumerate(meta.links):
|
||||
link_meta = frappe.get_meta(link.link_doctype)
|
||||
if not link_meta.get_field(link.link_fieldname):
|
||||
message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype))
|
||||
frappe.throw(message, InvalidFieldNameError, _("Invalid Fieldname"))
|
||||
|
||||
def validate_fields_for_doctype(doctype):
|
||||
doc = frappe.get_doc("DocType", doctype)
|
||||
doc.delete_duplicate_custom_fields()
|
||||
validate_fields(frappe.get_meta(doctype, cached=False))
|
||||
meta = frappe.get_meta(doctype, cached=False)
|
||||
validate_links_table_fieldnames(meta)
|
||||
validate_fields(meta)
|
||||
|
||||
# this is separate because it is also called via custom field
|
||||
def validate_fields(meta):
|
||||
|
|
|
|||
|
|
@ -5,12 +5,18 @@ from __future__ import unicode_literals
|
|||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.core.doctype.doctype.doctype import UniqueFieldnameError, IllegalMandatoryError, DoctypeLinkError, WrongOptionsDoctypeLinkError,\
|
||||
HiddenAndMandatoryWithoutDefaultError, CannotIndexedError, InvalidFieldNameError, CannotCreateStandardDoctypeError
|
||||
from frappe.core.doctype.doctype.doctype import (UniqueFieldnameError,
|
||||
IllegalMandatoryError,
|
||||
DoctypeLinkError,
|
||||
WrongOptionsDoctypeLinkError,
|
||||
HiddenAndMandatoryWithoutDefaultError,
|
||||
CannotIndexedError,
|
||||
InvalidFieldNameError,
|
||||
CannotCreateStandardDoctypeError,
|
||||
validate_links_table_fieldnames)
|
||||
|
||||
# test_records = frappe.get_test_records('DocType')
|
||||
|
||||
|
||||
class TestDocType(unittest.TestCase):
|
||||
def test_validate_name(self):
|
||||
self.assertRaises(frappe.NameError, new_doctype("_Some DocType").insert)
|
||||
|
|
@ -459,7 +465,7 @@ class TestDocType(unittest.TestCase):
|
|||
'link_doctype': "User",
|
||||
'link_fieldname': "first_name"
|
||||
})
|
||||
doc.validate_links_table_fieldnames() # no error
|
||||
validate_links_table_fieldnames(doc) # no error
|
||||
doc.links = [] # reset links table
|
||||
|
||||
# check invalid doctype
|
||||
|
|
@ -467,7 +473,7 @@ class TestDocType(unittest.TestCase):
|
|||
'link_doctype': "User2",
|
||||
'link_fieldname': "first_name"
|
||||
})
|
||||
self.assertRaises(frappe.DoesNotExistError, doc.validate_links_table_fieldnames)
|
||||
self.assertRaises(frappe.DoesNotExistError, validate_links_table_fieldnames, doc)
|
||||
doc.links = [] # reset links table
|
||||
|
||||
# check invalid fieldname
|
||||
|
|
@ -475,7 +481,7 @@ class TestDocType(unittest.TestCase):
|
|||
'link_doctype': "User",
|
||||
'link_fieldname': "a_field_that_does_not_exists"
|
||||
})
|
||||
self.assertRaises(InvalidFieldNameError, doc.validate_links_table_fieldnames)
|
||||
self.assertRaises(InvalidFieldNameError, validate_links_table_fieldnames, doc)
|
||||
|
||||
|
||||
def new_doctype(name, unique=0, depends_on='', fields=None):
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class TestUser(unittest.TestCase):
|
|||
frappe.db.set_value("System Settings", "System Settings", "enable_password_policy", 0)
|
||||
frappe.db.set_value("System Settings", "System Settings", "minimum_password_score", "")
|
||||
frappe.db.set_value("System Settings", "System Settings", "password_reset_limit", 3)
|
||||
frappe.set_user('Administrator')
|
||||
|
||||
def test_user_type(self):
|
||||
new_user = frappe.get_doc(dict(doctype='User', email='test-for-type@example.com',
|
||||
|
|
@ -106,13 +107,17 @@ class TestUser(unittest.TestCase):
|
|||
frappe.set_user("testperm@example.com")
|
||||
|
||||
me = frappe.get_doc("User", "testperm@example.com")
|
||||
self.assertRaises(frappe.PermissionError, me.add_roles, "System Manager")
|
||||
me.add_roles("System Manager")
|
||||
|
||||
# system manager is not added (it is reset)
|
||||
self.assertFalse('System Manager' in [d.role for d in me.roles])
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
me = frappe.get_doc("User", "testperm@example.com")
|
||||
me.add_roles("System Manager")
|
||||
|
||||
# system manager now added by Administrator
|
||||
self.assertTrue("System Manager" in [d.role for d in me.get("roles")])
|
||||
|
||||
# def test_deny_multiple_sessions(self):
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
"thread_notify",
|
||||
"send_me_a_copy",
|
||||
"allowed_in_mentions",
|
||||
"email_inbox",
|
||||
"user_emails",
|
||||
"sb_allow_modules",
|
||||
"modules_html",
|
||||
|
|
@ -641,11 +640,6 @@
|
|||
"link_doctype": "User Permission",
|
||||
"link_fieldname": "user"
|
||||
},
|
||||
{
|
||||
"group": "Settings",
|
||||
"link_doctype": "Assignment Rule",
|
||||
"link_fieldname": "user"
|
||||
},
|
||||
{
|
||||
"group": "Settings",
|
||||
"link_doctype": "Document Follow",
|
||||
|
|
@ -691,10 +685,11 @@
|
|||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"route": "user",
|
||||
"search_fields": "full_name",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "full_name",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
|
@ -85,9 +85,9 @@ class User(Document):
|
|||
|
||||
def validate_roles(self):
|
||||
if self.role_profile_name:
|
||||
role_profile = frappe.get_doc('Role Profile', self.role_profile_name)
|
||||
self.set('roles', [])
|
||||
self.append_roles(*[role.role for role in role_profile.roles])
|
||||
role_profile = frappe.get_doc('Role Profile', self.role_profile_name)
|
||||
self.set('roles', [])
|
||||
self.append_roles(*[role.role for role in role_profile.roles])
|
||||
|
||||
def validate_user_image(self):
|
||||
if self.user_image and len(self.user_image) > 2000:
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ frappe.PermissionEngine = class PermissionEngine {
|
|||
},
|
||||
callback: function (r) {
|
||||
r.message = $.map(r.message, function (p) {
|
||||
return $.format('<a href="/app/Form/User/{0}">{1}</a>', [p, p]);
|
||||
return $.format('<a href="/app/user/{0}">{1}</a>', [p, p]);
|
||||
});
|
||||
frappe.msgprint(__("Users with role {0}:", [__(role)])
|
||||
+ "<br>" + r.message.join("<br>"));
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ class Leaderboard {
|
|||
return fieldname === this.options.selected_filter_item;
|
||||
}));
|
||||
|
||||
const link = `/app/Form/${this.options.selected_doctype}/${item.name}`;
|
||||
const link = `/app/${frappe.router.slug(this.options.selected_doctype)}/${item.name}`;
|
||||
const name_html = item.formatted_name ?
|
||||
`<span class="text-muted ellipsis list-id">${item.formatted_name}</span>`
|
||||
: `<a class="grey list-id ellipsis" href="${link}"> ${item.name} </a>`;
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ import unittest
|
|||
import frappe.desk.form.document_follow as document_follow
|
||||
|
||||
class TestDocumentFollow(unittest.TestCase):
|
||||
|
||||
def test_add_subscription_and_send_mail(self):
|
||||
def test_document_follow(self):
|
||||
user = get_user()
|
||||
event_doc = get_event()
|
||||
|
||||
event_doc.description = "This is a test description for sending mail"
|
||||
event_doc.save(ignore_version=False)
|
||||
|
||||
doc = document_follow.follow_document("Event", event_doc.name , user.name, force=True)
|
||||
document_follow.unfollow_document("Event", event_doc.name, user.name)
|
||||
doc = document_follow.follow_document("Event", event_doc.name, user.name)
|
||||
self.assertEquals(doc.user, user.name)
|
||||
|
||||
document_follow.send_hourly_updates()
|
||||
|
|
@ -45,12 +45,15 @@ def get_event():
|
|||
return doc
|
||||
|
||||
def get_user():
|
||||
doc = frappe.new_doc("User")
|
||||
doc.email = "test@docsub.com"
|
||||
doc.first_name = "Test"
|
||||
doc.last_name = "User"
|
||||
doc.send_welcome_email = 0
|
||||
doc.document_follow_notify = 1
|
||||
doc.document_follow_frequency = "Hourly"
|
||||
doc.insert()
|
||||
if frappe.db.exists('User', 'test@docsub.com'):
|
||||
doc = frappe.get_doc('User', 'test@docsub.com')
|
||||
else:
|
||||
doc = frappe.new_doc("User")
|
||||
doc.email = "test@docsub.com"
|
||||
doc.first_name = "Test"
|
||||
doc.last_name = "User"
|
||||
doc.send_welcome_email = 0
|
||||
doc.document_follow_notify = 1
|
||||
doc.document_follow_frequency = "Hourly"
|
||||
doc.insert()
|
||||
return doc
|
||||
|
|
@ -198,7 +198,7 @@ frappe.ui.form.on('Notification', {
|
|||
frappe.notification.setup_example_message(frm);
|
||||
if (frm.doc.channel === 'SMS' && frm.doc.__islocal) {
|
||||
frm.set_df_property('channel',
|
||||
'description', `To use SMS Channel, initialize <a href="/app/Form/SMS Settings">SMS Settings</a>.`);
|
||||
'description', `To use SMS Channel, initialize <a href="/app/sms-settings">SMS Settings</a>.`);
|
||||
} else {
|
||||
frm.set_df_property('channel', 'description', ` `);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
frappe.ui.form.on("Google Calendar", {
|
||||
refresh: function(frm) {
|
||||
if (frm.is_new()) {
|
||||
frm.dashboard.set_headline(__("To use Google Calendar, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Calendar, enable {0}.", [`<a href='/app/google-settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on("import_google_calendar", (data) => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
frappe.ui.form.on('Google Contacts', {
|
||||
refresh: function(frm) {
|
||||
if (!frm.doc.enable) {
|
||||
frm.dashboard.set_headline(__("To use Google Contacts, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Contacts, enable {0}.", [`<a href='/app/google-settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on('import_google_contacts', (data) => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
frappe.ui.form.on('Google Drive', {
|
||||
refresh: function(frm) {
|
||||
if (!frm.doc.enable) {
|
||||
frm.dashboard.set_headline(__("To use Google Drive, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Drive, enable {0}.", [`<a href='/app/google-settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on("upload_to_google_drive", (data) => {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ def set_new_name(doc):
|
|||
frappe.get_meta(doc.doctype).get_field("name_case")
|
||||
)
|
||||
|
||||
|
||||
def set_name_from_naming_options(autoname, doc):
|
||||
"""
|
||||
Get a name based on the autoname field option
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ test_records = frappe.get_test_records('Print Format')
|
|||
class TestPrintFormat(unittest.TestCase):
|
||||
def test_print_user(self, style=None):
|
||||
print_html = frappe.get_print("User", "Administrator", style=style)
|
||||
self.assertTrue("<label>First Name</label>" in print_html)
|
||||
self.assertTrue(re.findall('<div class="col-xs-7[^"]*">[\s]*administrator[\s]*</div>', print_html))
|
||||
self.assertTrue("<label>First Name: </label>" in print_html)
|
||||
self.assertTrue(re.findall('<div class="col-xs-[^"]*">[\s]*administrator[\s]*</div>', print_html))
|
||||
return print_html
|
||||
|
||||
def test_print_user_standard(self):
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ frappe.quick_edit = (doctype, docname, fn) => {
|
|||
})
|
||||
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __(`Edit ${doctype} (${docname})`),
|
||||
title: __('Edit') + `${doctype} (${docname})`,
|
||||
fields: required,
|
||||
action: {
|
||||
primary: {
|
||||
|
|
@ -227,7 +227,7 @@ frappe.quick_edit = (doctype, docname, fn) => {
|
|||
`)
|
||||
$element.find('.qe-fp').click(() => {
|
||||
dialog.hide()
|
||||
frappe.set_route(`Form/${doctype}/${docname}`)
|
||||
frappe.set_route('Form', doctype, docname)
|
||||
})
|
||||
|
||||
dialog.show()
|
||||
|
|
@ -2221,7 +2221,7 @@ class extends Component {
|
|||
const item = { }
|
||||
|
||||
if ( ["Group", "Visitor"].includes(props.type) ) {
|
||||
item.route = `Form/Chat Room/${props.name}`
|
||||
item.route = `chat-room/${props.name}`
|
||||
|
||||
item.title = props.room_name
|
||||
item.image = props.avatar
|
||||
|
|
@ -2232,14 +2232,13 @@ class extends Component {
|
|||
item.subtitle = `${users.join(", ")} typing...`
|
||||
} else
|
||||
item.subtitle = props.type === "Group" ?
|
||||
__(`${props.users.length} ${frappe._.pluralize('member', props.users.length)}`)
|
||||
:
|
||||
""
|
||||
`${props.users.length} ${frappe._.pluralize('member', props.users.length)}`
|
||||
: ""
|
||||
}
|
||||
else {
|
||||
const user = props.owner === frappe.session.user ? frappe._.squash(props.users) : props.owner
|
||||
|
||||
item.route = `Form/User/${user}`
|
||||
item.route = `user/${user}`
|
||||
|
||||
item.title = frappe.user.full_name(user)
|
||||
item.image = frappe.user.image(user)
|
||||
|
|
@ -2405,7 +2404,7 @@ class extends Component {
|
|||
onclick: this.onclick},
|
||||
props.room_type === "Group" && !me?
|
||||
h("div",{class:"chat-bubble-author"},
|
||||
h("a", { onclick: () => { frappe.set_route(`Form/User/${props.user}`) } },
|
||||
h("a", { onclick: () => { frappe.set_route('Form', 'User', props.user) } },
|
||||
frappe.user.full_name(props.user)
|
||||
)
|
||||
) : null,
|
||||
|
|
|
|||
|
|
@ -996,7 +996,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
return;
|
||||
}
|
||||
|
||||
frappe.re_route[frappe.router.get_sub_path()] = 'Form/' + encodeURIComponent(this.doctype) + '/' + encodeURIComponent(name);
|
||||
frappe.re_route[frappe.router.get_sub_path()] = `${encodeURIComponent(frappe.router.slug(this.doctype))}/${encodeURIComponent(name)}`;
|
||||
frappe.set_route('Form', this.doctype, name);
|
||||
}
|
||||
|
||||
|
|
@ -1506,13 +1506,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
|
||||
const escaped_name = encodeURIComponent(value);
|
||||
|
||||
return repl('<a class="indicator %(color)s" href="/app/Form/%(doctype)s/%(escaped_name)s" data-doctype="%(doctype)s" data-name="%(name)s">%(label)s</a>', {
|
||||
color: get_color(doc || {}),
|
||||
doctype: df.options,
|
||||
escaped_name: escaped_name,
|
||||
label: label,
|
||||
name: value
|
||||
});
|
||||
return `<a class="indicator ${get_color(doc || {})}" href="/app/${frappe.router.slug(df.options)}/${escaped_name}" data-doctype="${doctype}" data-name="${value}">${label}</a>'`
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ frappe.ui.form.LinkedWith = class LinkedWith {
|
|||
return `<div class="list-row-container">
|
||||
<div class="level list-row small">
|
||||
<div class="level-left bold">
|
||||
<a href="/app/form/${frappe.router.slug(doctype)}/${doc.name}">${doc.name}</a>
|
||||
<a href="/app/${frappe.router.slug(doctype)}/${doc.name}">${doc.name}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ frappe.ui.form.MultiSelectDialog = class MultiSelectDialog {
|
|||
${
|
||||
head ? `<span class="ellipsis text-muted" title="${__(frappe.model.unscrub(column))}">${__(frappe.model.unscrub(column))}</span>`
|
||||
: (column !== "name" ? `<span class="ellipsis result-row" title="${__(result[column] || '')}">${__(result[column] || '')}</span>`
|
||||
: `<a href="${"/app/form/" + frappe.router.slug(me.doctype) + "/" + result[column] || ''}" class="list-id ellipsis" title="${__(result[column] || '')}">
|
||||
: `<a href="${"/app/" + frappe.router.slug(me.doctype) + "/" + result[column] || ''}" class="list-id ellipsis" title="${__(result[column] || '')}">
|
||||
${__(result[column] || '')}</a>`)}
|
||||
</div>`;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ class EventsView extends BaseNotificaitonsView {
|
|||
location = `, ${event.location}`;
|
||||
}
|
||||
|
||||
return `<a class="recent-item event" href="/app/Form/Event/${event.name}">
|
||||
return `<a class="recent-item event" href="/app/event/${event.name}">
|
||||
<div class="event-border" style="border-color: ${event.color}"></div>
|
||||
<div class="event-item">
|
||||
<div class="event-subject">${event.subject}</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Object.assign(frappe.energy_points, {
|
|||
const separator = `<span> - </span>`;
|
||||
const formatted_log = `<span>
|
||||
<!--${this.get_points(log.points)} -->
|
||||
<a href="/app/Form/Energy Point Log/${log.name}">${this.get_form_log_message(log)}</a>
|
||||
<a href="/app/energy-point-log/${log.name}">${this.get_form_log_message(log)}</a>
|
||||
${log.reason ? separator + log.reason : ''}
|
||||
</span>`;
|
||||
return formatted_log;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ frappe.help.help_links['modules/Setup'] = [
|
|||
{ label: 'Printing', url: 'http://frappe.github.io/erpnext/user/manual/en/setting-up/print/' },
|
||||
]
|
||||
|
||||
frappe.help.help_links['List/User'] = [
|
||||
frappe.help.help_links['user'] = [
|
||||
{ label: 'Adding Users', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/adding-users' },
|
||||
{ label: 'Rename User', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/rename-user' },
|
||||
]
|
||||
|
|
@ -25,19 +25,19 @@ frappe.help.help_links['user-permissions'] = [
|
|||
{ label: 'User Permissions', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/user-permissions' },
|
||||
]
|
||||
|
||||
frappe.help.help_links['Form/System Settings'] = [
|
||||
frappe.help.help_links['system-settings'] = [
|
||||
{ label: 'System Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/system-settings' },
|
||||
]
|
||||
|
||||
frappe.help.help_links['List/Email Account'] = [
|
||||
frappe.help.help_links['email-account'] = [
|
||||
{ label: 'Email Account', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-account' },
|
||||
]
|
||||
|
||||
frappe.help.help_links['List/Notification'] = [
|
||||
frappe.help.help_links['notification'] = [
|
||||
{ label: 'Notification', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-alerts' },
|
||||
]
|
||||
|
||||
frappe.help.help_links['Form/Print Settings'] = [
|
||||
frappe.help.help_links['print-settings'] = [
|
||||
{ label: 'Print Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-settings' },
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1145,17 +1145,17 @@ Object.assign(frappe.utils, {
|
|||
route = `${doctype_slug}/new`;
|
||||
break;
|
||||
case "Calendar":
|
||||
route = `${doctype_slug}/view/calendar/Default`;
|
||||
route = `${doctype_slug}/view/calendar/default`;
|
||||
break;
|
||||
default:
|
||||
frappe.throw({ message: __("Not a valid DocType view:") + item.doc_view, title: __("Unknown View") });
|
||||
frappe.throw({ message: __("Not a valid view:") + item.doc_view, title: __("Unknown View") });
|
||||
route = "";
|
||||
}
|
||||
}
|
||||
} else if (type === "report" && item.is_query_report) {
|
||||
route = "query-report/" + item.name;
|
||||
} else if (type === "report") {
|
||||
route = frappe.router.slug(item.doctype) + "/view/report/" + item.name;
|
||||
route = frappe.router.slug(item.name) + "/view/report";
|
||||
} else if (type === "page") {
|
||||
route = item.name;
|
||||
} else if (type === "dashboard") {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ frappe.views.Factory = class Factory {
|
|||
var page_name = frappe.get_route_str(),
|
||||
me = this;
|
||||
|
||||
if(frappe.pages[page_name] && !page_name.includes("Form/")) {
|
||||
if(frappe.pages[page_name]) {
|
||||
frappe.container.change_to(page_name);
|
||||
if(me.on_show) {
|
||||
me.on_show();
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
acc += '/' + curr;
|
||||
}
|
||||
return acc;
|
||||
}, '/app/List/File');
|
||||
}, '/app/file');
|
||||
|
||||
return `<a href="${route}">${folder}</a>`;
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ frappe.views.FormFactory = class FormFactory extends frappe.views.Factory {
|
|||
|
||||
if (!frappe.views.formview[doctype_layout]) {
|
||||
frappe.model.with_doctype(doctype, () => {
|
||||
this.page = frappe.container.add_page("form/" + doctype_layout);
|
||||
this.page = frappe.container.add_page(doctype_layout);
|
||||
frappe.views.formview[doctype_layout] = this.page;
|
||||
this.make_and_show(doctype, route);
|
||||
});
|
||||
|
|
@ -103,7 +103,7 @@ frappe.views.FormFactory = class FormFactory extends frappe.views.Factory {
|
|||
}
|
||||
|
||||
render(doctype_layout, name) {
|
||||
frappe.container.change_to("form/" + doctype_layout);
|
||||
frappe.container.change_to(doctype_layout);
|
||||
frappe.views.formview[doctype_layout].frm.refresh(name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ frappe.views.KanbanView.show_kanban_dialog = function (doctype, show_existing) {
|
|||
<p class="text-medium">
|
||||
${__('No fields found that can be used as a Kanban Column. Use the Customize Form to add a Custom Field of type "Select".')}
|
||||
</p>
|
||||
<a class="btn btn-xs btn-default" href="/app/form/customize-form?doc_type=${doctype}">
|
||||
<a class="btn btn-xs btn-default" href="/app/customize-form?doc_type=${doctype}">
|
||||
${__('Customize Form')}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
${no_of_reports_html}
|
||||
</p>`;
|
||||
|
||||
let get_item_html = item => `<a class="underline" href="/app/form/prepared-report/${item.name}">${item.name}</a>`;
|
||||
let get_item_html = item => `<a class="underline" href="/app/prepared-report/${item.name}">${item.name}</a>`;
|
||||
|
||||
warning_message += reports.map(get_item_html).join(', ');
|
||||
|
||||
|
|
@ -806,8 +806,8 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
const data = r.message;
|
||||
// Rememeber the name of Prepared Report doc
|
||||
this.prepared_report_doc_name = data.name;
|
||||
let alert_message = `Report initiated. You can track its status
|
||||
<a class="bold" href='/app/Form/Prepared Report/${data.name}'>here</a>`;
|
||||
let alert_message = `<a href='/app/prepared-report/${data.name}'>` +
|
||||
__('Report initiated, click to view status') + `</a>`;
|
||||
frappe.show_alert({message: alert_message, indicator: 'orange'}, 10);
|
||||
this.toggle_nothing_to_show(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -196,9 +196,9 @@ export default class OnboardingWidget extends Widget {
|
|||
show_form_tour(step) {
|
||||
let route;
|
||||
if (step.is_single) {
|
||||
route = `Form/${step.reference_document}`;
|
||||
route = frappe.router.slug(step.reference_document);
|
||||
} else {
|
||||
route = `Form/${step.reference_document}/${__('New')} ${__(step.reference_document)} 1`;
|
||||
route = `${frappe.router.slug(step.reference_document)}/new`;
|
||||
}
|
||||
|
||||
let current_route = frappe.get_route();
|
||||
|
|
@ -331,7 +331,7 @@ export default class OnboardingWidget extends Widget {
|
|||
frappe.route_hooks.after_save = callback;
|
||||
}
|
||||
|
||||
frappe.set_route(`Form/${step.reference_document}/${__('New')} ${__(step.reference_document)} 1`);
|
||||
frappe.set_route('Form', step.reference_document, 'new');
|
||||
}
|
||||
|
||||
show_quick_entry(step) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,6 @@ frappe.ui.form.on('Energy Point Log', {
|
|||
make_reference_name_link(frm) {
|
||||
let dt = frm.doc.reference_doctype;
|
||||
let dn = frm.doc.reference_name;
|
||||
frm.fields_dict.reference_name.$input_wrapper.find('.control-value').wrapInner(`<a href='/app/Form/${dt}/${dn}'></a>`);
|
||||
frm.fields_dict.reference_name.$input_wrapper.find('.control-value').wrapInner(`<a href='/app/${frappe.router.slug(dt)}/${dn}'></a>`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ def test_timeout_10():
|
|||
|
||||
def test_method():
|
||||
pass
|
||||
|
||||
class TestScheduler(TestCase):
|
||||
def setUp(self):
|
||||
purge_pending_jobs()
|
||||
|
|
@ -44,6 +43,8 @@ class TestScheduler(TestCase):
|
|||
job.db_set('last_execution', '2010-01-01 00:00:00')
|
||||
frappe.db.commit()
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
# 1st job is in the queue (or running), don't enqueue it again
|
||||
self.assertFalse(job.enqueue())
|
||||
frappe.db.sql('DELETE FROM `tabScheduled Job Log` WHERE `scheduled_job_type`=%s', job.name)
|
||||
|
|
|
|||
|
|
@ -181,12 +181,9 @@ def get_jobs(site=None, queue=None, key='method'):
|
|||
jobs = q.jobs + get_running_jobs_in_queue(q)
|
||||
for job in jobs:
|
||||
if job.kwargs.get('site'):
|
||||
if site is None:
|
||||
# if job belongs to current site, or if all jobs are requested
|
||||
if (job.kwargs['site'] == site) or site is None:
|
||||
add_to_dict(job)
|
||||
|
||||
elif job.kwargs['site'] == site:
|
||||
add_to_dict(job)
|
||||
|
||||
else:
|
||||
print('No site found in job', job.__dict__)
|
||||
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ def add_metatags(context):
|
|||
|
||||
# Get meta tags from Website Route meta
|
||||
# they can override the defaults set above
|
||||
route = context.route
|
||||
route = context.path
|
||||
if route == '':
|
||||
# homepage
|
||||
route = frappe.db.get_single_value('Website Settings', 'home_page')
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@
|
|||
"is_published_field": "published",
|
||||
"links": [],
|
||||
"max_attachments": 5,
|
||||
"modified": "2020-12-15 15:20:43.616046",
|
||||
"modified": "2020-12-23 14:28:36.311389",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Blog Post",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import unittest
|
|||
from frappe.utils import set_request
|
||||
from frappe.website.render import render
|
||||
|
||||
test_dependencies = ['Blog Post']
|
||||
class TestWebsiteRouteMeta(unittest.TestCase):
|
||||
def test_meta_tag_generation(self):
|
||||
blogs = frappe.get_all('Blog Post', fields=['name', 'route'],
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ frappe.listview_settings['Workflow Action'] = {
|
|||
? encodeURIComponent(docname)
|
||||
: docname;
|
||||
|
||||
const link = '/app/Form/' + doctype + '/' + docname;
|
||||
const link = '/app/' + frappe.router.slug(doctype) + '/' + docname;
|
||||
return link;
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue