Merge pull request #11917 from rmehta/unified-desk
feat(routing): New routing style, not using hashes, also /desk -> /app
This commit is contained in:
commit
742860f56e
91 changed files with 447 additions and 260 deletions
|
|
@ -2,7 +2,7 @@ context('API Resources', () => {
|
|||
before(() => {
|
||||
cy.visit('/login');
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
it('Creates two Comments', () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ context('Awesome Bar', () => {
|
|||
before(() => {
|
||||
cy.visit('/login');
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -16,7 +16,7 @@ context('Awesome Bar', () => {
|
|||
|
||||
cy.get('h1').should('contain', 'To Do');
|
||||
|
||||
cy.location('hash').should('eq', '#List/ToDo/List');
|
||||
cy.location('hash').should('eq', '/app/List/ToDo/List');
|
||||
});
|
||||
|
||||
it('find text in doctype list', () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('Control Barcode', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
function get_dialog_with_barcode() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('Control Duration', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
function get_dialog_with_duration(hide_days=0, hide_seconds=0) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
context('Control Link', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
cy.create_records({
|
||||
doctype: 'ToDo',
|
||||
description: 'this is a test todo for link'
|
||||
|
|
@ -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', `#Form/ToDo/${todos[0]}`);
|
||||
cy.location('hash').should('eq', `/app/Form/ToDo/${todos[0]}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('Control Rating', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
function get_dialog_with_rating() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const doctype_name = datetime_doctype.name;
|
|||
context('Control Date, Time and DateTime', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
return cy.insert_doc('DocType', datetime_doctype, true);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('Depends On', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
return frappe.call('frappe.tests.ui_test_helpers.create_doctype', {
|
||||
name: 'Test Depends On',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('FileUploader', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
function open_upload_dialog() {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
context('Form', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
return frappe.call("frappe.tests.ui_test_helpers.create_contact_records");
|
||||
});
|
||||
});
|
||||
it('create a new form', () => {
|
||||
cy.visit('/desk#Form/ToDo/New ToDo 1');
|
||||
cy.visit('/app/Form/ToDo/New ToDo 1');
|
||||
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,20 @@ context('Form', () => {
|
|||
}).as('form_save');
|
||||
cy.get('.primary-action').click();
|
||||
cy.wait('@form_save').its('status').should('eq', 200);
|
||||
cy.visit('/desk#List/ToDo');
|
||||
cy.location('hash').should('eq', '#List/ToDo/List');
|
||||
cy.visit('/app/List/ToDo');
|
||||
cy.location('hash').should('eq', '/app/List/ToDo/List');
|
||||
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('/desk#List/Contact');
|
||||
cy.location('hash').should('eq', '#List/Contact/List');
|
||||
cy.visit('/app/List/Contact');
|
||||
cy.location('hash').should('eq', '/app/List/Contact/List');
|
||||
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('/desk#Form/Contact/Test Form Contact 3');
|
||||
cy.visit('/app/Form/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 +50,7 @@ context('Form', () => {
|
|||
let website_input = 'website.in';
|
||||
let expectBackgroundColor = 'rgb(255, 220, 220)';
|
||||
|
||||
cy.visit('/desk#Form/Contact/New Contact 1');
|
||||
cy.visit('/app/Form/Contact/New Contact 1');
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
context('Grid Pagination', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
return frappe.call("frappe.tests.ui_test_helpers.create_contact_phone_nos_records");
|
||||
});
|
||||
});
|
||||
it('creates pages for child table', () => {
|
||||
cy.visit('/desk#Form/Contact/Test Contact');
|
||||
cy.visit('/app/Form/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('/desk#Form/Contact/Test Contact');
|
||||
cy.visit('/app/Form/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('/desk#Form/Contact/Test Contact');
|
||||
cy.visit('/app/Form/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('/desk#Form/Contact/Test Contact');
|
||||
// cy.visit('/app/Form/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();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
context('List View', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
return frappe.xcall("frappe.tests.ui_test_helpers.setup_workflow");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
context('List View Settings', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
it('Default settings', () => {
|
||||
cy.visit('/desk#List/DocType/List');
|
||||
cy.visit('/app/List/DocType/List');
|
||||
cy.get('.list-count').should('contain', "20 of");
|
||||
cy.get('.sidebar-stat').should('contain', "Tags");
|
||||
});
|
||||
it('disable count and sidebar stats then verify', () => {
|
||||
cy.wait(300);
|
||||
cy.visit('/desk#List/DocType/List');
|
||||
cy.visit('/app/List/DocType/List');
|
||||
cy.wait(300);
|
||||
cy.get('.list-count').should('contain', "20 of");
|
||||
cy.get('button').contains('Menu').click();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ context('Login', () => {
|
|||
cy.get('#login_password').type(Cypress.config('adminPassword'));
|
||||
|
||||
cy.get('.btn-login').click();
|
||||
cy.location('pathname').should('eq', '/desk');
|
||||
cy.location('pathname').should('eq', '/app');
|
||||
cy.window().its('frappe.session.user').should('eq', 'Administrator');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
context('Query Report', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
});
|
||||
|
||||
it('add custom column in report', () => {
|
||||
cy.visit('/desk#query-report/Permitted Documents For User');
|
||||
cy.visit('/app/query-report/Permitted Documents For User');
|
||||
|
||||
cy.get('div[class="page-form flex"]', {timeout: 60000}).should('have.length', 1).then(()=>{
|
||||
cy.get('#page-query-report input[data-fieldname="user"]').as('input');
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ context('Recorder', () => {
|
|||
});
|
||||
|
||||
it('Navigate to Recorder', () => {
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
cy.awesomebar('recorder');
|
||||
cy.get('h1').should('contain', 'Recorder');
|
||||
cy.location('hash').should('eq', '#recorder');
|
||||
});
|
||||
|
||||
it('Recorder Empty State', () => {
|
||||
cy.visit('/desk#recorder');
|
||||
cy.visit('/app/recorder');
|
||||
cy.get('.title-text').should('contain', 'Recorder');
|
||||
|
||||
cy.get('.indicator').should('contain', 'Inactive').should('have.class', 'red');
|
||||
|
|
@ -24,21 +24,21 @@ context('Recorder', () => {
|
|||
});
|
||||
|
||||
it('Recorder Start', () => {
|
||||
cy.visit('/desk#recorder');
|
||||
cy.visit('/app/recorder');
|
||||
cy.get('.primary-action').should('contain', 'Start').click();
|
||||
cy.get('.indicator').should('contain', 'Active').should('have.class', 'green');
|
||||
|
||||
cy.get('.msg-box').should('contain', 'No Requests');
|
||||
|
||||
cy.server();
|
||||
cy.visit('/desk#List/DocType/List');
|
||||
cy.visit('/app/List/DocType/List');
|
||||
cy.route('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh');
|
||||
cy.wait('@list_refresh');
|
||||
|
||||
cy.get('.title-text').should('contain', 'DocType');
|
||||
cy.get('.list-count').should('contain', '20 of ');
|
||||
|
||||
cy.visit('/desk#recorder');
|
||||
cy.visit('/app/recorder');
|
||||
cy.get('.title-text').should('contain', 'Recorder');
|
||||
cy.get('.result-list').should('contain', '/api/method/frappe.desk.reportview.get');
|
||||
|
||||
|
|
@ -48,11 +48,11 @@ context('Recorder', () => {
|
|||
});
|
||||
|
||||
it('Recorder View Request', () => {
|
||||
cy.visit('/desk#recorder');
|
||||
cy.visit('/app/recorder');
|
||||
cy.get('.primary-action').should('contain', 'Start').click();
|
||||
|
||||
cy.server();
|
||||
cy.visit('/desk#List/DocType/List');
|
||||
cy.visit('/app/List/DocType/List');
|
||||
cy.route('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh');
|
||||
cy.wait('@list_refresh');
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ context('Recorder', () => {
|
|||
// temporarily commenting out theses tests as they seem to be
|
||||
// randomly failing maybe due a backround event
|
||||
|
||||
// cy.visit('/desk#recorder');
|
||||
// cy.visit('/app/recorder');
|
||||
|
||||
// cy.get('.list-row-container span').contains('/api/method/frappe').click();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ context('Relative Timeframe', () => {
|
|||
});
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
frappe.call("frappe.tests.ui_test_helpers.create_todo_records");
|
||||
});
|
||||
});
|
||||
it('sets relative timespan filter for last week and filters list', () => {
|
||||
cy.visit('/desk#List/ToDo/List');
|
||||
cy.visit('/app/List/ToDo/List');
|
||||
cy.get('.list-row:contains("this is fourth todo")').should('exist');
|
||||
cy.get('.tag-filters-area .btn:contains("Add Filter")').click();
|
||||
cy.get('.fieldname-select-area').should('exist');
|
||||
|
|
@ -29,7 +29,7 @@ context('Relative Timeframe', () => {
|
|||
cy.wait('@save_user_settings');
|
||||
});
|
||||
it('sets relative timespan filter for next week and filters list', () => {
|
||||
cy.visit('/desk#List/ToDo/List');
|
||||
cy.visit('/app/List/ToDo/List');
|
||||
cy.get('.list-row:contains("this is fourth todo")').should('exist');
|
||||
cy.get('.tag-filters-area .btn:contains("Add Filter")').click();
|
||||
cy.get('.fieldname-select-area input').type("Due Date{enter}", { delay: 100 });
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const doctype_name = custom_submittable_doctype.name;
|
|||
context('Report View', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.visit('/desk#workspace/Website');
|
||||
cy.visit('/app/workspace/Website');
|
||||
cy.insert_doc('DocType', custom_submittable_doctype, true);
|
||||
cy.clear_cache();
|
||||
cy.insert_doc(doctype_name, {
|
||||
|
|
@ -18,7 +18,7 @@ context('Report View', () => {
|
|||
it('Field with enabled allow_on_submit should be editable.', () => {
|
||||
cy.server();
|
||||
cy.route('POST', 'api/method/frappe.client.set_value').as('value-update');
|
||||
cy.visit(`/desk#List/${doctype_name}/Report`);
|
||||
cy.visit(`/app/List/${doctype_name}/Report`);
|
||||
// check status column added from docstatus
|
||||
cy.get('.dt-row-0 > .dt-cell--col-3').should('contain', 'Submitted');
|
||||
let cell = cy.get('.dt-row-0 > .dt-cell--col-4');
|
||||
|
|
|
|||
|
|
@ -210,13 +210,13 @@ Cypress.Commands.add('awesomebar', text => {
|
|||
|
||||
Cypress.Commands.add('new_form', doctype => {
|
||||
let route = `Form/${doctype}/New ${doctype} 1`;
|
||||
cy.visit(`/desk#${route}`);
|
||||
cy.visit(`/app/${route}`);
|
||||
cy.get('body').should('have.attr', 'data-route', route);
|
||||
cy.get('body').should('have.attr', 'data-ajax-state', 'complete');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('go_to_list', doctype => {
|
||||
cy.visit(`/desk#List/${doctype}/List`);
|
||||
cy.visit(`/app/List/${doctype}/List`);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('clear_cache', () => {
|
||||
|
|
|
|||
|
|
@ -1611,7 +1611,7 @@ def log_error(message=None, title=_("Error")):
|
|||
method=title)).insert(ignore_permissions=True)
|
||||
|
||||
def get_desk_link(doctype, name):
|
||||
html = '<a href="#Form/{doctype}/{name}" style="font-weight: bold;">{doctype_local} {name}</a>'
|
||||
html = '<a href="/app/Form/{doctype}/{name}" style="font-weight: bold;">{doctype_local} {name}</a>'
|
||||
return html.format(
|
||||
doctype=doctype,
|
||||
name=name,
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ class LoginManager:
|
|||
frappe.local.cookie_manager.set_cookie("system_user", "yes")
|
||||
if not resume:
|
||||
frappe.local.response['message'] = 'Logged In'
|
||||
frappe.local.response["home_page"] = "/desk"
|
||||
frappe.local.response["home_page"] = "/app"
|
||||
|
||||
if not resume:
|
||||
frappe.response["full_name"] = self.full_name
|
||||
|
|
|
|||
|
|
@ -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="#Form/Customize Form">${__('Customize Form')}</a>`;
|
||||
let customize_form_link = `<a href="/app/Form/Customize Form">${__('Customize Form')}</a>`;
|
||||
frm.dashboard.set_headline(__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [customize_form_link]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ def get_bootinfo():
|
|||
bootinfo.frequently_visited_links = frequently_visited_links()
|
||||
bootinfo.link_preview_doctypes = get_link_preview_doctypes()
|
||||
bootinfo.additional_filters_config = get_additional_filters_from_hooks()
|
||||
bootinfo.desk_settings = get_desk_settings()
|
||||
|
||||
return bootinfo
|
||||
|
||||
|
|
@ -225,7 +226,7 @@ def load_translations(bootinfo):
|
|||
def get_user_info():
|
||||
user_info = frappe.db.get_all('User', fields=['`name`', 'full_name as fullname', 'user_image as image',
|
||||
'gender', 'email', 'username', 'bio', 'location', 'interest', 'banner_image', 'allowed_in_mentions'],
|
||||
filters=dict(enabled=1, user_type=['!=', 'Website User']))
|
||||
filters=dict(enabled=1))
|
||||
|
||||
user_info_map = {d.name: d for d in user_info}
|
||||
|
||||
|
|
@ -308,3 +309,16 @@ def get_additional_filters_from_hooks():
|
|||
|
||||
return filter_config
|
||||
|
||||
def get_desk_settings():
|
||||
role_list = frappe.get_all('Role', fields=['*'], filters=dict(
|
||||
name=['in', frappe.get_roles()]
|
||||
))
|
||||
desk_settings = {}
|
||||
|
||||
from frappe.core.doctype.role.role import desk_properties
|
||||
|
||||
for role in role_list:
|
||||
for key in desk_properties:
|
||||
desk_settings[key] = desk_settings.get(key) or role.get(key)
|
||||
|
||||
return desk_settings
|
||||
|
|
@ -11,7 +11,7 @@ frappe.listview_settings["Deleted Document"] = {
|
|||
if (r.message) {
|
||||
function body(docnames) {
|
||||
const html = docnames.map(docname => {
|
||||
return `<li><a href='/desk#Form/Deleted Document/${docname}'>${docname}</a></li>`;
|
||||
return `<li><a href='/app/Form/Deleted Document/${docname}'>${docname}</a></li>`;
|
||||
});
|
||||
return "<br><ul>" + html.join("");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ 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]), () => {
|
||||
frappe.set_route('Form', frm.doc.name);
|
||||
window.open(`/app/Form/${frm.doc.name}`);
|
||||
// frappe.set_route('Form', frm.doc.name);
|
||||
});
|
||||
} else {
|
||||
frm.add_custom_button(__('Go to {0} List', [frm.doc.name]), () => {
|
||||
frappe.set_route('List', frm.doc.name, 'List');
|
||||
window.open(`/app/List/${frm.doc.name}/List`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def has_unseen_error_log(user):
|
|||
def _get_response(show_alert=True):
|
||||
return {
|
||||
'show_alert': True,
|
||||
'message': _("You have unseen {0}").format('<a href="/desk#List/Error%20Log/List"> Error Logs </a>')
|
||||
'message': _("You have unseen {0}").format('<a href="/app/List/Error%20Log/List"> Error Logs </a>')
|
||||
}
|
||||
|
||||
if frappe.db.sql_list("select name from `tabError Log` where seen = 0 limit 1"):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import frappe
|
||||
from ..role import desk_properties
|
||||
|
||||
def execute():
|
||||
for role in frappe.get_all('Role', ['name', 'desk_access']):
|
||||
role_doc = frappe.get_doc('Role', role.name)
|
||||
for key in desk_properties:
|
||||
role_doc.set(key, role_doc.desk_access)
|
||||
role_doc.save()
|
||||
|
|
@ -13,7 +13,19 @@
|
|||
"column_break_4",
|
||||
"disabled",
|
||||
"desk_access",
|
||||
"two_factor_auth"
|
||||
"two_factor_auth",
|
||||
"navigation_settings_section",
|
||||
"search_bar",
|
||||
"notification",
|
||||
"chat",
|
||||
"list_settings_section",
|
||||
"list_sidebar",
|
||||
"bulk_actions",
|
||||
"view_switcher",
|
||||
"form_settings_section",
|
||||
"form_sidebar",
|
||||
"timeline",
|
||||
"dashboard"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
|
|
@ -60,12 +72,82 @@
|
|||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "navigation_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Navigation Settings"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "search_bar",
|
||||
"fieldtype": "Check",
|
||||
"label": "Search Bar"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "notification",
|
||||
"fieldtype": "Check",
|
||||
"label": "Notification"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "chat",
|
||||
"fieldtype": "Check",
|
||||
"label": "Chat"
|
||||
},
|
||||
{
|
||||
"fieldname": "list_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "List Settings"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "list_sidebar",
|
||||
"fieldtype": "Check",
|
||||
"label": "Sidebar"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "bulk_actions",
|
||||
"fieldtype": "Check",
|
||||
"label": "Bulk Actions"
|
||||
},
|
||||
{
|
||||
"fieldname": "form_settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Form Settings"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "form_sidebar",
|
||||
"fieldtype": "Check",
|
||||
"label": "Sidebar"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "timeline",
|
||||
"fieldtype": "Check",
|
||||
"label": "Timeline"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "dashboard",
|
||||
"fieldtype": "Check",
|
||||
"label": "Dashboard"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "view_switcher",
|
||||
"fieldtype": "Check",
|
||||
"label": "View Switcher"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-bookmark",
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-06 15:42:59.036960",
|
||||
"modified": "2020-11-11 17:29:13.149522",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Role",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import frappe
|
|||
|
||||
from frappe.model.document import Document
|
||||
|
||||
desk_properties = ("search_bar", "notification", "chat", "list_sidebar",
|
||||
"bulk_actions", "view_switcher", "form_sidebar", "timeline", "dashboard")
|
||||
|
||||
class Role(Document):
|
||||
def before_rename(self, old, new, merge=False):
|
||||
if old in ("Guest", "Administrator", "System Manager", "All"):
|
||||
|
|
@ -16,11 +19,25 @@ class Role(Document):
|
|||
|
||||
def validate(self):
|
||||
if self.disabled:
|
||||
if self.name in ("Guest", "Administrator", "System Manager", "All"):
|
||||
frappe.throw(frappe._("Standard roles cannot be disabled"))
|
||||
else:
|
||||
frappe.db.sql("delete from `tabHas Role` where role = %s", self.name)
|
||||
frappe.clear_cache()
|
||||
self.disable_role()
|
||||
else:
|
||||
self.set_desk_properties()
|
||||
|
||||
def disable_role(self):
|
||||
if self.name in ("Guest", "Administrator", "System Manager", "All"):
|
||||
frappe.throw(frappe._("Standard roles cannot be disabled"))
|
||||
else:
|
||||
self.remove_roles()
|
||||
|
||||
def set_desk_properties(self):
|
||||
# set if desk_access is not allowed, unset all desk properties
|
||||
if not self.desk_access:
|
||||
for key in desk_properties:
|
||||
self.set(key, 0)
|
||||
|
||||
def remove_roles(self):
|
||||
frappe.db.sql("delete from `tabHas Role` where role = %s", self.name)
|
||||
frappe.clear_cache()
|
||||
|
||||
def on_update(self):
|
||||
'''update system user desk access if this has changed in this update'''
|
||||
|
|
|
|||
|
|
@ -182,20 +182,17 @@ class User(Document):
|
|||
|
||||
|
||||
def share_with_self(self):
|
||||
if self.user_type=="System User":
|
||||
frappe.share.add(self.doctype, self.name, self.name, write=1, share=1,
|
||||
flags={"ignore_share_permission": True})
|
||||
else:
|
||||
frappe.share.remove(self.doctype, self.name, self.name,
|
||||
flags={"ignore_share_permission": True, "ignore_permissions": True})
|
||||
frappe.share.add(self.doctype, self.name, self.name, write=1, share=1,
|
||||
flags={"ignore_share_permission": True})
|
||||
|
||||
def validate_share(self, docshare):
|
||||
if docshare.user == self.name:
|
||||
if self.user_type=="System User":
|
||||
if docshare.share != 1:
|
||||
frappe.throw(_("Sorry! User should have complete access to their own record."))
|
||||
else:
|
||||
frappe.throw(_("Sorry! Sharing with Website User is prohibited."))
|
||||
pass
|
||||
# if docshare.user == self.name:
|
||||
# if self.user_type=="System User":
|
||||
# if docshare.share != 1:
|
||||
# frappe.throw(_("Sorry! User should have complete access to their own record."))
|
||||
# else:
|
||||
# frappe.throw(_("Sorry! Sharing with Website User is prohibited."))
|
||||
|
||||
def send_password_notification(self, new_password):
|
||||
try:
|
||||
|
|
@ -580,7 +577,7 @@ def update_password(new_password, logout_all_sessions=0, key=None, old_password=
|
|||
frappe.db.set_value("User", user, "reset_password_key", "")
|
||||
|
||||
if user_doc.user_type == "System User":
|
||||
return "/desk"
|
||||
return "/app"
|
||||
else:
|
||||
return redirect_url if redirect_url else "/"
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ frappe.PermissionEngine = class PermissionEngine {
|
|||
},
|
||||
callback: function (r) {
|
||||
r.message = $.map(r.message, function (p) {
|
||||
return $.format('<a href="#Form/User/{0}">{1}</a>', [p, p]);
|
||||
return $.format('<a href="/app/Form/User/{0}">{1}</a>', [p, p]);
|
||||
});
|
||||
frappe.msgprint(__("Users with role {0}:", [__(role)])
|
||||
+ "<br>" + r.message.join("<br>"));
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<li>{%= __("Permissions are set on Roles and Document Types (called DocTypes) by setting rights like Read, Write, Create, Delete, Submit, Cancel, Amend, Report, Import, Export, Print, Email and Set User Permissions.") %}</li>
|
||||
<li>{%= __("Permissions get applied on Users based on what Roles they are assigned.") %}</li>
|
||||
<li>{%= __("Roles can be set for users from their User page.") %}
|
||||
<a href="#List/User">{%= __("Setup > User") %}</a></li>
|
||||
<li>{%= __("The system provides many pre-defined roles. You can add new roles to set finer permissions.") %}<a href="#List/Role"> {%= __("Add a New Role") %}</a></li>
|
||||
<a href="/app/List/User">{%= __("Setup > User") %}</a></li>
|
||||
<li>{%= __("The system provides many pre-defined roles. You can add new roles to set finer permissions.") %}<a href="/app/List/Role"> {%= __("Add a New Role") %}</a></li>
|
||||
<li>{%= __("Permissions are automatically applied to Standard Reports and searches.") %}</li>
|
||||
<li>{%= __("As a best practice, do not assign the same set of permission rule to different Roles. Instead, set multiple Roles to the same User.") %}</li>
|
||||
</ol>
|
||||
|
|
@ -24,13 +24,13 @@
|
|||
<li>{%= __("Permissions at level 0 are Document Level permissions, i.e. they are primary for access to the document.") %}</li>
|
||||
<li>{%= __("If a Role does not have access at Level 0, then higher levels are meaningless.") %}</li>
|
||||
<li>{%= __("Permissions at higher levels are Field Level permissions. All Fields have a Permission Level set against them and the rules defined at that permissions apply to the field. This is useful in case you want to hide or make certain field read-only for certain Roles.") %}</li>
|
||||
<li>{%= __("You can use Customize Form to set levels on fields.") %} <a href="#Form/Customize Form">{%= __("Setup > Customize Form") %}</a></li>
|
||||
<li>{%= __("You can use Customize Form to set levels on fields.") %} <a href="/app/Form/Customize Form">{%= __("Setup > Customize Form") %}</a></li>
|
||||
</ol>
|
||||
<hr>
|
||||
<h4>{%= __("User Permissions") %}:</h4>
|
||||
<ol>
|
||||
<li>{%= __("User Permissions are used to limit users to specific records.") %}
|
||||
<a href="#List/User Permission">{%= __("Setup > User Permissions") %}</a></li>
|
||||
<a href="/app/List/User Permission">{%= __("Setup > User Permissions") %}</a></li>
|
||||
<li>{%= __("Select Document Types to set which User Permissions are used to limit access.") %}</li>
|
||||
<li>{%= __("Once you have set this, the users will only be able access documents (eg. Blog Post) where the link exists (eg. Blogger).") %}</li>
|
||||
<li>{%= __("Apart from System Manager, roles with Set User Permissions right can set permissions for other users for that Document Type.") %}</li>
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ class TestCustomizeForm(unittest.TestCase):
|
|||
testdt1.delete()
|
||||
|
||||
def test_custom_action(self):
|
||||
test_route = '#List/DocType'
|
||||
test_route = '/app/List/DocType'
|
||||
|
||||
# create a dummy action (route)
|
||||
d = self.get_customize_form("Event")
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ def get_non_standard_warning_message(non_standard_docs_map):
|
|||
def get_html(docs, doctype):
|
||||
html = '<p>{}</p>'.format(frappe.bold(doctype))
|
||||
for doc in docs:
|
||||
html += '<div><a href="#Form/{doctype}/{doc}">{doc}</a></div>'.format(doctype=doctype, doc=doc)
|
||||
html += '<div><a href="/app/Form/{doctype}/{doc}">{doc}</a></div>'.format(doctype=doctype, doc=doc)
|
||||
html += '<br>'
|
||||
return html
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from frappe.cache_manager import build_domain_restriced_doctype_cache, build_dom
|
|||
@frappe.whitelist()
|
||||
def get(module):
|
||||
"""Returns data (sections, list of reports, counts) to render module view in desk:
|
||||
`/desk/#Module/[name]`."""
|
||||
`/app/#Module/[name]`."""
|
||||
data = get_data(module)
|
||||
|
||||
out = {
|
||||
|
|
@ -90,7 +90,7 @@ def get_data(module, build=True):
|
|||
return data
|
||||
|
||||
def build_config_from_file(module):
|
||||
"""Build module info from `app/config/desktop.py` files."""
|
||||
"""Build module info from `app/config/apptop.py` files."""
|
||||
data = []
|
||||
module = frappe.scrub(module)
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ def add_section(data, label, icon, items):
|
|||
|
||||
|
||||
def add_custom_doctypes(data, doctype_info):
|
||||
"""Adds Custom DocTypes to modules setup via `config/desktop.py`."""
|
||||
"""Adds Custom DocTypes to modules setup via `config/apptop.py`."""
|
||||
add_section(data, _("Documents"), "fa fa-star",
|
||||
[d for d in doctype_info if (d.custom and d.document_type in ("Document", "Transaction"))])
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ def config_exists(app, module):
|
|||
return False
|
||||
|
||||
def add_setup_section(config, app, module, label, icon):
|
||||
"""Add common sections to `/desk#Module/Setup`"""
|
||||
"""Add common sections to `/app/Module/Setup`"""
|
||||
try:
|
||||
setup_section = get_setup_section(app, module, label, icon)
|
||||
if setup_section:
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ class Leaderboard {
|
|||
return fieldname === this.options.selected_filter_item;
|
||||
}));
|
||||
|
||||
const link = `#Form/${this.options.selected_doctype}/${item.name}`;
|
||||
const link = `/app/Form/${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>`;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
|
|||
}
|
||||
setTimeout(function () {
|
||||
// Reload
|
||||
window.location.href = '/desk';
|
||||
window.location.href = '/app';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ def execute(filters=None):
|
|||
for todo in todo_list:
|
||||
if todo.owner==frappe.session.user or todo.assigned_by==frappe.session.user:
|
||||
if todo.reference_type:
|
||||
todo.reference = """<a href="#Form/%s/%s">%s: %s</a>""" % (todo.reference_type,
|
||||
todo.reference = """<a href="/app/Form/%s/%s">%s: %s</a>""" % (todo.reference_type,
|
||||
todo.reference_name, todo.reference_type, todo.reference_name)
|
||||
else:
|
||||
todo.reference = None
|
||||
|
|
|
|||
|
|
@ -203,7 +203,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="#Form/SMS Settings">SMS Settings</a>.`);
|
||||
'description', `To use SMS Channel, initialize <a href="/app/Form/SMS Settings">SMS Settings</a>.`);
|
||||
} else {
|
||||
frm.set_df_property('channel', 'description', ` `);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,16 +29,18 @@ page_js = {
|
|||
|
||||
# website
|
||||
app_include_js = [
|
||||
"assets/js/libs.min.js",
|
||||
"assets/js/desk.min.js",
|
||||
"assets/js/list.min.js",
|
||||
"assets/js/form.min.js",
|
||||
"assets/js/control.min.js",
|
||||
"assets/js/report.min.js",
|
||||
"/assets/js/libs.min.js",
|
||||
"/assets/js/desk.min.js",
|
||||
"/assets/js/list.min.js",
|
||||
"/assets/js/form.min.js",
|
||||
"/assets/js/control.min.js",
|
||||
"/assets/js/report.min.js",
|
||||
]
|
||||
app_include_css = [
|
||||
"assets/css/desk.min.css",
|
||||
"assets/css/report.min.css",
|
||||
"/assets/css/desk.min.css",
|
||||
"/assets/css/list.min.css",
|
||||
"/assets/css/form.min.css",
|
||||
"/assets/css/report.min.css",
|
||||
]
|
||||
|
||||
doctype_js = {
|
||||
|
|
|
|||
|
|
@ -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='#Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Calendar, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on("import_google_calendar", (data) => {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ def authorize_access(g_calendar, reauthorize=None):
|
|||
frappe.db.commit()
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = "/desk#Form/{0}/{1}".format(quote("Google Calendar"), quote(google_calendar.name))
|
||||
frappe.local.response["location"] = "/app/Form/{0}/{1}".format(quote("Google Calendar"), quote(google_calendar.name))
|
||||
|
||||
frappe.msgprint(_("Google Calendar has been configured."))
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -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='#Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Contacts, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on('import_google_contacts', (data) => {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ def authorize_access(g_contact, reauthorize=None):
|
|||
frappe.db.commit()
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = "/desk#Form/Google%20Contacts/{}".format(google_contact.name)
|
||||
frappe.local.response["location"] = "/app/Form/Google%20Contacts/{}".format(google_contact.name)
|
||||
|
||||
frappe.msgprint(_("Google Contacts has been configured."))
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -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='#Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
frm.dashboard.set_headline(__("To use Google Drive, enable {0}.", [`<a href='/app/Form/Google Settings'>${__('Google Settings')}</a>`]));
|
||||
}
|
||||
|
||||
frappe.realtime.on("upload_to_google_drive", (data) => {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ def authorize_access(reauthorize=None):
|
|||
frappe.db.commit()
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = "/desk#Form/{0}".format(quote("Google Drive"))
|
||||
frappe.local.response["location"] = "/app/Form/{0}".format(quote("Google Drive"))
|
||||
|
||||
frappe.msgprint(_("Google Drive has been configured."))
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -287,8 +287,8 @@ def check_if_doc_is_dynamically_linked(doc, method="Delete"):
|
|||
raise_link_exists_exception(doc, reference_doctype, reference_docname, at_position)
|
||||
|
||||
def raise_link_exists_exception(doc, reference_doctype, reference_docname, row=''):
|
||||
doc_link = '<a href="#Form/{0}/{1}">{1}</a>'.format(doc.doctype, doc.name)
|
||||
reference_link = '<a href="#Form/{0}/{1}">{1}</a>'.format(reference_doctype, reference_docname)
|
||||
doc_link = '<a href="/app/Form/{0}/{1}">{1}</a>'.format(doc.doctype, doc.name)
|
||||
reference_link = '<a href="/app/Form/{0}/{1}">{1}</a>'.format(reference_doctype, reference_docname)
|
||||
|
||||
#hack to display Single doctype only once in message
|
||||
if reference_doctype == reference_docname:
|
||||
|
|
|
|||
|
|
@ -1188,8 +1188,8 @@ class Document(BaseDocument):
|
|||
doc.set(fieldname, flt(doc.get(fieldname), self.precision(fieldname, doc.parentfield)))
|
||||
|
||||
def get_url(self):
|
||||
"""Returns Desk URL for this document. `/desk#Form/{doctype}/{name}`"""
|
||||
return "/desk#Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name)
|
||||
"""Returns Desk URL for this document. `/app/Form/{doctype}/{name}`"""
|
||||
return "/app/Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name)
|
||||
|
||||
def add_comment(self, comment_type='Comment', text=None, comment_email=None, link_doctype=None, link_name=None, comment_by=None):
|
||||
"""Add a comment to this document.
|
||||
|
|
|
|||
|
|
@ -318,3 +318,4 @@ frappe.patches.v13_0.web_template_set_module #2020-10-05
|
|||
frappe.patches.v13_0.remove_custom_link
|
||||
execute:frappe.delete_doc("DocType", "Footer Item")
|
||||
frappe.patches.v13_0.replace_field_target_with_open_in_new_tab
|
||||
frappe.core.doctype.role.patches.v13_set_default_desk_properties
|
||||
|
|
|
|||
|
|
@ -73,19 +73,9 @@ frappe.Application = Class.extend({
|
|||
|
||||
this.set_rtl();
|
||||
|
||||
if (frappe.boot) {
|
||||
if (localStorage.getItem("session_last_route")) {
|
||||
window.location.hash = localStorage.getItem("session_last_route");
|
||||
localStorage.removeItem("session_last_route");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// page container
|
||||
this.make_page_container();
|
||||
|
||||
// route to home page
|
||||
frappe.route();
|
||||
this.set_route();
|
||||
|
||||
// trigger app startup
|
||||
$(document).trigger('startup');
|
||||
|
|
@ -155,7 +145,7 @@ frappe.Application = Class.extend({
|
|||
});
|
||||
}, 300000); // check every 5 minutes
|
||||
|
||||
if(frappe.user.has_role("System Manager")){
|
||||
if (frappe.user.has_role("System Manager")) {
|
||||
setInterval(function() {
|
||||
frappe.call({
|
||||
method: 'frappe.core.doctype.log_settings.log_settings.has_unseen_error_log',
|
||||
|
|
@ -164,7 +154,7 @@ frappe.Application = Class.extend({
|
|||
},
|
||||
callback: function(r) {
|
||||
console.log(r);
|
||||
if(r.message.show_alert){
|
||||
if (r.message.show_alert) {
|
||||
frappe.show_alert({
|
||||
indicator: 'red',
|
||||
message: r.message.message
|
||||
|
|
@ -179,6 +169,19 @@ frappe.Application = Class.extend({
|
|||
this.fetch_tags();
|
||||
},
|
||||
|
||||
set_route() {
|
||||
if (frappe.boot && localStorage.getItem("session_last_route")) {
|
||||
frappe.set_route(localStorage.getItem("session_last_route"));
|
||||
localStorage.removeItem("session_last_route");
|
||||
} else if (frappe._cur_route) {
|
||||
// go to the appropriate sub-path
|
||||
frappe.set_route(frappe._cur_route);
|
||||
} else {
|
||||
// route to home page
|
||||
frappe.route();
|
||||
}
|
||||
},
|
||||
|
||||
setup_frappe_vue() {
|
||||
Vue.prototype.__ = window.__;
|
||||
Vue.prototype.frappe = window.frappe;
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
return;
|
||||
}
|
||||
|
||||
frappe.re_route[window.location.hash] = '#Form/' + encodeURIComponent(this.doctype) + '/' + encodeURIComponent(name);
|
||||
frappe.re_route[frappe.get_sub_path()] = 'Form/' + encodeURIComponent(this.doctype) + '/' + encodeURIComponent(name);
|
||||
frappe.set_route('Form', this.doctype, name);
|
||||
}
|
||||
|
||||
|
|
@ -1522,7 +1522,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
|
||||
const escaped_name = encodeURIComponent(value);
|
||||
|
||||
return repl('<a class="indicator %(color)s" href="#Form/%(doctype)s/%(escaped_name)s" data-doctype="%(doctype)s" data-name="%(name)s">%(label)s</a>', {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ frappe.form.formatters = {
|
|||
{onclick: docfield.link_onclick.replace(/"/g, '"'), value:value});
|
||||
} else if(docfield && doctype) {
|
||||
return `<a
|
||||
href="#Form/${encodeURIComponent(doctype)}/${encodeURIComponent(original_value)}"
|
||||
href="/app/Form/${encodeURIComponent(doctype)}/${encodeURIComponent(original_value)}"
|
||||
data-doctype="${doctype}"
|
||||
data-name="${original_value}">
|
||||
${__(options && options.label || value)}</a>`
|
||||
|
|
|
|||
|
|
@ -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="#Form/${doctype}/${doc.name}">${doc.name}</a>
|
||||
<a href="/app/Form/${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="${"#Form/" + me.doctype + "/" + result[column] || ''}" class="list-id ellipsis" title="${__(result[column] || '')}">
|
||||
: `<a href="${"/app/Form/" + me.doctype + "/" + result[column] || ''}" class="list-id ellipsis" title="${__(result[column] || '')}">
|
||||
${__(result[column] || '')}</a>`)}
|
||||
</div>`;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
{% if(addr_list[i].is_shipping_address) { %}
|
||||
<span class="text-muted">({%= __("Shipping") %})</span>{% } %}
|
||||
|
||||
<a href="#Form/Address/{%= encodeURIComponent(addr_list[i].name) %}" class="btn btn-default btn-xs pull-right"
|
||||
<a href="/app/Form/Address/{%= encodeURIComponent(addr_list[i].name) %}" class="btn btn-default btn-xs pull-right"
|
||||
style="margin-top:-3px; margin-right: -5px;">
|
||||
{%= __("Edit") %}</a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
{% if(contact_list[i].designation){ %}
|
||||
<span class="text-muted">– {%= contact_list[i].designation %}</span>
|
||||
{% } %}
|
||||
<a href="#Form/Contact/{%= encodeURIComponent(contact_list[i].name) %}"
|
||||
<a href="/app/Form/Contact/{%= encodeURIComponent(contact_list[i].name) %}"
|
||||
class="btn btn-xs btn-default ml-auto">
|
||||
{%= __("Edit") %}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
</a>
|
||||
<ul class="dropdown-menu print-format-dropdown" style="max-height: 300px;
|
||||
overflow-y: auto; left: auto;">
|
||||
<li><a class="dropdown-item" href="#Form/Print Settings">
|
||||
<li><a class="dropdown-item" href="/app/Form/Print Settings">
|
||||
{%= __("Print Settings") %}</a></li>
|
||||
<li><a class="btn-printer-setting dropdown-item" style="display: none;">
|
||||
{%= __("Raw Printing Settings") %}</a></li>
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ frappe.views.ListFactory = class ListFactory extends frappe.views.Factory {
|
|||
if (route[0] === 'List' && route.length === 2 && frappe.views.list_view[doctype]) {
|
||||
if(last_route && last_route[0]==='List' && last_route[1]===doctype) {
|
||||
// last route same as this route, so going back.
|
||||
// this happens because #List/Item will redirect to #List/Item/List
|
||||
// this happens because /app/List/Item will redirect to /app/List/Item/List
|
||||
// while coming from back button, the last 2 routes will be same, so
|
||||
// we know user is coming in the reverse direction (via back button)
|
||||
|
||||
// example:
|
||||
// Step 1: #List/Item redirects to #List/Item/List
|
||||
// Step 2: User hits "back" comes back to #List/Item
|
||||
// Step 3: Now we cannot send the user back to #List/Item/List so go back one more step
|
||||
// Step 1: /app/List/Item redirects to /app/List/Item/List
|
||||
// Step 2: User hits "back" comes back to /app/List/Item
|
||||
// Step 3: Now we cannot send the user back to /app/List/Item/List so go back one more step
|
||||
window.history.go(-1);
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -871,7 +871,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
? encodeURIComponent(doc.name)
|
||||
: doc.name;
|
||||
|
||||
return "#Form/" + this.doctype + "/" + docname;
|
||||
return "/app/Form/" + this.doctype + "/" + docname;
|
||||
}
|
||||
|
||||
get_seen_class(doc) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Vue.use(VueRouter);
|
|||
const routes = [
|
||||
{
|
||||
name: "recorder-detail",
|
||||
path: '/desk',
|
||||
path: '/app',
|
||||
component: RecorderDetail,
|
||||
},
|
||||
{
|
||||
|
|
@ -22,7 +22,7 @@ const routes = [
|
|||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: "/desk#recorder/",
|
||||
base: "/app/recorder/",
|
||||
routes: routes,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -13,39 +13,88 @@ frappe.view_factory = {};
|
|||
frappe.view_factories = [];
|
||||
frappe.route_options = null;
|
||||
frappe.route_hooks = {};
|
||||
frappe._cur_route = null;
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
// v1 style routing, route is in hash
|
||||
if (window.location.hash) {
|
||||
let sub_path = frappe.get_sub_path(window.location.hash);
|
||||
window.location.hash = '';
|
||||
frappe.push_state(sub_path);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('popstate', (event) => {
|
||||
// forward-back button, just re-render based on current route
|
||||
frappe.route();
|
||||
});
|
||||
|
||||
// routing v2, capture all clicks so that the target is managed with push-state
|
||||
$('body').on('click', 'a', function(e) {
|
||||
let override = (e, route) => {
|
||||
e.preventDefault();
|
||||
frappe.push_state(frappe.get_sub_path(route));
|
||||
return false;
|
||||
};
|
||||
|
||||
// click handled, but not by href
|
||||
if (e.currentTarget.getAttribute('onclick')) return;
|
||||
|
||||
const href = e.currentTarget.getAttribute('href');
|
||||
|
||||
if (href==='#' || href==='') {
|
||||
return override(e, '/app');
|
||||
}
|
||||
|
||||
// target has "#" ,this is a v1 style route, so remake it.
|
||||
if (e.currentTarget.hash) {
|
||||
return override(e, e.currentTarget.hash);
|
||||
}
|
||||
|
||||
// target has "/app, this is a v2 style route.
|
||||
if (e.currentTarget.pathname &&
|
||||
(e.currentTarget.pathname.startsWith('/app') || e.currentTarget.pathname.startsWith('app'))) {
|
||||
return override(e, e.currentTarget.pathname);
|
||||
}
|
||||
});
|
||||
|
||||
frappe.route = function() {
|
||||
|
||||
// Application is not yet initiated
|
||||
if (!frappe.app) return;
|
||||
|
||||
if(frappe.re_route[window.location.hash] !== undefined) {
|
||||
let sub_path = frappe.get_sub_path();
|
||||
|
||||
if (frappe.re_route[sub_path] !== undefined) {
|
||||
// after saving a doc, for example,
|
||||
// "New DocType 1" and the renamed "TestDocType", both exist in history
|
||||
// now if we try to go back,
|
||||
// it doesn't allow us to go back to the one prior to "New DocType 1"
|
||||
// Hence if this check is true, instead of changing location hash,
|
||||
// we just do a back to go to the doc previous to the "New DocType 1"
|
||||
var re_route_val = frappe.get_route_str(frappe.re_route[window.location.hash]);
|
||||
var cur_route_val = frappe.get_route_str(frappe._cur_route);
|
||||
if (decodeURIComponent(re_route_val) === decodeURIComponent(cur_route_val)) {
|
||||
var re_route_val = frappe.get_sub_path(frappe.re_route[sub_path]);
|
||||
if (decodeURIComponent(re_route_val) === decodeURIComponent(sub_path)) {
|
||||
window.history.back();
|
||||
return;
|
||||
} else {
|
||||
window.location.hash = frappe.re_route[window.location.hash];
|
||||
frappe.set_route(re_route_val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
frappe._cur_route = window.location.hash;
|
||||
frappe._cur_route = sub_path;
|
||||
|
||||
var route = frappe.get_route();
|
||||
if (route === false) {
|
||||
return;
|
||||
}
|
||||
let route = frappe.get_route();
|
||||
|
||||
frappe.route_history.push(route);
|
||||
|
||||
if(route[0]) {
|
||||
// set title
|
||||
frappe.route_titles[sub_path] = frappe._original_title || document.title;
|
||||
|
||||
// hide open dialog
|
||||
frappe.ui.hide_open_dialog();
|
||||
|
||||
if (route[0]) {
|
||||
const title_cased_route = frappe.utils.to_title_case(route[0]);
|
||||
if (title_cased_route === 'Workspace') {
|
||||
frappe.views.pageview.show('');
|
||||
|
|
@ -66,32 +115,31 @@ frappe.route = function() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// Show desk
|
||||
// Show home
|
||||
frappe.views.pageview.show('');
|
||||
}
|
||||
|
||||
|
||||
if(frappe.route_titles[window.location.hash]) {
|
||||
frappe.utils.set_title(frappe.route_titles[window.location.hash]);
|
||||
if (frappe.route_titles[sub_path]) {
|
||||
frappe.utils.set_title(frappe.route_titles[sub_path]);
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
frappe.route_titles[frappe.get_route_str()] = frappe._original_title || document.title;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if(window.mixpanel) {
|
||||
window.mixpanel.track(route.slice(0, 2).join(' '));
|
||||
}
|
||||
}
|
||||
frappe.route.trigger('change');
|
||||
|
||||
};
|
||||
|
||||
frappe.get_route = function(route) {
|
||||
// for app
|
||||
route = frappe.get_raw_route_str(route).split('/');
|
||||
route = frappe.get_sub_path_string(route).split('/');
|
||||
route = $.map(route, frappe._decode_str);
|
||||
var parts = null;
|
||||
var doc_name = route[route.length - 1];
|
||||
// if the last part contains ? then check if it is valid query string
|
||||
if(doc_name.indexOf("?") < doc_name.indexOf("=")){
|
||||
if (doc_name.indexOf("?") < doc_name.indexOf("=")) {
|
||||
parts = doc_name.split("?");
|
||||
route[route.length - 1] = parts[0];
|
||||
} else {
|
||||
|
|
@ -102,17 +150,11 @@ frappe.get_route = function(route) {
|
|||
frappe.route_options = $.extend(frappe.route_options || {}, query_params);
|
||||
}
|
||||
|
||||
// backward compatibility
|
||||
if (route && route[0]==='Module') {
|
||||
frappe.set_route('modules', route[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
frappe.get_prev_route = function() {
|
||||
if(frappe.route_history && frappe.route_history.length > 1) {
|
||||
if (frappe.route_history && frappe.route_history.length > 1) {
|
||||
return frappe.route_history[frappe.route_history.length - 2];
|
||||
} else {
|
||||
return [];
|
||||
|
|
@ -122,7 +164,7 @@ frappe.get_prev_route = function() {
|
|||
frappe._decode_str = function(r) {
|
||||
try {
|
||||
return decodeURIComponent(r);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
if (e instanceof URIError) {
|
||||
return r;
|
||||
} else {
|
||||
|
|
@ -131,31 +173,41 @@ frappe._decode_str = function(r) {
|
|||
}
|
||||
}
|
||||
|
||||
frappe.get_raw_route_str = function(route) {
|
||||
if(!route)
|
||||
frappe.get_sub_path_string = function(route) {
|
||||
// return clean sub_path from hash or url
|
||||
// supports both v1 and v2 routing
|
||||
|
||||
if (!route) {
|
||||
route = window.location.hash;
|
||||
}
|
||||
if (!route) {
|
||||
route = window.location.pathname;
|
||||
}
|
||||
|
||||
if(route.substr(0,1)=='#') route = route.substr(1);
|
||||
if(route.substr(0,1)=='!') route = route.substr(1);
|
||||
if (route.substr(0, 1)=='/') route = route.substr(1); // for /app/sub
|
||||
if (route.startsWith('app')) route = route.substr(4); // for desk/sub
|
||||
if (route.substr(0, 1)=='/') route = route.substr(1);
|
||||
if (route.substr(0, 1)=='#') route = route.substr(1);
|
||||
if (route.substr(0, 1)=='!') route = route.substr(1);
|
||||
|
||||
return route;
|
||||
}
|
||||
};
|
||||
|
||||
frappe.get_route_str = function(route) {
|
||||
var rawRoute = frappe.get_raw_route_str(route);
|
||||
route = $.map(rawRoute.split('/'), frappe._decode_str).join('/');
|
||||
frappe.get_sub_path = frappe.get_route_str = function(route) {
|
||||
var sub_path = frappe.get_sub_path_string(route);
|
||||
route = $.map(sub_path.split('/'), frappe._decode_str).join('/');
|
||||
|
||||
return route;
|
||||
}
|
||||
};
|
||||
|
||||
frappe.set_route = function() {
|
||||
return new Promise(resolve => {
|
||||
var params = arguments;
|
||||
if(params.length===1 && $.isArray(params[0])) {
|
||||
if (params.length===1 && $.isArray(params[0])) {
|
||||
params = params[0];
|
||||
}
|
||||
var route = $.map(params, function(a) {
|
||||
if($.isPlainObject(a)) {
|
||||
if ($.isPlainObject(a)) {
|
||||
frappe.route_options = a;
|
||||
return null;
|
||||
} else {
|
||||
|
|
@ -174,51 +226,47 @@ frappe.set_route = function() {
|
|||
url.hash = route;
|
||||
window.location.replace(url);
|
||||
} else {
|
||||
window.location.hash = route;
|
||||
//
|
||||
// window.location.hash = route;
|
||||
|
||||
// routing v2
|
||||
frappe.push_state(route);
|
||||
}
|
||||
|
||||
// Set favicon (app.js)
|
||||
frappe.provide('frappe.app');
|
||||
frappe.app.set_favicon && frappe.app.set_favicon();
|
||||
|
||||
setTimeout(() => {
|
||||
frappe.after_ajax && frappe.after_ajax(() => {
|
||||
resolve();
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
frappe.push_state = function (route) {
|
||||
let url = `/app/${route}`;
|
||||
if (window.location.pathname !== url) {
|
||||
// cleanup any remenants of v1 routing
|
||||
window.location.hash = '';
|
||||
|
||||
// push state so the browser looks fine
|
||||
history.pushState(null, null, url);
|
||||
|
||||
// now process the route
|
||||
frappe.route();
|
||||
}
|
||||
};
|
||||
|
||||
frappe.set_re_route = function() {
|
||||
var tmp = window.location.hash;
|
||||
var tmp = frappe.get_sub_path();
|
||||
frappe.set_route.apply(null, arguments);
|
||||
frappe.re_route[tmp] = window.location.hash;
|
||||
frappe.re_route[tmp] = frappe.get_sub_path();
|
||||
};
|
||||
|
||||
frappe.has_route_options = function() {
|
||||
return Boolean(Object.keys(frappe.route_options || {}).length);
|
||||
}
|
||||
|
||||
frappe._cur_route = null;
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
// save the title
|
||||
frappe.route_titles[frappe._cur_route] = frappe._original_title || document.title;
|
||||
|
||||
if(window.location.hash==frappe._cur_route)
|
||||
return;
|
||||
|
||||
// hide open dialog
|
||||
if(window.cur_dialog) {
|
||||
if (!cur_dialog.minimizable) {
|
||||
cur_dialog.hide();
|
||||
} else if (!cur_dialog.is_minimized) {
|
||||
cur_dialog.toggle_minimize();
|
||||
}
|
||||
}
|
||||
|
||||
frappe.route();
|
||||
|
||||
frappe.route.trigger('change');
|
||||
});
|
||||
};
|
||||
|
||||
frappe.utils.make_event_emitter(frappe.route);
|
||||
|
|
|
|||
|
|
@ -227,3 +227,14 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup {
|
|||
this.header.find('.modal-title').toggleClass('cursor-pointer');
|
||||
}
|
||||
};
|
||||
|
||||
frappe.ui.hide_open_dialog = () => {
|
||||
// hide open dialog
|
||||
if (window.cur_dialog) {
|
||||
if (!cur_dialog.minimizable) {
|
||||
cur_dialog.hide();
|
||||
} else if (!cur_dialog.is_minimized) {
|
||||
cur_dialog.toggle_minimize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ frappe.ui.Notifications = class Notifications {
|
|||
}
|
||||
|
||||
route_to_settings() {
|
||||
frappe.set_route(`#Form/Notification Settings/${frappe.session.user}`);
|
||||
frappe.set_route(`/app/Form/Notification Settings/${frappe.session.user}`);
|
||||
}
|
||||
|
||||
mark_all_as_read(e) {
|
||||
|
|
@ -253,7 +253,7 @@ class NotificationsView extends BaseNotificaitonsView {
|
|||
if (this.container.find('.activity-status')) {
|
||||
this.container.find('.activity-status').replaceWith(
|
||||
`<a class="recent-item text-center text-muted"
|
||||
href="#List/Notification Log">
|
||||
href="/app/List/Notification Log">
|
||||
<div class="full-log-btn">${__('View Full Log')}</div>
|
||||
</a>`
|
||||
);
|
||||
|
|
@ -339,7 +339,7 @@ class NotificationsView extends BaseNotificaitonsView {
|
|||
this.container.append(this.get_dropdown_item_html(field));
|
||||
});
|
||||
this.container.append(`<a class="list-footer"
|
||||
href="#List/Notification Log">
|
||||
href="/app/List/Notification Log">
|
||||
<div class="full-log-btn">${__('See all Activity')}</div>
|
||||
</a>`);
|
||||
} else {
|
||||
|
|
@ -449,7 +449,7 @@ class EventsView extends BaseNotificaitonsView {
|
|||
location = `, ${event.location}`;
|
||||
}
|
||||
|
||||
return `<a class="recent-item event" href="#Form/Event/${event.name}">
|
||||
return `<a class="recent-item event" href="/app/Form/Event/${event.name}">
|
||||
<div class="event-border" style="border-color: ${event.color}"></div>
|
||||
<div class="event-item">
|
||||
<div class="event-subject">${event.subject}</div>
|
||||
|
|
|
|||
|
|
@ -107,13 +107,7 @@ frappe.search.AwesomeBar = Class.extend({
|
|||
if(item.onclick) {
|
||||
item.onclick(item.match);
|
||||
} else {
|
||||
var previous_hash = window.location.hash;
|
||||
frappe.set_route(item.route);
|
||||
|
||||
// hashchange didn't fire!
|
||||
if (window.location.hash == previous_hash) {
|
||||
frappe.route();
|
||||
}
|
||||
}
|
||||
$input.val("");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ frappe.ui.toolbar.Toolbar = class {
|
|||
}));
|
||||
$('.dropdown-toggle').dropdown();
|
||||
|
||||
let awesome_bar = new frappe.search.AwesomeBar();
|
||||
awesome_bar.setup("#navbar-search");
|
||||
// awesome_bar.setup("#modal-search");
|
||||
|
||||
this.setup_awesomebar();
|
||||
this.setup_notifications();
|
||||
this.make();
|
||||
}
|
||||
|
|
@ -157,8 +154,17 @@ frappe.ui.toolbar.Toolbar = class {
|
|||
}
|
||||
}
|
||||
|
||||
setup_awesomebar() {
|
||||
if (frappe.boot.desk_settings.search_bar) {
|
||||
let awesome_bar = new frappe.search.AwesomeBar();
|
||||
awesome_bar.setup("#navbar-search");
|
||||
}
|
||||
}
|
||||
|
||||
setup_notifications () {
|
||||
this.notifications = new frappe.ui.Notifications();
|
||||
if (frappe.boot.desk_settings.notifications) {
|
||||
this.notifications = new frappe.ui.Notifications();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Object.assign(frappe.energy_points, {
|
|||
const separator = `<span> - </span>`;
|
||||
const formatted_log = `<span>
|
||||
<!--${this.get_points(log.points)} -->
|
||||
<a href="#Form/Energy Point Log/${log.name}">${this.get_form_log_message(log)}</a>
|
||||
<a href="/app/Form/Energy Point Log/${log.name}">${this.get_form_log_message(log)}</a>
|
||||
${log.reason ? separator + log.reason: ''}
|
||||
</span>`;
|
||||
return formatted_log;
|
||||
|
|
|
|||
|
|
@ -815,7 +815,7 @@ Object.assign(frappe.utils, {
|
|||
display_text = display_text || name;
|
||||
doctype = encodeURIComponent(doctype);
|
||||
name = encodeURIComponent(name);
|
||||
const route = ['#Form', doctype, name].join('/');
|
||||
const route = ['/app/Form', doctype, name].join('/');
|
||||
if (html) {
|
||||
return `<a href="${route}">${display_text}</a>`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ frappe.breadcrumbs = {
|
|||
label = module_info ? module_info.label : breadcrumbs.module;
|
||||
|
||||
if(module_info && !module_info.blocked && frappe.visible_modules.includes(module_info.module_name)) {
|
||||
$(repl('<li><a href="#workspace/%(module)s">%(label)s</a></li>',
|
||||
$(repl('<li><a href="/app/workspace/%(module)s">%(label)s</a></li>',
|
||||
{ module: breadcrumbs.module, label: __(breadcrumbs.module) }))
|
||||
.appendTo($breadcrumbs);
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ frappe.breadcrumbs = {
|
|||
} else {
|
||||
route = 'List/' + breadcrumbs.doctype;
|
||||
}
|
||||
$(`<li><a href="#${route}">${doctype}</a></li>`)
|
||||
$(`<li><a href="/app/${route}">${doctype}</a></li>`)
|
||||
.appendTo($breadcrumbs)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ frappe.views.Container = Class.extend({
|
|||
|
||||
$(document).trigger("page-change");
|
||||
|
||||
this.page._route = window.location.hash;
|
||||
this.page._route = frappe.get_sub_path();
|
||||
$(this.page).trigger('show');
|
||||
!this.page.disable_scroll_to_top && frappe.utils.scroll_to(0);
|
||||
frappe.breadcrumbs.update();
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
frappe.breadcrumbs.add({
|
||||
type: 'Custom',
|
||||
label: __('Home'),
|
||||
route: '#List/File/Home',
|
||||
route: '/app/List/File/Home',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
acc += '/' + curr;
|
||||
}
|
||||
return acc;
|
||||
}, '#List/File');
|
||||
}, '/app/List/File');
|
||||
|
||||
return `<a href="${route}">${folder}</a>`;
|
||||
})
|
||||
|
|
@ -364,7 +364,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
|
||||
get_route_url(file) {
|
||||
return file.is_folder
|
||||
? '#List/File/' + file.name
|
||||
? '/app/List/File/' + file.name
|
||||
: this.get_form_link(file);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="image-view-body">
|
||||
<a data-name="{{ data.name }}"
|
||||
title="{{ data.name }}"
|
||||
href="#Form/{{ data.doctype }}/{{ data.name }}"
|
||||
href="/app/Form/{{ data.doctype }}/{{ data.name }}"
|
||||
>
|
||||
<div class="image-field"
|
||||
data-name="{{ data.name }}"
|
||||
|
|
|
|||
|
|
@ -328,7 +328,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="#Form/Customize Form?doc_type=${doctype}">
|
||||
<a class="btn btn-xs btn-default" href="/app/Form/Customize Form?doc_type=${doctype}">
|
||||
${__('Customize Form')}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -38,15 +38,15 @@ frappe.views.pageview = {
|
|||
},
|
||||
|
||||
show: function(name) {
|
||||
if(!name) {
|
||||
if (!name) {
|
||||
name = (frappe.boot ? frappe.boot.home_page : window.page_name);
|
||||
}
|
||||
frappe.model.with_doctype("Page", function() {
|
||||
frappe.views.pageview.with_page(name, function(r) {
|
||||
if(r && r.exc) {
|
||||
if(!r['403'])
|
||||
if (r && r.exc) {
|
||||
if (!r['403'])
|
||||
frappe.show_not_found(name);
|
||||
} else if(!frappe.pages[name]) {
|
||||
} else if (!frappe.pages[name]) {
|
||||
new frappe.views.Page(name);
|
||||
}
|
||||
frappe.container.change_to(name);
|
||||
|
|
@ -59,7 +59,7 @@ frappe.views.Page = class Page {
|
|||
constructor(name) {
|
||||
this.name = name;
|
||||
var me = this;
|
||||
|
||||
|
||||
// web home page
|
||||
if(name==window.page_name) {
|
||||
this.wrapper = document.getElementById('page-' + name);
|
||||
|
|
@ -87,7 +87,7 @@ frappe.views.Page = class Page {
|
|||
}
|
||||
|
||||
this.trigger_page_event('on_page_load');
|
||||
|
||||
|
||||
// set events
|
||||
$(this.wrapper).on('show', function() {
|
||||
window.cur_frm = null;
|
||||
|
|
|
|||
|
|
@ -677,7 +677,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
<span class="indicator orange">
|
||||
${part1}
|
||||
${part2}
|
||||
<a href="#List/Prepared%20Report?report_name=${this.report_name}">${part3}</a>
|
||||
<a href="/app/List/Prepared%20Report?report_name=${this.report_name}">${part3}</a>
|
||||
</span>
|
||||
`);
|
||||
};
|
||||
|
|
@ -754,7 +754,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
get_queued_prepared_reports_warning_message(reports) {
|
||||
const route = `#List/Prepared Report/List?status=Queued&report_name=${this.report_name}`;
|
||||
const route = `/app/List/Prepared Report/List?status=Queued&report_name=${this.report_name}`;
|
||||
const report_link_html = reports.length == 1
|
||||
? `<a class="underline" href="${route}">${__('1 Report')}</a>`
|
||||
: `<a class="underline" href="${route}">${__("{0} Reports", [reports.length])}</a>`;
|
||||
|
|
@ -769,7 +769,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
${no_of_reports_html}
|
||||
</p>`;
|
||||
|
||||
let get_item_html = item => `<a class="underline" href="#Form/Prepared Report/${item.name}">${item.name}</a>`;
|
||||
let get_item_html = item => `<a class="underline" href="/app/Form/Prepared Report/${item.name}">${item.name}</a>`;
|
||||
|
||||
warning_message += reports.map(get_item_html).join(', ');
|
||||
|
||||
|
|
@ -805,7 +805,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
// 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='#Form/Prepared Report/${data.name}'>here</a>`;
|
||||
<a class="bold" href='/app/Form/Prepared Report/${data.name}'>here</a>`;
|
||||
frappe.show_alert({message: alert_message, indicator: 'orange'}, 10);
|
||||
this.toggle_nothing_to_show(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ frappe.views.Workspace = class Workspace {
|
|||
|
||||
const get_sidebar_item = function (item) {
|
||||
return $(`<a
|
||||
href="${"desk#workspace/" + item.name}"
|
||||
href="/desk/workspace/${item.name}"
|
||||
class="desk-sidebar-item standard-sidebar-item ${item.selected ? "selected" : ""}"
|
||||
>
|
||||
<div> ${frappe.utils.icon(item.icon || "folder-normal", "md")} </div>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export default class OnboardingWidget extends Widget {
|
|||
"Watch Video": (step) => this.show_video(step),
|
||||
"Create Entry": (step) => {
|
||||
if (step.is_complete) {
|
||||
frappe.set_route(`#List/${step.reference_document}`);
|
||||
frappe.set_route(`/app/List/${step.reference_document}`);
|
||||
} else {
|
||||
if (step.show_full_form) {
|
||||
this.create_entry(step);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ function generate_route(item) {
|
|||
route = "dashboard/" + item.name;
|
||||
}
|
||||
|
||||
route = "#" + route;
|
||||
} else {
|
||||
route = item.route;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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='#Form/${dt}/${dn}'></a>`);
|
||||
frm.fields_dict.reference_name.$input_wrapper.find('.control-value').wrapInner(`<a href='/app/Form/${dt}/${dn}'></a>`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ def add_comment(comment, comment_email, comment_by, reference_doctype, reference
|
|||
clear_cache(route)
|
||||
|
||||
content = (comment.content
|
||||
+ "<p><a href='{0}/desk#Form/Comment/{1}' style='font-size: 80%'>{2}</a></p>".format(frappe.utils.get_request_site_address(),
|
||||
+ "<p><a href='{0}/app/Form/Comment/{1}' style='font-size: 80%'>{2}</a></p>".format(frappe.utils.get_request_site_address(),
|
||||
comment.name,
|
||||
_("View Comment")))
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
</a>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
<a class="dropdown-item switch-to-desk hidden" href="/desk">{{ _('Switch To Desk') }}</a>
|
||||
<a class="dropdown-item switch-to-desk hidden" href="/app">{{ _('Switch To Desk') }}</a>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
{{ _("Success") }}</span>
|
||||
</div>
|
||||
<p>{{ _("Your connection request to Google Calendar was successfully accepted") }}</p>
|
||||
<div><a href='{{ "/desk" }}' class='btn btn-primary btn-sm'>
|
||||
<div><a href='{{ "/app" }}' class='btn btn-primary btn-sm'>
|
||||
{{ _("Back to Desk") }}</a></div>
|
||||
</div>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class BotParser(object):
|
|||
|
||||
def format_list(self, data):
|
||||
'''Format list as markdown'''
|
||||
return _('I found these: ') + ', '.join([' [{title}](#Form/{doctype}/{name})'.format(
|
||||
return _('I found these: ') + ', '.join([' [{title}](/app/Form/{doctype}/{name})'.format(
|
||||
title = d.title or d.name,
|
||||
doctype=self.get_doctype(),
|
||||
name=d.name) for d in data])
|
||||
|
|
@ -58,7 +58,7 @@ class ShowNotificationBot(BotParser):
|
|||
|
||||
if open_items:
|
||||
return ("Following items need your attention:\n\n"
|
||||
+ "\n\n".join(["{0} [{1}](#List/{1})".format(d[1], d[0])
|
||||
+ "\n\n".join(["{0} [{1}](/app/List/{1})".format(d[1], d[0])
|
||||
for d in open_items if d[1] > 0]))
|
||||
else:
|
||||
return 'Take it easy, nothing urgent needs your attention'
|
||||
|
|
@ -77,7 +77,7 @@ class GetOpenListBot(BotParser):
|
|||
else:
|
||||
data = [{'name':d[0], 'title':d[1]} for d in frappe.get_attr(filters)(as_list=True)]
|
||||
|
||||
return ", ".join('[{title}](#Form/{doctype}/{name})'.format(doctype=doctype,
|
||||
return ", ".join('[{title}](/app/Form/{doctype}/{name})'.format(doctype=doctype,
|
||||
name=d.get('name'), title=d.get('title') or d.get('name')) for d in data)
|
||||
else:
|
||||
return _("Can't identify open {0}. Try something else.").format(doctype)
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ def import_doc(d, doctype, overwrite, row_idx, submit=False, ignore_links=False)
|
|||
doc.get('name')))
|
||||
|
||||
def getlink(doctype, name):
|
||||
return '<a href="#Form/%(doctype)s/%(name)s">%(name)s</a>' % locals()
|
||||
return '<a href="/app/Form/%(doctype)s/%(name)s">%(name)s</a>' % locals()
|
||||
|
||||
def get_csv_content_from_google_sheets(url):
|
||||
# https://docs.google.com/spreadsheets/d/{sheetid}}/edit#gid={gid}
|
||||
|
|
|
|||
|
|
@ -1035,13 +1035,13 @@ def get_link_to_report(name, label=None, report_type=None, doctype=None, filters
|
|||
return """<a href='{0}'>{1}</a>""".format(get_url_to_report(name, report_type, doctype), label)
|
||||
|
||||
def get_absolute_url(doctype, name):
|
||||
return "desk#Form/{0}/{1}".format(quoted(doctype), quoted(name))
|
||||
return "desk/app/Form/{0}/{1}".format(quoted(doctype), quoted(name))
|
||||
|
||||
def get_url_to_form(doctype, name):
|
||||
return get_url(uri = "desk#Form/{0}/{1}".format(quoted(doctype), quoted(name)))
|
||||
return get_url(uri = "desk/app/Form/{0}/{1}".format(quoted(doctype), quoted(name)))
|
||||
|
||||
def get_url_to_list(doctype):
|
||||
return get_url(uri = "desk#List/{0}".format(quoted(doctype)))
|
||||
return get_url(uri = "desk/app/List/{0}".format(quoted(doctype)))
|
||||
|
||||
def get_url_to_report(name, report_type = None, doctype = None):
|
||||
if report_type == "Report Builder":
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ def redirect_post_login(desk_user, redirect_to=None, provider=None):
|
|||
|
||||
if not redirect_to:
|
||||
# the #desktop is added to prevent a facebook redirect bug
|
||||
desk_uri = "/desk#workspace" if provider == 'facebook' else '/desk'
|
||||
desk_uri = "/app/workspace" if provider == 'facebook' else '/app'
|
||||
redirect_to = desk_uri if desk_user else "/me"
|
||||
redirect_to = frappe.utils.get_url(redirect_to)
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def authorize_access(reauthorize=None):
|
|||
frappe.db.commit()
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = "/desk#Form/{0}".format(quote("Website Settings"))
|
||||
frappe.local.response["location"] = "/app/Form/{0}".format(quote("Website Settings"))
|
||||
|
||||
frappe.msgprint(_("Google Indexing has been configured."))
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -252,6 +252,9 @@ def resolve_path(path):
|
|||
if path != "index":
|
||||
path = resolve_from_map(path)
|
||||
|
||||
if path.startswith("app"):
|
||||
path = "app"
|
||||
|
||||
return path
|
||||
|
||||
def resolve_from_map(path):
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ frappe.listview_settings['Workflow Action'] = {
|
|||
? encodeURIComponent(docname)
|
||||
: docname;
|
||||
|
||||
const link = '#Form/' + doctype + '/' + docname;
|
||||
const link = '/app/Form/' + doctype + '/' + docname;
|
||||
return link;
|
||||
}
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
from __future__ import unicode_literals, print_function
|
||||
|
||||
no_cache = 1
|
||||
base_template_path = "templates/www/desk.html"
|
||||
base_template_path = "templates/www/app.html"
|
||||
|
||||
import os, re
|
||||
import frappe
|
||||
|
|
@ -14,8 +14,8 @@ import frappe.sessions
|
|||
def get_context(context):
|
||||
if frappe.session.user == "Guest":
|
||||
frappe.throw(_("Log in to access this page."), frappe.PermissionError)
|
||||
elif frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User":
|
||||
frappe.throw(_("You are not permitted to access this page."), frappe.PermissionError)
|
||||
# elif frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User":
|
||||
# frappe.throw(_("You are not permitted to access this page."), frappe.PermissionError)
|
||||
|
||||
hooks = frappe.get_hooks()
|
||||
try:
|
||||
|
|
@ -24,7 +24,7 @@ def get_context(context):
|
|||
if frappe.session.data.user_type=="Website User":
|
||||
redirect_to = get_home_page()
|
||||
else:
|
||||
redirect_to = "/desk"
|
||||
redirect_to = "/app"
|
||||
frappe.local.flags.redirect_location = redirect_to
|
||||
raise frappe.Redirect
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue