Merge pull request #2816 from SchrodingersGat/markdown-editor

Markdown editor
This commit is contained in:
Oliver authored and GitHub committed 2022-04-10 22:44:57 +10:00
commit fe8f5a74e7
15 files changed
+254 -199

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
/**
* easymde v2.16.1
* Copyright Jeroen Akkerman
* @link https://github.com/ionaru/easy-markdown-editor
* @license MIT
*/
.CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor .CodeMirror-line::selection,.cm-fat-cursor .CodeMirror-line>span::selection,.cm-fat-cursor .CodeMirror-line>span>span::selection{background:0 0}.cm-fat-cursor .CodeMirror-line::-moz-selection,.cm-fat-cursor .CodeMirror-line>span::-moz-selection,.cm-fat-cursor .CodeMirror-line>span>span::-moz-selection{background:0 0}.cm-fat-cursor{caret-color:transparent}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-type,.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:red}.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-50px;margin-right:-50px;padding-bottom:50px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:50px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none;outline:0}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-50px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sLine truncated
+7
View File
@@ -0,0 +1,7 @@
/**
* easymde v2.16.1
* Copyright Jeroen Akkerman
* @link https://github.com/ionaru/easy-markdown-editor
* @license MIT
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EasyMDE=e()}}((function(){return function e(t,n,r){function i(a,l){if(!n[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[a]={exports:{}};t[a][0].call(c.exports,(function(e){return i(t[a][1][e]||e)}),c,c.exports,e,t,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<r.length;a++)i(r[a]);return i}({1:[function(e,t,n){},{}],2:[function(e,t,n){"use strict";var r=e("typo-js");function i(e){"function"==typeof(e=e||{}).codeMirrorInstance&&"function"==typeof e.codeMirrorInstance.defineMode?(String.prototype.includes||(String.prototype.includes=function(){return-1!==String.prototype.indexOf.apply(this,arguments)}),e.codeMirrorInstance.defineMode("spell-checker",(function(t){if(!i.aff_loading){i.aff_loading=!0;var n=new XMLHttpRequest;n.open("GET","https://cdn.jsdelivr.net/codemirror.spell-checker/latest/en_US.aff",!0),n.onload=function(){4===n.readyState&&200===n.status&&(i.aff_data=n.responseText,i.num_loaded++,2==i.num_loaded&&(i.typo=new r("en_US",i.aff_data,i.dic_data,{platform:"any"})))},n.send(null)}if(!i.dic_loading){i.dic_loading=!0;var o=new XMLHttpRequest;o.open("GET","https://cdn.jsdelivr.net/codemirror.spell-checker/latest/en_US.dic",!0),o.onload=function(){4===o.readyState&&200===o.status&&(i.dic_data=o.responseText,i.num_loaded++,2==i.num_loaded&&(i.typo=new r("en_US",i.aff_data,i.dic_data,{platform:"any"})))},o.send(null)}var a='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~ ',l={token:function(e){var t=e.peek(),n="";if(a.includes(t))return e.next(),null;for(;null!=(t=e.peek())&&!a.includes(t);)n+=t,e.next();return i.typo&&!i.typo.check(n)?"spell-error":null}},s=e.codeMirrorInstance.getMode(t,t.backdrop||"text/plain");return e.codeMirrorInstance.overlayMode(s,l,!0)}))):console.log("CodeMirror Spell Checker: You must provide an instance of CodeMirror via the option `codeMirrorInstance`")}i.num_loaded=0,i.aff_loading=!1,i.dic_loading=!1,i.aff_data="",i.dic_data="",i.typo,t.exports=i},{"typo-js":16}],3:[function(e,t,n){(function(e){"use strict";function t(t,n){clearTimeout(n.timeout),e.off(window,"mouseup",n.hurry),e.off(window,"keyup",n.hurry)}e.defineOption("autoRefresh",!1,(function(n,r){n.state.autoRefresh&&(t(0,n.state.autoRefresh),n.state.autoRefresh=null),r&&0==n.display.wrapper.offsetHeight&&function(n,r){function i(){n.display.wrapper.offsetHeight?(t(0,r),n.display.lastWrapHeight!=n.display.wrapper.clientHeight&&n.refresh()):r.timeout=setTimeout(i,r.delay)}r.timeout=setTimeout(i,r.delay),r.hurry=function(){clearTimeout(r.timeout),r.timeout=setTimeout(i,50)},e.on(window,"mouseup",r.hurry),e.on(window,"keyup",r.hurry)}(n,n.state.autoRefresh={delay:r.delay||250})}))})("object"==typeof n&&"object"==typeof t?e("../../lib/codemirror"):CodeMirror)},{"../../lib/codemirror":10}],4:[function(e,t,n){(function(e){"use strict";e.defineOption("fullScreen",!1,(function(t,n,r){r==e.Init&&(r=!1),!r!=!n&&(n?function(e){var t=e.getWrapperElement();e.state.fullScreenRestore={scrollTop:window.pageYOffset,scrollLeft:window.pageXOffset,width:t.style.width,height:t.style.height},t.style.width="",t.style.height="auto",t.className+=" CodeMirror-fullscreen",document.documentElement.style.overflow="hidden",e.refresh()}(t):function(e){var t=e.getWrapperElement();t.className=t.className.replace(/\s*CodeMirror-fullscreen\b/,""),document.documentElement.style.overflow="";var n=e.state.fullScreenRestore;t.style.width=n.width,t.style.height=n.height,window.scrollTo(n.scrollLeft,n.scrollTop),e.refresh()}(t))}))})("object"==typeof n&&"object"==typeof t?e("../../lib/codemirror"):CodeMirror)},{"../../lib/codemirror":10}],5:[function(e,t,n){(function(e){function t(e){e.state.placeholder&&(e.state.placeholder.parentNode.removeChild(e.state.placeholder),e.state.placeholder=null)}function n(e){t(e);var n=e.state.placeholder=document.createElement("pre");n.style.cssText="height: 0; overflow: visible",n.style.direction=e.getOption("direction"),n.className="CodeMirror-placeholder CodeMirror-line-like";var r=e.getOption("placeholder");"string"==typeof r&&(r=document.createTextNode(r)),n.appendChild(r),e.display.lineSpace.insertBefore(n,e.display.lineSpace.firstChild)}function r(e){o(e)&&n(e)}function i(e){var r=e.getWrapperElement(),i=o(e);r.className=r.className.replace(" CodeMirror-empty","")+(i?" CodeMirror-empty":""),i?n(e):t(e)}function o(e){return 1===e.lineCount()&&""===e.getLine(0)}e.defineOption("placeholder","",(function(o,a,l){var s=l&&l!=e.Init;if(a&&!s)o.on("blur",r),o.on("change",i),o.on("swapDoc",i),e.on(o.getInputField(),"compositionupdate",o.state.placeholderCompose=function(){!function(e){setTimeout((function(){var r=!1;Line truncated
+1 -1
View File
@@ -72,7 +72,7 @@ class ViewTests(TestCase):
"""
# Change this number as more javascript files are added to the index page
N_SCRIPT_FILES = 38
N_SCRIPT_FILES = 39
content = self.get_index_page()
+18 -26
View File
@@ -3,7 +3,6 @@
{% load i18n %}
{% load inventree_extras %}
{% load status_codes %}
{% load markdownify %}
{% block sidebar %}
{% include "build/sidebar.html" %}
@@ -309,24 +308,16 @@
<div class='panel panel-hidden' id='panel-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Build Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-small btn-outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Build Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if build.notes %}
{{ build.notes | markdownify }}
{% endif %}
<textarea id='build-notes'></textarea>
</div>
</div>
@@ -392,17 +383,18 @@ onPanelLoad('attachments', function() {
});
onPanelLoad('notes', function() {
$('#edit-notes').click(function() {
constructForm('{% url "api-build-detail" build.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Notes" %}',
reload: true,
});
});
setupNotesField(
'build-notes',
'{% url "api-build-detail" build.pk %}',
{
{% if roles.build.change %}
editable: true,
{% else %}
editable: false,
{% endif %}
}
);
});
function reloadTable() {
+43 -48
View File
@@ -1,7 +1,6 @@
{% extends "company/company_base.html" %}
{% load static %}
{% load i18n %}
{% load markdownify %}
{% block sidebar %}
{% include 'company/sidebar.html' %}
@@ -181,24 +180,16 @@
<div class='panel panel-hidden' id='panel-company-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Company Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-small btn-outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Company Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if company.notes %}
{{ company.notes | markdownify }}
{% endif %}
<textarea id='company-notes'></textarea>
</div>
</div>
@@ -207,16 +198,15 @@
{% block js_ready %}
{{ block.super }}
$('#edit-notes').click(function() {
constructForm('{% url "api-company-detail" company.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Notes" %}',
reload: true,
});
onPanelLoad('company-notes', function() {
setupNotesField(
'company-notes',
'{% url "api-company-detail" company.pk %}',
{
editable: true,
}
)
});
loadStockTable($("#assigned-stock-table"), {
@@ -230,18 +220,37 @@
filterTarget: '#filter-list-customerstock',
});
{% if company.is_customer %}
loadSalesOrderTable("#sales-order-table", {
url: "{% url 'api-so-list' %}",
params: {
customer: {{ company.id }},
}
onPanelLoad('company-stock', function() {
loadStockTable($('#stock-table'), {
url: "{% url 'api-stock-list' %}",
params: {
company: {{ company.id }},
part_detail: true,
supplier_part_detail: true,
location_detail: true,
},
buttons: [
'#stock-options',
],
filterKey: "companystock",
});
});
$("#new-sales-order").click(function() {
{% if company.is_customer %}
onPanelLoad('panel-sales-orders', function() {
loadSalesOrderTable("#sales-order-table", {
url: "{% url 'api-so-list' %}",
params: {
customer: {{ company.id }},
}
});
createSalesOrder({
customer: {{ company.pk }},
$("#new-sales-order").click(function() {
createSalesOrder({
customer: {{ company.pk }},
});
});
});
{% endif %}
@@ -270,20 +279,6 @@
{% endif %}
loadStockTable($('#stock-table'), {
url: "{% url 'api-stock-list' %}",
params: {
company: {{ company.id }},
part_detail: true,
supplier_part_detail: true,
location_detail: true,
},
buttons: [
'#stock-options',
],
filterKey: "companystock",
});
{% if company.is_manufacturer %}
function reloadManufacturerPartTable() {
@@ -4,7 +4,6 @@
{% load status_codes %}
{% load i18n %}
{% load static %}
{% load markdownify %}
{% block sidebar %}
{% include 'order/po_sidebar.html' %}
@@ -71,24 +70,16 @@
<div class='panel panel-hidden' id='panel-order-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Order Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Order Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if order.notes %}
{{ order.notes | markdownify }}
{% endif %}
<textarea id='order-notes'></textarea>
</div>
</div>
@@ -98,16 +89,18 @@
{{ block.super }}
$('#edit-notes').click(function() {
constructForm('{% url "api-po-detail" order.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Notes" %}',
reload: true,
});
onPanelLoad('order-notes', function() {
setupNotesField(
'order-notes',
'{% url "api-po-detail" order.pk %}',
{
{% if roles.purchase_order.change %}
editable: true,
{% else %}
editable: false,
{% endif %}
}
);
});
enableDragAndDrop(
@@ -4,7 +4,6 @@
{% load status_codes %}
{% load i18n %}
{% load static %}
{% load markdownify %}
{% block sidebar %}
{% include "order/so_sidebar.html" %}
@@ -118,24 +117,16 @@
<div class='panel panel-hidden' id='panel-order-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Order Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Order Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if order.notes %}
{{ order.notes | markdownify }}
{% endif %}
<textarea id='order-notes'></textarea>
</div>
</div>
@@ -176,16 +167,18 @@
});
});
$('#edit-notes').click(function() {
constructForm('{% url "api-so-detail" order.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Notes" %}',
reload: true,
});
onPanelLoad('order-notes', function() {
setupNotesField(
'order-notes',
'{% url "api-so-detail" order.pk %}',
{
{% if roles.purchase_order.change %}
editable: true,
{% else %}
editable: false,
{% endif %}
}
);
});
enableDragAndDrop(
+18 -45
View File
@@ -3,7 +3,6 @@
{% load i18n %}
{% load inventree_extras %}
{% load crispy_forms_tags %}
{% load markdownify %}
{% block sidebar %}
{% include 'part/part_sidebar.html' %}
@@ -134,24 +133,16 @@
<div class='panel panel-hidden' id='panel-part-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Part Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if part.notes %}
{{ part.notes | markdownify }}
{% endif %}
<textarea id='part-notes'></textarea>
</div>
</div>
@@ -419,6 +410,18 @@
{% block js_ready %}
{{ block.super }}
// Load the "notes" tab
onPanelLoad('part-notes', function() {
setupNotesField(
'part-notes',
'{% url "api-part-detail" part.pk %}',
{
editable: {% if roles.part.change %}true{% else %}false{% endif %},
}
);
});
// Load the "scheduling" tab
onPanelLoad('scheduling', function() {
loadPartSchedulingChart('part-schedule-chart', {{ part.pk }});
@@ -832,36 +835,6 @@
});
});
$('#edit-notes').click(function() {
constructForm('{% url "api-part-detail" part.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Part Notes" %}',
reload: true,
});
});
$(".slidey").change(function() {
var field = $(this).attr('fieldname');
var checked = $(this).prop('checked');
var data = {};
data[field] = checked;
// Update the particular field
inventreePut("{% url 'api-part-detail' part.id %}",
data,
{
method: 'PATCH',
reloadOnSuccess: true,
},
);
});
onPanelLoad("part-parameters", function() {
loadPartParameterTable(
'#parameter-table',
@@ -4,7 +4,6 @@
{% load report %}
{% load barcode %}
{% load inventree_extras %}
{% load markdownify %}
{% block page_margin %}
margin: 2cm;
+20 -26
View File
@@ -4,7 +4,6 @@
{% load inventree_extras %}
{% load i18n %}
{% load l10n %}
{% load markdownify %}
{% block sidebar %}
{% include "stock/stock_sidebar.html" %}
@@ -133,24 +132,16 @@
<div class='panel panel-hidden' id='panel-notes'>
<div class='panel-heading'>
<div class='row'>
<div class='col-sm-6'>
<h4>{% trans "Stock Item Notes" %}</h4>
</div>
<div class='col-sm-6'>
<div class='btn-group float-right'>
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-small btn-outline-secondary'>
<span class='fas fa-edit'>
</span>
</button>
</div>
<div class='d-flex flex-wrap'>
<h4>{% trans "Stock Item Notes" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% include "notes_buttons.html" %}
</div>
</div>
</div>
<div class='panel-content'>
{% if item.notes %}
{{ item.notes | markdownify }}
{% endif %}
<textarea id='stock-notes'></textarea>
</div>
</div>
@@ -235,18 +226,21 @@
reload: true,
}
);
});
$('#edit-notes').click(function() {
constructForm('{% url "api-stock-detail" item.pk %}', {
fields: {
notes: {
multiline: true,
}
},
title: '{% trans "Edit Notes" %}',
reload: true,
});
});
onPanelLoad('notes', function() {
setupNotesField(
'stock-notes',
'{% url "api-stock-detail" item.pk %}',
{
{% if roles.stock.change and user_owns_item %}
editable: true,
{% else %}
editable: false,
{% endif %}
}
);
});
enableDragAndDrop(
@@ -89,7 +89,7 @@ $('table').find('.boolean-setting').change(function() {
},
{
method: 'PATCH',
onSuccess: function(data) {
success: function(data) {
},
error: function(xhr) {
showApiError(xhr, url);
+2
View File
@@ -48,6 +48,7 @@
<link rel="stylesheet" href="{% static 'select2/css/select2-bootstrap-5-theme.css' %}">
<link rel="stylesheet" href="{% static 'fullcalendar/main.css' %}">
<link rel="stylesheet" href="{% static 'script/jquery-ui/jquery-ui.min.css' %}">
<link rel="stylesheet" href="{% static 'easymde/easymde.min.css' %}">
<link rel="stylesheet" href="{% static 'css/inventree.css' %}">
@@ -160,6 +161,7 @@
<script type='text/javascript' src="{% static 'script/chart.js' %}"></script>
<script type='text/javascript' src="{% static 'script/moment.js' %}"></script>
<script type='text/javascript' src="{% static 'script/chartjs-adapter-moment.js' %}"></script>
<script type='text/javascript' src="{% static 'easymde/easymde.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
@@ -10,6 +10,7 @@
makeProgressBar,
renderLink,
select2Thumbnail,
setupNotesField,
thumbnailImage
yesNoLabel,
*/
@@ -221,3 +222,93 @@ function renderLink(text, url, options={}) {
return `<a href="${url}">${text}</a>`;
}
function setupNotesField(element, url, options={}) {
var editable = options.editable || false;
// Read initial notes value from the URL
var initial = null;
inventreeGet(url, {}, {
async: false,
success: function(response) {
initial = response[options.notes_field || 'notes'];
},
});
var toolbar_icons = [
'preview', '|',
];
if (editable) {
// Heading icons
toolbar_icons.push('heading-1', 'heading-2', 'heading-3', '|');
// Font style
toolbar_icons.push('bold', 'italic', 'strikethrough', '|');
// Text formatting
toolbar_icons.push('unordered-list', 'ordered-list', 'code', 'quote', '|');
// Elements
toolbar_icons.push('table', 'link', 'image');
}
// Markdown syntax guide
toolbar_icons.push('|', 'guide');
const mde = new EasyMDE({
element: document.getElementById(element),
initialValue: initial,
toolbar: toolbar_icons,
shortcuts: [],
});
// Hide the toolbar
$(`#${element}`).next('.EasyMDEContainer').find('.editor-toolbar').hide();
if (!editable) {
// Set readonly
mde.codemirror.setOption('readOnly', true);
// Hide the "edit" and "save" buttons
$('#edit-notes').hide();
$('#save-notes').hide();
} else {
mde.togglePreview();
// Add callback for "edit" button
$('#edit-notes').click(function() {
$('#edit-notes').hide();
$('#save-notes').show();
// Show the toolbar
$(`#${element}`).next('.EasyMDEContainer').find('.editor-toolbar').show();
mde.togglePreview();
});
// Add callback for "save" button
$('#save-notes').click(function() {
var data = {};
data[options.notes_field || 'notes'] = mde.value();
inventreePut(url, data, {
method: 'PATCH',
success: function(response) {
showMessage('{% trans "Notes updated" %}', {style: 'success'});
},
error: function(xhr) {
showApiError(xhr, url);
}
});
});
}
}
+8
View File
@@ -0,0 +1,8 @@
{% load i18n %}
<button type='button' id='edit-notes' title='{% trans "Edit" %}' class='btn btn-primary'>
<span class='fas fa-edit'></span> {% trans "Edit" %}
</button>
<button type='button' id='save-notes' title='{% trans "Save" %}' class='btn btn-success' style='display: none;'>
<span class='fas fa-save'></span> {% trans "Save" %}
</button>
+2 -1
View File
@@ -1,5 +1,6 @@
# Please keep this list sorted
Django==3.2.12 # Django package
Django==3.2.12 # Django package
bleach==4.1.0 # HTML santization
certifi # Certifi is (most likely) installed through one of the requirements above
coreapi==2.3.0 # API documentation
coverage==5.3 # Unit test coverage