Bladeren bron

feat: Wiki based desk page

version-14
shariquerik 4 jaren geleden
bovenliggende
commit
902676ffb3
23 gewijzigde bestanden met toevoegingen van 10805 en 8296 verwijderingen
  1. +0
    -0
      frappe/desk/doctype/internal_wiki_page/__init__.py
  2. +8
    -0
      frappe/desk/doctype/internal_wiki_page/internal_wiki_page.js
  3. +87
    -0
      frappe/desk/doctype/internal_wiki_page/internal_wiki_page.json
  4. +45
    -0
      frappe/desk/doctype/internal_wiki_page/internal_wiki_page.py
  5. +10
    -0
      frappe/desk/doctype/internal_wiki_page/test_internal_wiki_page.py
  6. +0
    -0
      frappe/desk/page/wiki/__init__.py
  7. +15
    -0
      frappe/desk/page/wiki/wiki.js
  8. +19
    -0
      frappe/desk/page/wiki/wiki.json
  9. +3
    -0
      frappe/public/build.json
  10. +4
    -0
      frappe/public/js/frappe/router.js
  11. +426
    -0
      frappe/public/js/frappe/views/wiki.js
  12. +43
    -0
      frappe/public/js/frappe/widgets/widget_group.js
  13. +111
    -0
      frappe/public/js/frappe/wiki_blocks/blank.js
  14. +23
    -0
      frappe/public/js/frappe/wiki_blocks/blocks.js
  15. +155
    -0
      frappe/public/js/frappe/wiki_blocks/card.js
  16. +156
    -0
      frappe/public/js/frappe/wiki_blocks/chart.js
  17. +210
    -0
      frappe/public/js/frappe/wiki_blocks/paragraph.js
  18. +153
    -0
      frappe/public/js/frappe/wiki_blocks/shortcut.js
  19. +554
    -0
      frappe/public/js/frappe/wiki_blocks/spacing_tune.js
  20. +1
    -0
      frappe/public/scss/desk/index.scss
  21. +154
    -0
      frappe/public/scss/desk/wiki.scss
  22. +5
    -0
      package.json
  23. +8623
    -8296
      yarn.lock

+ 0
- 0
frappe/desk/doctype/internal_wiki_page/__init__.py Bestand weergeven


+ 8
- 0
frappe/desk/doctype/internal_wiki_page/internal_wiki_page.js Bestand weergeven

@@ -0,0 +1,8 @@
// Copyright (c) 2021, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Internal Wiki Page', {
// refresh: function(frm) {

// }
});

+ 87
- 0
frappe/desk/doctype/internal_wiki_page/internal_wiki_page.json Bestand weergeven

@@ -0,0 +1,87 @@
{
"actions": [],
"autoname": "field:title",
"creation": "2021-05-02 14:44:26.490935",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"title",
"icon",
"parent_page",
"column_break_4",
"sequence_id",
"private",
"section_break_7",
"content"
],
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Title",
"reqd": 1,
"unique": 1
},
{
"fieldname": "icon",
"fieldtype": "Data",
"label": "Icon"
},
{
"fieldname": "parent_page",
"fieldtype": "Data",
"label": "Parent Page"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"fieldname": "sequence_id",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Sequence Id"
},
{
"default": "0",
"fieldname": "private",
"fieldtype": "Check",
"label": "Private"
},
{
"fieldname": "section_break_7",
"fieldtype": "Section Break"
},
{
"fieldname": "content",
"fieldtype": "Long Text",
"label": "Content"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-05-02 16:06:35.033197",
"modified_by": "Administrator",
"module": "Desk",
"name": "Internal Wiki Page",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

+ 45
- 0
frappe/desk/doctype/internal_wiki_page/internal_wiki_page.py Bestand weergeven

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe, json
from frappe import _
from frappe.model.document import Document

class InternalWikiPage(Document):

def before_insert(self):
if frappe.db.count('Internal Wiki Page') == 0:
self.sequence_id = 1
else:
self.sequence_id = frappe.get_last_doc('Internal Wiki Page').sequence_id + 1

@frappe.whitelist()
def save_wiki_page(title, parent, blocks, save=True):
if save:
if not frappe.db.exists("Workspace", title):
wspace = frappe.new_doc('Workspace')
wspace.label = title
wspace.insert()

doc = frappe.new_doc('Internal Wiki Page')
doc.title = title
doc.parent_page = parent
doc.content = blocks
doc.insert()
else:
doc = frappe.get_doc('Internal Wiki Page', title)
doc.content = blocks
doc.save()
return doc.title

@frappe.whitelist()
def get_page_content(page):
return frappe.db.get_value("Internal Wiki Page", page, "content")

@frappe.whitelist()
def get_pages():
return frappe.db.get_list('Internal Wiki Page', fields=['name', 'icon', 'private', 'parent_page', 'sequence_id'],
order_by="sequence_id asc")

+ 10
- 0
frappe/desk/doctype/internal_wiki_page/test_internal_wiki_page.py Bestand weergeven

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies and Contributors
# See license.txt
from __future__ import unicode_literals

# import frappe
import unittest

class TestInternalWikiPage(unittest.TestCase):
pass

+ 0
- 0
frappe/desk/page/wiki/__init__.py Bestand weergeven


+ 15
- 0
frappe/desk/page/wiki/wiki.js Bestand weergeven

@@ -0,0 +1,15 @@
frappe.provide('frappe.views')

frappe.pages['wiki'].on_page_load = function(wrapper) {
frappe.ui.make_app_page({
parent: wrapper,
name: "Wiki",
single_column: false,
});

frappe.wiki = new frappe.views.Wiki(wrapper);

$(wrapper).bind('show', function () {
frappe.wiki.show();
});
}

+ 19
- 0
frappe/desk/page/wiki/wiki.json Bestand weergeven

@@ -0,0 +1,19 @@
{
"content": null,
"creation": "2021-05-02 14:50:05.327302",
"docstatus": 0,
"doctype": "Page",
"idx": 0,
"modified": "2021-05-02 14:50:05.327302",
"modified_by": "Administrator",
"module": "Desk",
"name": "wiki",
"owner": "Administrator",
"page_name": "wiki",
"roles": [],
"script": null,
"standard": "Yes",
"style": null,
"system_page": 0,
"title": "Wiki"
}

+ 3
- 0
frappe/public/build.json Bestand weergeven

@@ -178,6 +178,7 @@
"public/js/frappe/views/breadcrumbs.js",
"public/js/frappe/views/factory.js",
"public/js/frappe/views/pageview.js",
"public/js/frappe/views/wiki.js",

"public/js/frappe/ui/toolbar/awesome_bar.js",
"public/js/frappe/ui/toolbar/energy_points_notifications.js",
@@ -196,6 +197,8 @@

"public/js/frappe/widgets/widget_group.js",

"public/js/frappe/wiki_blocks/blocks.js",

"public/js/frappe/ui/sort_selector.html",
"public/js/frappe/ui/sort_selector.js",



+ 4
- 0
frappe/public/js/frappe/router.js Bestand weergeven

@@ -119,6 +119,7 @@ frappe.router = {

convert_to_standard_route(route) {
// /app/settings = ["Workspaces", "Settings"]
// /app/wiki/accounting = ["wiki", "Accounting"]
// /app/user = ["List", "User"]
// /app/user/view/report = ["List", "User", "Report"]
// /app/user/view/tree = ["Tree", "User"]
@@ -129,6 +130,9 @@ frappe.router = {
if (frappe.workspaces[route[0]]) {
// workspace
route = ['Workspaces', frappe.workspaces[route[0]].name];
} else if (frappe.wiki_pages && frappe.wiki_pages[route[1]]) {
// wiki-pages
route = ['wiki', frappe.wiki_pages[route[1]].name];
} else if (this.routes[route[0]]) {
// route
route = this.set_doctype_route(route);


+ 426
- 0
frappe/public/js/frappe/views/wiki.js Bestand weergeven

@@ -0,0 +1,426 @@
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import Checklist from '@editorjs/checklist';
import List from '@editorjs/list';
import Undo from 'editorjs-undo';

frappe.views.Wiki = class Wiki {
constructor(wrapper) {
this.wrapper = $(wrapper);
this.page = wrapper.page;
this.pages = {};
this.sections = {};
this.sidebar_items = {};
this.sorted_sidebar_items = {}
this.tools = {}
this.isReadOnly = true;
this.prepare_container();
this.setup_wiki_pages();
}

prepare_container() {
let list_sidebar = $(`
<div class="list-sidebar overlay-sidebar hidden-xs hidden-sm">
<div class="desk-sidebar list-unstyled sidebar-menu"></div>
</div>
`).appendTo(this.wrapper.find(".layout-side-section"));
this.sidebar = list_sidebar.find(".desk-sidebar");
this.body = this.wrapper.find(".layout-main-section");
// this.body.addClass("frappe-card");
}

setup_wiki_pages() {
this.get_pages().then(() => {
if(this.all_pages) {
frappe.wiki_pages = {};
let root_pages = this.all_pages.filter(page => page.parent_page == '' || page.parent_page == null)
for (let page of this.all_pages || []) {
frappe.wiki_pages[frappe.router.slug(page.name)] = page;
}
frappe.router.route();
this.make_sidebar(root_pages);
this.make_sidebar_sortable();
}
})
}

make_sidebar_sortable() {
let me = this;
this.sidebar_sortable = Sortable.create(this.page.sidebar.find(".standard-sidebar-section").get(0), {
handle: ".standard-sidebar-item-container",
draggable: ".standard-sidebar-item-container",
animation: 150,
onEnd: function (evt){
// let sb_items = me.all_pages.filter(page => page.parent_page == '' || page.parent_page == null)
// let startBlock = sb_items[evt.oldIndex];
// let endBlock = sb_items[evt.newIndex];
// startBlock.sequence_id = parseInt(me.sidebar.find('.standard-sidebar-item-container')[evt.oldIndex].getAttribute('item-sequence'));
// let oldName = me.sidebar.find('.standard-sidebar-item-container')[evt.oldIndex].getAttribute('item-name');
// endBlock.sequence_id = parseInt(me.sidebar.find('.standard-sidebar-item-container')[evt.newIndex].getAttribute('item-sequence'));
// let newName = me.sidebar.find('.standard-sidebar-item-container')[evt.newIndex].getAttribute('item-name');
// frappe.db.set_value('Internal Wiki Page', newName, {["sequence_id"]: startBlock.sequence_id})
// frappe.db.set_value('Internal Wiki Page', oldName, {["sequence_id"]: endBlock.sequence_id})
}
});
}

get_pages() {
return frappe.xcall("frappe.desk.doctype.internal_wiki_page.internal_wiki_page.get_pages").then(data => {
this.all_pages = data;
});
}

make_sidebar(items) {
if (this.sidebar.find('.standard-sidebar-section')[0]) {
this.sidebar.find('.standard-sidebar-section')[0].remove()
}
let sidebar_section = $(`<div class="standard-sidebar-section"></div>`);

const get_sidebar_item = function (item) {
return $(`
<div class="standard-sidebar-item-container" item-name="${item.name}" item-sequence="${item.sequence_id}">
<div class="desk-sidebar-item standard-sidebar-item ${item.selected ? "selected" : ""}">
<a
href="/app/wiki/${frappe.router.slug(item.name)}"
class="item-anchor"
>
<span>${frappe.utils.icon(item.icon || "folder-normal", "md")}</span>
<span class="sidebar-item-label">${item.label || item.name}<span>
</a>
<span class="drop-icon hidden">${frappe.utils.icon("small-down", "sm")}</span>
</div>
<div class="sidebar-child-item hidden"></div>
</div>
`);
};

const make_sidebar_category_item = item => {
if (item.name == this.get_page_to_show()) {
item.selected = true;
this.current_page_name = item.name;
}

const get_child_item = function (item) {
return $(`
<div class="sidebar-child-item-container">
<a
href="/app/wiki/${frappe.router.slug(item.name)}"
class="desk-sidebar-item standard-sidebar-item ${item.selected ? "selected" : ""}"
>
<span>${frappe.utils.icon(item.icon || "folder-normal", "md")}</span>
<span class="sidebar-item-label">${item.label || item.name}<span>
</a>
</div>
`);
}
const make_sidebar_child_item = item => {
let $child_item = get_child_item(item);
$child_item.appendTo(child_item_section)
this.sidebar_items[item.name] = $child_item;
}

let $item = get_sidebar_item(item);
let drop_icon = $item.find('.drop-icon').get(0);
let child_item_section = $item.find('.sidebar-child-item').get(0);
if(this.all_pages.some(e => e.parent_page == item.name)) {
drop_icon.classList.remove('hidden');
drop_icon.addEventListener('click', () => {
child_item_section.classList.toggle("hidden");
});
}

let child_items = this.all_pages.filter(page => page.parent_page == item.name)
child_items.forEach(item => make_sidebar_child_item(item));

$item.appendTo(sidebar_section);
this.sidebar_items[item.name] = $item;
};

items.forEach(item => make_sidebar_category_item(item));

sidebar_section.appendTo(this.sidebar);
}

show() {
if (!this.all_pages) {
// pages not yet loaded, call again after a bit
setTimeout(() => {
this.show();
}, 500);
return;
}
let page = this.get_page_to_show();
this.page.set_title(`${__(page)}`);
this.show_page(page);
this.get_content(page).then(() => {
this.get_data(page).then(() => {
if(this.content){
this.tools = {
header: {
class: Header,
inlineToolbar: true
},
paragraph: {
class: frappe.wiki_block.blocks['paragraph'],
inlineToolbar: true
},
checklist: {
class: Checklist,
inlineToolbar: true,
},
list: {
class: List,
inlineToolbar: true,
},
chart: {
class: frappe.wiki_block.blocks['chart'],
config: {
page_data: this.page_data || []
}
},
card: {
class: frappe.wiki_block.blocks['card'],
config: {
page_data: this.page_data || []
}
},
shortcut: {
class: frappe.wiki_block.blocks['shortcut'],
config: {
page_data: this.page_data || []
}
},
blank: frappe.wiki_block.blocks['blank'],
spacingTune: frappe.wiki_block.tunes['spacing_tune'],
}
if(this.editor) {
this.editor.isReady.then(() => {
this.editor.configuration.tools.chart.config.page_data = this.page_data;
this.editor.configuration.tools.shortcut.config.page_data = this.page_data;
this.editor.configuration.tools.card.config.page_data = this.page_data;
this.editor.render({
blocks: JSON.parse(this.content) || []
})
})
} else {
this.initialize_editorjs(JSON.parse(this.content));
}
}
})
})
}

get_content(page) {
return frappe.xcall("frappe.desk.doctype.internal_wiki_page.internal_wiki_page.get_page_content", {
page: page
}).then(data => {
this.content = data;
});
}

get_data(page) {
return frappe.xcall("frappe.desk.desktop.get_desktop_page", {
page: page
}).then(data => {
this.page_data = data;
});
}

get_page_to_show() {
let default_page;

if (localStorage.current_wiki_page) {
default_page = localStorage.current_wiki_page;
} else if (this.all_pages) {
default_page = this.all_pages[0].name;
} else {
default_page = "Home";
}

let page = frappe.get_route()[1] || default_page;
return page;
}

show_page(page) {
if (this.current_page_name && this.pages[this.current_page_name]) {
this.pages[this.current_page_name].hide();
}

if (this.sidebar_items && this.sidebar_items[this.current_page_name]) {
this.sidebar_items[this.current_page_name][0].firstElementChild.classList.remove("selected");
this.sidebar_items[page][0].firstElementChild.classList.add("selected");
}
this.current_page_name = page;
localStorage.current_wiki_page = page;

this.current_page = this.pages[page];

if (!this.body.find('#editorjs')[0]) {
this.$page = $(`
<div id="editorjs" class="wiki-page page-main-content"></div>
`).appendTo(this.body);
}

this.setup_actions();
}

setup_actions() {
this.page.clear_inner_toolbar();

this.page.set_secondary_action(
__("Customize"),
() => {
this.isReadOnly = false;
this.editor.readOnly.toggle();
this.editor.isReady
.then(() => {
let me = this;
this.undo = new Undo({ editor: this.editor });
this.undo.initialize({blocks: JSON.parse(this.content)});
this.setup_customization_buttons();
this.page_sortable = Sortable.create(this.page.main.find(".codex-editor__redactor").get(0), {
handle: ".ce-block",
animation: 150,
onEnd: function (evt){
me.editor.blocks.move(evt.newIndex, evt.oldIndex);
},
setData: function (dataTransfer, dragEl) {
//Do Nothing
}
});
})
},
);

this.page.add_inner_button(__('Create Page'), () => {
this.initialize_new_page();
});
}

setup_customization_buttons() {
this.page.clear_primary_action();
this.page.clear_secondary_action();
this.page.clear_inner_toolbar();

this.page.set_primary_action(
__("Save Customizations"),
() => {
this.page.clear_primary_action();
this.page.clear_secondary_action();
this.save_page();
this.editor.readOnly.toggle();
this.isReadOnly = true;
this.page_sortable.option("disabled", true);
},
null,
__("Saving")
);

this.page.set_secondary_action(
__("Discard"),
() => {
this.page.clear_primary_action();
this.page.clear_secondary_action();
this.editor.readOnly.toggle();
this.isReadOnly = true;
this.page_sortable.option("disabled", true);
this.reload();
frappe.show_alert({ message: __("Customizations Discarded"), indicator: "info" });
}
);
}

initialize_new_page() {
const d = new frappe.ui.Dialog({
title: __('Set Title'),
fields: [
{ label: __('Title'), fieldtype: 'Data', fieldname: 'title'},
{ label: __('Parent'), fieldtype: 'Select', fieldname: 'parent', options: this.all_pages.map(pages => pages.name)}
],
primary_action_label: __('Create'),
primary_action: (values) => {
d.hide();
this.setup_customization_buttons();
this.title = values.title;
this.parent = values.parent;
// const index = this.all_pages.findIndex(e => e.selected == true )
// this.all_pages[index].selected = false;
// let item = {name: this.title, selected: true}
// this.make_sidebar([...this.all_pages, item], 'new')
this.editor.render({
blocks: [
{
type: "header",
data: {
text: this.title,
level: 2
}
}
]
}).then(() => {
if(this.editor.configuration.readOnly) {
this.isReadOnly = false;
this.editor.readOnly.toggle();
}
this.dirty = false;
})
}
});
d.show();
}

initialize_editorjs(blocks) {
this.dirty = false;
const data = {
blocks: blocks || []
}
this.editor = new EditorJS({
tools: this.tools,
autofocus: false,
data,
tunes: ['spacingTune'],
onChange: () => {
this.dirty = true;
},
readOnly: true,
});
}

save_page() {
frappe.dom.freeze();
let save = true;
if (!this.title && this.current_page_name) {
this.title = this.current_page_name;
save = '';
}
let me = this;
this.editor.save().then((outputData) => {
frappe.call({
method: "frappe.desk.doctype.internal_wiki_page.internal_wiki_page.save_wiki_page",
args: {
title: me.title,
parent: me.parent || '',
blocks: JSON.stringify(outputData.blocks),
save: save
},
callback: function(res) {
frappe.dom.unfreeze();
if (res.message) {
frappe.show_alert({ message: __("Page Saved Successfully"), indicator: "green" });
me.title = '';
me.parent = '';
me.reload();
}
}
});
}).catch((error) => {
console.log('Saving failed: ', error);
});
}

reload() {
this.setup_wiki_pages();
this.dirty = false;
}
}

+ 43
- 0
frappe/public/js/frappe/widgets/widget_group.js Bestand weergeven

@@ -186,4 +186,47 @@ export default class WidgetGroup {
}
}

export class SingleWidgetGroup {
constructor(opts) {
Object.assign(this, opts);
this.widgets_list = [];
this.widgets_dict = {};
this.widget_order = [];
this.make();
}

make() {
this.add_widget(this.widgets);
}

add_widget(widget) {
let widget_object = frappe.widget.make_widget({
...widget,
widget_type: this.type,
container: this.container,
height: this.height || null,
options: {
...this.options,
on_delete: (name) => this.on_delete(name),
},
});

this.widgets_list.push(widget_object);
this.widgets_dict[widget.name] = widget_object;

return widget_object;
}

customize() {
// if (!this.hidden) this.widget_area.show();
this.widgets_list.forEach((wid) => {
wid.customize(this.options);
});

// this.options.allow_create && this.setup_new_widget();
// this.options.allow_sorting && this.setup_sortable();
}
}

frappe.widget.WidgetGroup = WidgetGroup;
frappe.widget.SingleWidgetGroup = SingleWidgetGroup;

+ 111
- 0
frappe/public/js/frappe/wiki_blocks/blank.js Bestand weergeven

@@ -0,0 +1,111 @@
export default class Blank {
static get toolbox() {
return {
title: 'Blank',
icon: '<svg width="18" height="18" viewBox="0 0 400 400"><path d="M377.87 24.126C361.786 8.042 342.417 0 319.769 0H82.227C59.579 0 40.211 8.042 24.125 24.126 8.044 40.212.002 59.576.002 82.228v237.543c0 22.647 8.042 42.014 24.123 58.101 16.086 16.085 35.454 24.127 58.102 24.127h237.542c22.648 0 42.011-8.042 58.102-24.127 16.085-16.087 24.126-35.453 24.126-58.101V82.228c-.004-22.648-8.046-42.016-24.127-58.102zm-12.422 295.645c0 12.559-4.47 23.314-13.415 32.264-8.945 8.945-19.698 13.411-32.265 13.411H82.227c-12.563 0-23.317-4.466-32.264-13.411-8.945-8.949-13.418-19.705-13.418-32.264V82.228c0-12.562 4.473-23.316 13.418-32.264 8.947-8.946 19.701-13.418 32.264-13.418h237.542c12.566 0 23.319 4.473 32.265 13.418 8.945 8.947 13.415 19.701 13.415 32.264v237.543h-.001z"/></svg>'
};
}

static get isReadOnlySupported() {
return true;
}

constructor({data, api, config, readOnly}){
this.data = data;
this.api = api;
this.config = config;
this.readOnly = readOnly;
this.col = this.data.col ? this.data.col : "12",
this.pt = this.data.pt ? this.data.pt : "0",
this.pr = this.data.pr ? this.data.pr : "0",
this.pb = this.data.pb ? this.data.pb : "0",
this.pl = this.data.pl ? this.data.pl : "0"
}

render() {
this.wrapper = document.createElement('div');
if (!this.readOnly) {
this.wrapper.innerText = 'Blank';
this.wrapper.classList.add('widget', 'new-widget');
this.wrapper.style.minHeight = 50 + 'px';
}
return this.wrapper;
}

save(blockContent) {
return {
col: this._getCol(),
pt: this._getPadding("t"),
pr: this._getPadding("r"),
pb: this._getPadding("b"),
pl: this._getPadding("l")
}
}

rendered() {
var e = this.wrapper.parentNode.parentNode;
e.classList.add("col-" + this.col)
e.classList.add("pt-" + this.pt)
e.classList.add("pr-" + this.pr)
e.classList.add("pb-" + this.pb)
e.classList.add("pl-" + this.pl)
}

_getCol() {
var e = 12,
t = "col-12",
n = this.wrapper.parentNode.parentNode,
r = new RegExp(/\bcol-.+?\b/, "g");
if (n.className.match(r)) {
n.classList.forEach(function (e) {
e.match(r) && (t = e);
});
var a = t.split("-");
e = parseInt(a[1]);
}
return e;
}

_getPadding() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "l",
t = 0,
n = "p" + e + "-0",
r = this.wrapper.parentNode.parentNode,
a = new RegExp(/\pl-.+?\b/, "g"),
i = new RegExp(/\pr-.+?\b/, "g"),
o = new RegExp(/\pt-.+?\b/, "g"),
c = new RegExp(/\pb-.+?\b/, "g");
if ("l" == e) {
if (r.className.match(a)) {
r.classList.forEach(function (e) {
e.match(a) && (n = e);
});
var s = n.split("-");
t = parseInt(s[1]);
}
} else if ("r" == e) {
if (r.className.match(i)) {
r.classList.forEach(function (e) {
e.match(i) && (n = e);
});
var l = n.split("-");
t = parseInt(l[1]);
}
} else if ("t" == e) {
if (r.className.match(o)) {
r.classList.forEach(function (e) {
e.match(o) && (n = e);
});
var u = n.split("-");
t = parseInt(u[1]);
}
} else if ("b" == e && r.className.match(c)) {
r.classList.forEach(function (e) {
e.match(c) && (n = e);
});
var p = n.split("-");
t = parseInt(p[1]);
}
return t;
}
}

+ 23
- 0
frappe/public/js/frappe/wiki_blocks/blocks.js Bestand weergeven

@@ -0,0 +1,23 @@
// import blocks
import Paragraph from "../wiki_blocks/paragraph";
import Card from "../wiki_blocks/card";
import Chart from "../wiki_blocks/chart";
import Shortcut from "../wiki_blocks/shortcut";
import Blank from "../wiki_blocks/blank";

// import tunes
import SpacingTune from "../wiki_blocks/spacing_tune";

frappe.provide("frappe.wiki_block");

frappe.wiki_block.blocks = {
paragraph: Paragraph,
card: Card,
chart: Chart,
shortcut: Shortcut,
blank: Blank,
};

frappe.wiki_block.tunes = {
spacing_tune : SpacingTune
}

+ 155
- 0
frappe/public/js/frappe/wiki_blocks/card.js Bestand weergeven

@@ -0,0 +1,155 @@
export default class Card {
static get toolbox() {
return {
title: 'Card',
icon: '<svg height="24" width="24" viewBox="0 0 24 24"><path d="M7 15h3a1 1 0 000-2H7a1 1 0 000 2zM19 5H5a3 3 0 00-3 3v9a3 3 0 003 3h14a3 3 0 003-3V8a3 3 0 00-3-3zm1 12a1 1 0 01-1 1H5a1 1 0 01-1-1v-6h16zm0-8H4V8a1 1 0 011-1h14a1 1 0 011 1z"/></svg>'
};
}

static get isReadOnlySupported() {
return true;
}

constructor({data, api, config, readOnly, block}){
this.data = data;
this.api = api;
this.config = config;
this.readOnly = readOnly;
this.sections = {};
this.col = this.data.col ? this.data.col : "12",
this.pt = this.data.pt ? this.data.pt : "0",
this.pr = this.data.pr ? this.data.pr : "0",
this.pb = this.data.pb ? this.data.pb : "0",
this.pl = this.data.pl ? this.data.pl : "0"
}

render() {
let me = this;
this.wrapper = document.createElement('div');
this._make_fieldgroup(this.wrapper, [{
fieldtype: "Select",
label: "Card Name",
fieldname: "card_name",
options: this.config.page_data.cards.items.map(({ label }) => label),
change: function() {
if (this.value) {
me._make_cards(this.value)
}
}
}]);
if (this.data && this.data.card_name) {
this._make_cards(this.data.card_name)
}
return this.wrapper;
}

save(blockContent) {
return {
card_name: blockContent.getAttribute('card_name'),
col: this._getCol(),
pt: this._getPadding("t"),
pr: this._getPadding("r"),
pb: this._getPadding("b"),
pl: this._getPadding("l")
}
}

rendered() {
var e = this.wrapper.parentNode.parentNode;
e.classList.add("col-" + this.col)
e.classList.add("pt-" + this.pt)
e.classList.add("pr-" + this.pr)
e.classList.add("pb-" + this.pb)
e.classList.add("pl-" + this.pl)
}

_getCol() {
var e = 12,
t = "col-12",
n = this.wrapper.parentNode.parentNode,
r = new RegExp(/\bcol-.+?\b/, "g");
if (n.className.match(r)) {
n.classList.forEach(function (e) {
e.match(r) && (t = e);
});
var a = t.split("-");
e = parseInt(a[1]);
}
return e;
}

_getPadding() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "l",
t = 0,
n = "p" + e + "-0",
r = this.wrapper.parentNode.parentNode,
a = new RegExp(/\pl-.+?\b/, "g"),
i = new RegExp(/\pr-.+?\b/, "g"),
o = new RegExp(/\pt-.+?\b/, "g"),
c = new RegExp(/\pb-.+?\b/, "g");
if ("l" == e) {
if (r.className.match(a)) {
r.classList.forEach(function (e) {
e.match(a) && (n = e);
});
var s = n.split("-");
t = parseInt(s[1]);
}
} else if ("r" == e) {
if (r.className.match(i)) {
r.classList.forEach(function (e) {
e.match(i) && (n = e);
});
var l = n.split("-");
t = parseInt(l[1]);
}
} else if ("t" == e) {
if (r.className.match(o)) {
r.classList.forEach(function (e) {
e.match(o) && (n = e);
});
var u = n.split("-");
t = parseInt(u[1]);
}
} else if ("b" == e && r.className.match(c)) {
r.classList.forEach(function (e) {
e.match(c) && (n = e);
});
var p = n.split("-");
t = parseInt(p[1]);
}
return t;
}

_make_fieldgroup(parent, ddf_list) {
this.card_field = new frappe.ui.FieldGroup({
"fields": ddf_list,
"parent": parent
});
this.card_field.make();
}

_make_cards(card_name) {
let card = this.config.page_data.cards.items.find(obj => {
return obj.label == card_name
});
this.wrapper.innerHTML = '';
this.sections = {};
let cards = new frappe.widget.SingleWidgetGroup({
container: this.wrapper,
type: "links",
columns: 3,
options: {
allow_sorting: this.allow_customization,
allow_create: false,
allow_delete: false,
allow_hiding: this.allow_customization,
allow_edit: false,
},
widgets: card
});

this.sections["cards"] = cards;
this.wrapper.setAttribute("card_name", card_name);
}
}

+ 156
- 0
frappe/public/js/frappe/wiki_blocks/chart.js Bestand weergeven

@@ -0,0 +1,156 @@
export default class Chart {
static get toolbox() {
return {
title: 'Chart',
icon: '<svg height="18" width="18" viewBox="0 0 512 512"><path d="M117.547 234.667H10.88c-5.888 0-10.667 4.779-10.667 10.667v256C.213 507.221 4.992 512 10.88 512h106.667c5.888 0 10.667-4.779 10.667-10.667v-256a10.657 10.657 0 00-10.667-10.666zM309.12 0H202.453c-5.888 0-10.667 4.779-10.667 10.667v490.667c0 5.888 4.779 10.667 10.667 10.667H309.12c5.888 0 10.667-4.779 10.667-10.667V10.667C319.787 4.779 315.008 0 309.12 0zM501.12 106.667H394.453c-5.888 0-10.667 4.779-10.667 10.667v384c0 5.888 4.779 10.667 10.667 10.667H501.12c5.888 0 10.667-4.779 10.667-10.667v-384c0-5.889-4.779-10.667-10.667-10.667z"/></svg>'
};
}

static get isReadOnlySupported() {
return true;
}

constructor({data, api, config, readOnly}){
this.data = data;
this.api = api;
this.config = config;
this.readOnly = readOnly;
this.sections = {};
this.col = this.data.col ? this.data.col : "12",
this.pt = this.data.pt ? this.data.pt : "0",
this.pr = this.data.pr ? this.data.pr : "0",
this.pb = this.data.pb ? this.data.pb : "0",
this.pl = this.data.pl ? this.data.pl : "0"
}

render() {
let me = this;
this.wrapper = document.createElement('div');
this._make_fieldgroup(this.wrapper, [{
fieldtype: "Select",
label: "Chart Name",
fieldname: "chart_name",
options: this.config.page_data.charts.items.map(({ chart_name }) => chart_name),
change: function() {
if (this.value) {
me._make_charts(this.value)
}
}
}]);
if (this.data && this.data.chart_name) {
this._make_charts(this.data.chart_name)
}
return this.wrapper;
}

save(blockContent) {
return {
chart_name: blockContent.getAttribute('chart_name'),
col: this._getCol(),
pt: this._getPadding("t"),
pr: this._getPadding("r"),
pb: this._getPadding("b"),
pl: this._getPadding("l")
}
}

rendered() {
var e = this.wrapper.parentNode.parentNode;
e.classList.add("col-" + this.col)
e.classList.add("pt-" + this.pt)
e.classList.add("pr-" + this.pr)
e.classList.add("pb-" + this.pb)
e.classList.add("pl-" + this.pl)
}

_getCol() {
var e = 12,
t = "col-12",
n = this.wrapper.parentNode.parentNode,
r = new RegExp(/\bcol-.+?\b/, "g");
if (n.className.match(r)) {
n.classList.forEach(function (e) {
e.match(r) && (t = e);
});
var a = t.split("-");
e = parseInt(a[1]);
}
return e;
}

_getPadding() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "l",
t = 0,
n = "p" + e + "-0",
r = this.wrapper.parentNode.parentNode,
a = new RegExp(/\pl-.+?\b/, "g"),
i = new RegExp(/\pr-.+?\b/, "g"),
o = new RegExp(/\pt-.+?\b/, "g"),
c = new RegExp(/\pb-.+?\b/, "g");
if ("l" == e) {
if (r.className.match(a)) {
r.classList.forEach(function (e) {
e.match(a) && (n = e);
});
var s = n.split("-");
t = parseInt(s[1]);
}
} else if ("r" == e) {
if (r.className.match(i)) {
r.classList.forEach(function (e) {
e.match(i) && (n = e);
});
var l = n.split("-");
t = parseInt(l[1]);
}
} else if ("t" == e) {
if (r.className.match(o)) {
r.classList.forEach(function (e) {
e.match(o) && (n = e);
});
var u = n.split("-");
t = parseInt(u[1]);
}
} else if ("b" == e && r.className.match(c)) {
r.classList.forEach(function (e) {
e.match(c) && (n = e);
});
var p = n.split("-");
t = parseInt(p[1]);
}
return t;
}

_make_fieldgroup(parent, ddf_list) {
this.chart_field = new frappe.ui.FieldGroup({
"fields": ddf_list,
"parent": parent
});
this.chart_field.make();
}

_make_charts(chart_name) {
let chart = this.config.page_data.charts.items.find(obj => {
return obj.chart_name == chart_name
});
this.wrapper.innerHTML = '';
this.sections = {};
this.sections["charts"] = new frappe.widget.SingleWidgetGroup({
container: this.wrapper,
type: "chart",
columns: 1,
class_name: "widget-charts",
// hidden: Boolean(this.onboarding_widget),
options: {
allow_sorting: this.allow_customization,
allow_create: this.allow_customization,
allow_delete: this.allow_customization,
allow_hiding: false,
allow_edit: true,
max_widget_count: 2,
},
widgets: chart
});
this.wrapper.setAttribute("chart_name", chart_name)
}
}

+ 210
- 0
frappe/public/js/frappe/wiki_blocks/paragraph.js Bestand weergeven

@@ -0,0 +1,210 @@
export default class Paragraph {

static get DEFAULT_PLACEHOLDER() {
return '';
}

constructor({data, config, api, readOnly}) {
this.api = api;
this.readOnly = readOnly;

this._CSS = {
block: this.api.styles.block,
wrapper: 'ce-paragraph'
};

if (!this.readOnly) {
this.onKeyUp = this.onKeyUp.bind(this);
}

this._placeholder = config.placeholder ? config.placeholder : Paragraph.DEFAULT_PLACEHOLDER;
this._data = {};
this._element = this.drawView();
this._preserveBlank = config.preserveBlank !== undefined ? config.preserveBlank : false;

this.data = data;
this.col = this.data.col ? this.data.col : "12",
this.pt = this.data.pt ? this.data.pt : "0",
this.pr = this.data.pr ? this.data.pr : "0",
this.pb = this.data.pb ? this.data.pb : "0",
this.pl = this.data.pl ? this.data.pl : "0"
}

onKeyUp(e) {
if (e.code !== 'Backspace' && e.code !== 'Delete') {
return;
}

const {textContent} = this._element;

if (textContent === '') {
this._element.innerHTML = '';
}
}

drawView() {
let div = document.createElement('DIV');

div.classList.add(this._CSS.wrapper, this._CSS.block, 'widget');
div.contentEditable = false;
div.dataset.placeholder = this.api.i18n.t(this._placeholder);

if (!this.readOnly) {
div.contentEditable = true;
div.addEventListener('keyup', this.onKeyUp);
}
return div;
}

render() {
return this._element;
}

merge(data) {
let newData = {
text : this.data.text + data.text
};

this.data = newData;
}

validate(savedData) {
if (savedData.text.trim() === '' && !this._preserveBlank) {
return false;
}

return true;
}

save(toolsContent) {
return {
text: toolsContent.innerHTML,
col: this._getCol(),
pt: this._getPadding("t"),
pr: this._getPadding("r"),
pb: this._getPadding("b"),
pl: this._getPadding("l")
};
}

rendered() {
var e = this._element.parentNode.parentNode;
e.classList.add("col-" + this.col)
e.classList.add("pt-" + this.pt)
e.classList.add("pr-" + this.pr)
e.classList.add("pb-" + this.pb)
e.classList.add("pl-" + this.pl)
}

_getCol() {
var e = 12,
t = "col-12",
n = this._element.parentNode.parentNode,
r = new RegExp(/\bcol-.+?\b/, "g");
if (n.className.match(r)) {
n.classList.forEach(function (e) {
e.match(r) && (t = e);
});
var a = t.split("-");
e = parseInt(a[1]);
}
return e;
}

_getPadding() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "l",
t = 0,
n = "p" + e + "-0",
r = this._element.parentNode.parentNode,
a = new RegExp(/\pl-.+?\b/, "g"),
i = new RegExp(/\pr-.+?\b/, "g"),
o = new RegExp(/\pt-.+?\b/, "g"),
c = new RegExp(/\pb-.+?\b/, "g");
if ("l" == e) {
if (r.className.match(a)) {
r.classList.forEach(function (e) {
e.match(a) && (n = e);
});
var s = n.split("-");
t = parseInt(s[1]);
}
} else if ("r" == e) {
if (r.className.match(i)) {
r.classList.forEach(function (e) {
e.match(i) && (n = e);
});
var l = n.split("-");
t = parseInt(l[1]);
}
} else if ("t" == e) {
if (r.className.match(o)) {
r.classList.forEach(function (e) {
e.match(o) && (n = e);
});
var u = n.split("-");
t = parseInt(u[1]);
}
} else if ("b" == e && r.className.match(c)) {
r.classList.forEach(function (e) {
e.match(c) && (n = e);
});
var p = n.split("-");
t = parseInt(p[1]);
}
return t;
}

onPaste(event) {
const data = {
text: event.detail.data.innerHTML
};

this.data = data;
}

static get conversionConfig() {
return {
export: 'text', // to convert Paragraph to other block, use 'text' property of saved data
import: 'text' // to covert other block's exported string to Paragraph, fill 'text' property of tool data
};
}

static get sanitize() {
return {
text: {
br: true,
}
};
}

static get isReadOnlySupported() {
return true;
}

get data() {
let text = this._element.innerHTML;

this._data.text = text;

return this._data;
}

set data(data) {
this._data = data || {};

this._element.innerHTML = this._data.text || '';
}

static get pasteConfig() {
return {
tags: [ 'P' ]
};
}

static get toolbox() {
return {
icon: '<svg viewBox="0.2 -0.3 9 11.4" width="12" height="14"><path d="M0 2.77V.92A1 1 0 01.2.28C.35.1.56 0 .83 0h7.66c.28.01.48.1.63.28.14.17.21.38.21.64v1.85c0 .26-.08.48-.23.66-.15.17-.37.26-.66.26-.28 0-.5-.09-.64-.26a1 1 0 01-.21-.66V1.69H5.6v7.58h.5c.25 0 .45.08.6.23.17.16.25.35.25.6s-.08.45-.24.6a.87.87 0 01-.62.22H3.21a.87.87 0 01-.61-.22.78.78 0 01-.24-.6c0-.25.08-.44.24-.6a.85.85 0 01.61-.23h.5V1.7H1.73v1.08c0 .26-.08.48-.23.66-.15.17-.37.26-.66.26-.28 0-.5-.09-.64-.26A1 1 0 010 2.77z"/></svg>',
title: 'Text'
};
}
}

+ 153
- 0
frappe/public/js/frappe/wiki_blocks/shortcut.js Bestand weergeven

@@ -0,0 +1,153 @@
export default class Shortcut {
static get toolbox() {
return {
title: 'Shortcut',
icon: '<svg height="18" width="18" viewBox="0 0 122.88 115.71"><path d="M116.56 3.69l-3.84 53.76-17.69-15c-19.5 8.72-29.96 23.99-30.51 43.77-17.95-26.98-7.46-50.4 12.46-65.97L64.96 3l51.6.69zM28.3 0h14.56v19.67H32.67c-4.17 0-7.96 1.71-10.72 4.47-2.75 2.75-4.46 6.55-4.46 10.72l-.03 46c.03 4.16 1.75 7.95 4.5 10.71 2.76 2.76 6.56 4.48 10.71 4.48h58.02c4.15 0 7.95-1.72 10.71-4.48 2.76-2.76 4.48-6.55 4.48-10.71V73.9h17.01v11.33c0 7.77-3.2 17.04-8.32 22.16-5.12 5.12-12.21 8.32-19.98 8.32H28.3c-7.77 0-14.86-3.2-19.98-8.32C3.19 102.26 0 95.18 0 87.41l.03-59.1c-.03-7.79 3.16-14.88 8.28-20C13.43 3.19 20.51 0 28.3 0z" fill-rule="evenodd" clip-rule="evenodd"/></svg>'
};
}

static get isReadOnlySupported() {
return true;
}

constructor({data, api, config, readOnly}){
this.data = data;
this.api = api;
this.config = config;
this.readOnly = readOnly;
this.sections = {};
this.col = this.data.col ? this.data.col : "12",
this.pt = this.data.pt ? this.data.pt : "0",
this.pr = this.data.pr ? this.data.pr : "0",
this.pb = this.data.pb ? this.data.pb : "0",
this.pl = this.data.pl ? this.data.pl : "0"
}

render() {
let me = this;
this.wrapper = document.createElement('div');
this._make_fieldgroup(this.wrapper, [{
fieldtype: "Select",
label: "Shortcut Name",
fieldname: "shortcut_name",
options: this.config.page_data.shortcuts.items.map(({ label }) => label),
change: function() {
if (this.value) {
me._make_shortcuts(this.value);
}
}
}]);
if (this.data && this.data.shortcut_name) {
this._make_shortcuts(this.data.shortcut_name)
}
return this.wrapper;
}

save(blockContent) {
return {
shortcut_name: blockContent.getAttribute('shortcut_name'),
col: this._getCol(),
pt: this._getPadding("t"),
pr: this._getPadding("r"),
pb: this._getPadding("b"),
pl: this._getPadding("l")
}
}

rendered() {
var e = this.wrapper.parentNode.parentNode;
e.classList.add("col-" + this.col)
e.classList.add("pt-" + this.pt)
e.classList.add("pr-" + this.pr)
e.classList.add("pb-" + this.pb)
e.classList.add("pl-" + this.pl)
}

_getCol() {
var e = 12,
t = "col-12",
n = this.wrapper.parentNode.parentNode,
r = new RegExp(/\bcol-.+?\b/, "g");
if (n.className.match(r)) {
n.classList.forEach(function (e) {
e.match(r) && (t = e);
});
var a = t.split("-");
e = parseInt(a[1]);
}
return e;
}

_getPadding() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "l",
t = 0,
n = "p" + e + "-0",
r = this.wrapper.parentNode.parentNode,
a = new RegExp(/\pl-.+?\b/, "g"),
i = new RegExp(/\pr-.+?\b/, "g"),
o = new RegExp(/\pt-.+?\b/, "g"),
c = new RegExp(/\pb-.+?\b/, "g");
if ("l" == e) {
if (r.className.match(a)) {
r.classList.forEach(function (e) {
e.match(a) && (n = e);
});
var s = n.split("-");
t = parseInt(s[1]);
}
} else if ("r" == e) {
if (r.className.match(i)) {
r.classList.forEach(function (e) {
e.match(i) && (n = e);
});
var l = n.split("-");
t = parseInt(l[1]);
}
} else if ("t" == e) {
if (r.className.match(o)) {
r.classList.forEach(function (e) {
e.match(o) && (n = e);
});
var u = n.split("-");
t = parseInt(u[1]);
}
} else if ("b" == e && r.className.match(c)) {
r.classList.forEach(function (e) {
e.match(c) && (n = e);
});
var p = n.split("-");
t = parseInt(p[1]);
}
return t;
}

_make_fieldgroup(parent, ddf_list) {
this.shortcut_field = new frappe.ui.FieldGroup({
"fields": ddf_list,
"parent": parent
});
this.shortcut_field.make();
}

_make_shortcuts(shortcut_name) {
let shortcut = this.config.page_data.shortcuts.items.find(obj => {
return obj.label == shortcut_name
});
this.wrapper.innerHTML = '';
this.sections = {};
this.sections["shortcuts"] = new frappe.widget.SingleWidgetGroup({
container: this.wrapper,
type: "shortcut",
columns: 3,
options: {
allow_sorting: this.allow_customization,
allow_create: this.allow_customization,
allow_delete: this.allow_customization,
allow_hiding: false,
allow_edit: true,
},
widgets: shortcut
});
this.wrapper.setAttribute("shortcut_name", shortcut_name);
}
}

+ 554
- 0
frappe/public/js/frappe/wiki_blocks/spacing_tune.js Bestand weergeven

@@ -0,0 +1,554 @@
export default class SpacingTune {
static get isTune() {
return true;
}

constructor({api, settings}) {
this.api = api;
this.settings = settings;
this.CSS = {
button: 'ce-settings__button',
wrapper: 'ce-tune-layout',
sidebar: 'cdx-settings-sidebar',
animation: 'wobble',
};
this.data = { colWidth: 12, pl: 0, pr: 0, pt: 0, pb: 0 };
this.wrapper = undefined;
this.sidebar = undefined;
}

render() {
let me = this;
let layoutWrapper = document.createElement('div');
layoutWrapper.classList.add(this.CSS.wrapper);
let decreaseWidthButton = document.createElement('div');
decreaseWidthButton.classList.add(this.CSS.button);
let increaseWidthButton = document.createElement('div');
increaseWidthButton.classList.add(this.CSS.button);
let paddingButton = document.createElement('div');
paddingButton.classList.add(this.CSS.button);

layoutWrapper.appendChild(paddingButton);
layoutWrapper.appendChild(decreaseWidthButton);
layoutWrapper.appendChild(increaseWidthButton);

// paddingButton.appendChild($.svg('padding', 15, 15));
paddingButton.innerHTML = `<svg version="1.1" height="12" x="0px" y="0px" viewBox="-674 379 17 12" style="enable-background:new -674 379 17 12;" xml:space="preserve"><rect x="-666.1" y="379.9" width="1.7" height="10.3"/><polygon points="-657,384.2 -659.9,384.2 -658.8,383.1 -660,381.9 -663.1,385 -660,388.1 -658.8,386.9 -659.9,385.8 -657,385.8 "/><rect x="-671.9" y="379.9" width="4.1" height="1.7"/><rect x="-674" y="384.2" width="6.1" height="1.7"/><rect x="-671.9" y="388.4" width="4.1" height="1.7"/></svg>`;
this.api.listeners.on(
paddingButton,
'click',
(event) => me.showPadding(event, paddingButton),
false
);

// decreaseWidthButton.appendChild($.svg('decrease-width', 15, 15));
decreaseWidthButton.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><path d="M-674,383.9h3.6l-1.7-1.7c-0.4-0.4-0.4-1.2,0-1.6c0.4-0.4,1.1-0.4,1.6,0l3.2,3.2c0.6,0.2,0.8,0.8,0.6,1.4 c-0.1,0.1-0.1,0.3-0.2,0.4l-3.8,3.8c-0.4,0.4-1.1,0.4-1.5,0c-0.4-0.4-0.4-1.1,0-1.5l1.8-1.8h-3.6V383.9z"/><path d="M-657,386.1h-3.6l1.7,1.7c0.4,0.4,0.4,1.2,0,1.6c-0.4,0.4-1.1,0.4-1.6,0l-3.2-3.2c-0.6-0.2-0.8-0.8-0.6-1.4 c0.1-0.1,0.1-0.3,0.2-0.4l3.8-3.8c0.4-0.4,1.1-0.4,1.5,0c0.4,0.4,0.4,1.1,0,1.5l-1.8,1.8h3.6V386.1z"/></svg>`;
this.api.listeners.on(
decreaseWidthButton,
'click',
(event) => me.decreaseWidth(event, decreaseWidthButton),
false
);

// increaseWidthButton.appendChild();
increaseWidthButton.innerHTML = `<svg width="17" height="10" viewBox="0 0 17 10"><path d="M13.568 5.925H4.056l1.703 1.703a1.125 1.125 0 0 1-1.59 1.591L.962 6.014A1.069 1.069 0 0 1 .588 4.26L4.38.469a1.069 1.069 0 0 1 1.512 1.511L4.084 3.787h9.606l-1.85-1.85a1.069 1.069 0 1 1 1.512-1.51l3.792 3.791a1.069 1.069 0 0 1-.475 1.788L13.514 9.16a1.125 1.125 0 0 1-1.59-1.591l1.644-1.644z"/></svg>`;
this.api.listeners.on(
increaseWidthButton,
'click',
(event) => me.increaseWidth(event, increaseWidthButton),
false
);

this.wrapper = layoutWrapper;
return layoutWrapper;
}

decreaseWidth(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if (currentBlockIndex < 0) {
return;
}

let currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

let currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'col-12';
let colClass = new RegExp(/\bcol-.+?\b/, 'g');
if (currentBlockElement.className.match(colClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(colClass)){
className = cn;
}
});
let parts = className.split('-');
let width = parseInt(parts[1]);
if(width >= 2){
currentBlockElement.classList.remove('col-'+width);
width = width - 1;
currentBlockElement.classList.add('col-'+width);
}
}
}

increaseWidth(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if (currentBlockIndex < 0) {
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'col-12';
const colClass = new RegExp(/\bcol-.+?\b/, 'g');
if (currentBlockElement.className.match(colClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(colClass)){
className = cn;
}
});
let parts = className.split('-');
let width = parseInt(parts[1]);
if(width <= 11){
currentBlockElement.classList.remove('col-'+width);
width = width + 1;
currentBlockElement.classList.add('col-'+width);
}
}
}
showPadding(event, button) {
let me = this;
if(button.classList.contains('cdx-settings-button--active')){
this.sidebar.remove();
button.classList.remove('cdx-settings-button--active');
} else {
button.classList.add('cdx-settings-button--active');

let sidebarWrapper = document.createElement('div');
sidebarWrapper.classList.add(this.CSS.sidebar);

let paddingLeftCaption = document.createElement('button');
paddingLeftCaption.classList.add(this.CSS.button, 'disabled');
// paddingLeftCaption.appendChild($.svg('arrow-left', 10, 10));
paddingLeftCaption.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><polygon points="-659,384.1 -667.8,384.1 -665.8,381.9 -667,380.7 -671,384.9 -667.1,388.9 -665.8,387.7 -667.8,385.7 -659,385.7 "/></svg>`;

let paddingRightCaption = document.createElement('button');
paddingRightCaption.classList.add(this.CSS.button, 'disabled');
// paddingRightCaption.appendChild($.svg('arrow-right', 10, 10));
paddingRightCaption.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><polygon points="-671,385.7 -662.2,385.7 -664.2,387.7 -662.9,388.9 -659,384.9 -663,380.7 -664.2,381.9 -662.2,384.1 -671,384.1 "/></svg>`;

let paddingTopCaption = document.createElement('button');
paddingTopCaption.classList.add(this.CSS.button, 'disabled');
// paddingTopCaption.appendChild($.svg('arrow-up', 10, 10));
paddingTopCaption.innerHTML = `<svg version="1.1" height="13" x="0px" y="0px" viewBox="-674 378.5 17 13" style="enable-background:new -674 378.5 17 13;" xml:space="preserve"><polygon points="-664.6,391 -664.6,382.2 -662.6,384.2 -661.4,382.9 -665.4,379 -669.6,383 -668.4,384.2 -666.2,382.2 -666.2,391 "/></svg>`;

let paddingBottomCaption = document.createElement('button');
paddingBottomCaption.classList.add(this.CSS.button, 'disabled');
// paddingBottomCaption.appendChild($.svg('arrow-down', 10, 10));
paddingBottomCaption.innerHTML = `<svg version="1.1" height="13" x="0px" y="0px" viewBox="-674 378.5 17 13" style="enable-background:new -674 378.5 17 13;" xml:space="preserve"><polygon points="-666.2,379 -666.2,387.8 -668.4,385.8 -669.6,387 -665.4,391 -661.4,387.1 -662.6,385.8 -664.6,387.8 -664.6,379 "/></svg>`;

let increasePaddingLeft = document.createElement('button');
increasePaddingLeft.classList.add(this.CSS.button);

let decreasePaddingLeft = document.createElement('button');
decreasePaddingLeft.classList.add(this.CSS.button);

let increasePaddingRight = document.createElement('button');
increasePaddingRight.classList.add(this.CSS.button);

let decreasePaddingRight = document.createElement('button');
decreasePaddingRight.classList.add(this.CSS.button);

let increasePaddingTop = document.createElement('button');
increasePaddingTop.classList.add(this.CSS.button);

let decreasePaddingTop = document.createElement('button');
decreasePaddingTop.classList.add(this.CSS.button);

let increasePaddingBottom = document.createElement('button');
increasePaddingBottom.classList.add(this.CSS.button);

let decreasePaddingBottom = document.createElement('button');
decreasePaddingBottom.classList.add(this.CSS.button);

this.sidebar = sidebarWrapper;

// Left Padding
sidebarWrapper.appendChild(paddingLeftCaption);

// increasePaddingLeft.appendChild($.svg('plus', 15, 15));
increasePaddingLeft.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
increasePaddingLeft,
'click',
(event) => me.increasePaddingLeft(event, increasePaddingLeft),
false
);
sidebarWrapper.appendChild(increasePaddingLeft);

// decreasePaddingLeft.appendChild($.svg('minus', 15, 15));
decreasePaddingLeft.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
decreasePaddingLeft,
'click',
(event) => me.decreasePaddingLeft(event, decreasePaddingLeft),
false
);
sidebarWrapper.appendChild(decreasePaddingLeft);

// Right Padding
sidebarWrapper.appendChild(paddingRightCaption);
// increasePaddingRight.appendChild($.svg('plus', 15, 15));
increasePaddingRight.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
increasePaddingRight,
'click',
(event) => me.increasePaddingRight(event, increasePaddingRight),
false
);
sidebarWrapper.appendChild(increasePaddingRight);

// decreasePaddingRight.appendChild($.svg('minus', 15, 15));
decreasePaddingRight.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
decreasePaddingRight,
'click',
(event) => me.decreasePaddingRight(event, decreasePaddingRight),
false
);
sidebarWrapper.appendChild(decreasePaddingRight);

// Top Padding
sidebarWrapper.appendChild(paddingTopCaption);
// increasePaddingTop.appendChild($.svg('plus', 15, 15));
increasePaddingTop.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
increasePaddingTop,
'click',
(event) => me.increasePaddingTop(event, increasePaddingTop),
false
);
sidebarWrapper.appendChild(increasePaddingTop);

// decreasePaddingTop.appendChild($.svg('minus', 15, 15));
decreasePaddingTop.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
decreasePaddingTop,
'click',
(event) => me.decreasePaddingTop(event, decreasePaddingTop),
false
);
sidebarWrapper.appendChild(decreasePaddingTop);

// Bottom Padding
sidebarWrapper.appendChild(paddingBottomCaption);
// increasePaddingBottom.appendChild($.svg('plus', 15, 15));
increasePaddingBottom.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
increasePaddingBottom,
'click',
(event) => me.increasePaddingBottom(event, increasePaddingBottom),
false
);
sidebarWrapper.appendChild(increasePaddingBottom);

// decreasePaddingBottom.appendChild($.svg('minus', 15, 15));
decreasePaddingBottom.innerHTML = `<svg version="1.1" height="10" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;

this.api.listeners.on(
decreasePaddingBottom,
'click',
(event) => me.decreasePaddingBottom(event, decreasePaddingBottom),
false
);
sidebarWrapper.appendChild(decreasePaddingBottom);

this.wrapper.appendChild(sidebarWrapper);
}
}

increasePaddingLeft(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pl-0';
const paddingClass = new RegExp(/\pl-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding <= 4){
currentBlockElement.classList.remove('pl-'+padding);
padding = padding + 1;
currentBlockElement.classList.add('pl-'+padding);
}
}

}

decreasePaddingLeft(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pl-0';
const paddingClass = new RegExp(/\pl-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding >= 1){
currentBlockElement.classList.remove('pl-'+padding);
padding = padding - 1;
currentBlockElement.classList.add('pl-'+padding);
}
}
}

increasePaddingRight(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pr-0';
const paddingClass = new RegExp(/\pr-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding <= 4){
currentBlockElement.classList.remove('pr-'+padding);
padding = padding + 1;
currentBlockElement.classList.add('pr-'+padding);
}
}
}

decreasePaddingRight(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pr-0';
const paddingClass = new RegExp(/\pr-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding >= 1){
currentBlockElement.classList.remove('pr-'+padding);
padding = padding - 1;
currentBlockElement.classList.add('pr-'+padding);
}
}
}

increasePaddingTop(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pt-0';
const paddingClass = new RegExp(/\pt-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding <= 4){
currentBlockElement.classList.remove('pt-'+padding);
padding = padding + 1;
currentBlockElement.classList.add('pt-'+padding);
}
}
}

decreasePaddingTop(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pt-0';
const paddingClass = new RegExp(/\pt-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding >= 1){
currentBlockElement.classList.remove('pt-'+padding);
padding = padding - 1;
currentBlockElement.classList.add('pt-'+padding);
}
}
}

increasePaddingBottom(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pb-0';
const paddingClass = new RegExp(/\pb-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding <= 4){
currentBlockElement.classList.remove('pb-'+padding);
padding = padding + 1;
currentBlockElement.classList.add('pb-'+padding);
}
}
}

decreasePaddingBottom(event, button) {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();

if(currentBlockIndex < 0){
return;
}

const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
if (!currentBlock){
return;
}

const currentBlockElement = currentBlock.holder;

// let block = this.api.blocks.getBlock(currentBlockElement);
let className = 'pb-0';
const paddingClass = new RegExp(/\pb-.+?\b/, 'g');
if (currentBlockElement.className.match(paddingClass)) {
currentBlockElement.classList.forEach( cn => {
if(cn.match(paddingClass)){
className = cn;
}
});
let parts = className.split('-');
let padding = parseInt(parts[1]);
if(padding >= 1){
currentBlockElement.classList.remove('pb-'+padding);
padding = padding - 1;
currentBlockElement.classList.add('pb-'+padding);
}
}
}
}

+ 1
- 0
frappe/public/scss/desk/index.scss Bestand weergeven

@@ -24,6 +24,7 @@
@import "notification";
@import "global_search";
@import "desktop";
@import "wiki";
@import "../common/awesomeplete";
@import "sidebar";
@import "filters";


+ 154
- 0
frappe/public/scss/desk/wiki.scss Bestand weergeven

@@ -0,0 +1,154 @@
[data-page-route="wiki"] {
@media (min-width: map-get($grid-breakpoints, "lg")) {
.layout-main {
height: calc(100vh - var(--navbar-height) - var(--page-head-height) - 5px);
.layout-side-section, .layout-main-section-wrapper {
height: 100%;
overflow-y: auto;
}
.desk-sidebar {
margin-bottom: var(--margin-2xl);
}
}
}
}

.ce-header {
padding: 0 !important;
margin-bottom: 0 !important;
}

.codex-editor {
min-height: 630px;

svg {
fill: none;
}

.ce-toolbar {
svg {
fill: currentColor;
}

.icon {
stroke: none;
width: fit-content;
}
}

.ce-inline-tool, .ce-inline-toolbar__dropdown {
.icon {
fill: currentColor;
}
}
@media (min-width: 1199px) {
.ce-toolbar__content {
max-width: 930px;
}
}
@media (max-width: 995px) {
.ce-toolbar__content {
max-width: 760px;
}
}

@media (max-width: 1199px) {
.ce-block.col-4 {
flex: 0 0 50%;
max-width: 50%;
}
}
@media (max-width: 750px) {
.ce-block.col-4 {
flex: 0 0 100%;
max-width: 100%;
}
}
@media (max-width: 750px) {
.ce-block.col-6 {
flex: 0 0 100%;
max-width: 100%;
}
}
div[card_name] {
height: inherit;
}
}

.codex-editor__redactor{
display: flex;
flex-wrap: wrap;
flex-direction: row;
margin: 0px -7px;
}
.ce-block{
width: 100%;
padding-left: 0;
padding-right: 0;
}
.cdx-settings-input{
border: 1px solid rgba(201,201,204,.48);
-webkit-box-shadow: inset 0 1px 2px 0 rgba(35,44,72,.06);
box-shadow: inset 0 1px 2px 0 rgba(35,44,72,.06);
border-radius: 3px;padding: 3px 8px;outline: none;
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.cdx-small{
font-size: .6rem
}
.ce-block__content {
max-width: 100%;
height: 100%;
padding: 7px;

&> div {
height: 100%;
}
}

.cdx-settings-button.disabled{
pointer-events: none;
opacity: .5
}
.cdx-settings-sidebar{
position: absolute;
right: 100%;
top:0;
background: #fff;
width: 108px;
height: 145px;
box-shadow: 0 3px 15px -3px rgba(13,20,33,.13);
border-radius: 0 4px 4px 0;z-index: 0;
}


[data-page-route="wiki"] {

.standard-sidebar-item {
justify-content: space-between;
}

.sidebar-child-item-container {
margin-left: 10px;

.standard-sidebar-item {
justify-content: start;
}
}

.sidebar-item-label {
flex: 1;
}

.item-anchor {
display: flex;
overflow: hidden;
flex: 1;
}
}

+ 5
- 0
package.json Bestand weergeven

@@ -18,6 +18,8 @@
},
"homepage": "https://frappeframework.com",
"dependencies": {
"@editorjs/editorjs": "^2.20.0",
"@editorjs/header": "^2.6.1",
"ace-builds": "^1.4.8",
"air-datepicker": "github:frappe/air-datepicker",
"autoprefixer": "^9.8.6",
@@ -54,8 +56,11 @@
"vue-router": "^2.0.0"
},
"devDependencies": {
"@editorjs/checklist": "^1.3.0",
"@editorjs/list": "^1.6.2",
"babel-runtime": "^6.26.0",
"chalk": "^2.3.2",
"editorjs-undo": "^0.1.5",
"graphlib": "^2.1.8",
"less": "^3.11.1",
"rollup": "^1.2.2",


+ 8623
- 8296
yarn.lock
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


Laden…
Annuleren
Opslaan