FEATURE: Use spreadsheet editor for building tables
This commit is contained in:
parent
a50cd73dcf
commit
3eee3da853
|
@ -2,6 +2,5 @@
|
|||
@import "vendor/jspreadsheet-datatables";
|
||||
@import "vendor/jspreadsheet-theme";
|
||||
@import "vendor/jsuites";
|
||||
|
||||
@import "table-builder";
|
||||
@import "table-editor";
|
||||
@import "post/table-edit-decorator";
|
||||
@import "modal/insert-table-modal";
|
||||
|
|
|
@ -3,22 +3,24 @@ import { action } from "@ember/object";
|
|||
import showModal from "discourse/lib/show-modal";
|
||||
|
||||
export default apiInitializer("0.11.1", (api) => {
|
||||
api.modifyClass("component:d-editor", {
|
||||
api.modifyClass("controller:composer", {
|
||||
pluginId: "discourse-table-builder",
|
||||
|
||||
@action
|
||||
showTableBuilder(event) {
|
||||
showModal("table-builder-modal").set("toolbarEvent", event);
|
||||
showTableBuilder() {
|
||||
showModal("insert-table-modal").setProperties({
|
||||
toolbarEvent: this.toolbarEvent,
|
||||
tableHtml: null,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
api.onToolbarCreate((toolbar) => {
|
||||
toolbar.addButton({
|
||||
api.addToolbarPopupMenuOptionsCallback(() => {
|
||||
return {
|
||||
id: "table-builder",
|
||||
group: "insertions",
|
||||
action: "showTableBuilder",
|
||||
icon: "table",
|
||||
sendAction: (event) => toolbar.context.send("showTableBuilder", event),
|
||||
title: themePrefix("discourse_table_builder.composer.button"),
|
||||
});
|
||||
label: themePrefix("discourse_table_builder.composer.button"),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ export default apiInitializer("0.11.1", (api) => {
|
|||
|
||||
return ajax(`/posts/${this.id}`, { type: "GET" })
|
||||
.then((post) => {
|
||||
showModal("table-editor-modal", {
|
||||
showModal("insert-table-modal", {
|
||||
model: post,
|
||||
}).setProperties({
|
||||
tableHtml: tempTable,
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import GlimmerComponent from "discourse/components/glimmer";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default class BodyRow extends GlimmerComponent {
|
||||
get disableRemoveRow() {
|
||||
if (this.args.allRows.length > 1) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
addBodyValue() {
|
||||
const columnId = this.args.columnId;
|
||||
const rowId = this.args.row.id;
|
||||
const value = this.bodyRowValue;
|
||||
|
||||
this.args.setRowValue(columnId, rowId, value);
|
||||
}
|
||||
|
||||
@action
|
||||
addRow() {
|
||||
const columnId = this.args.columnId;
|
||||
const rowId = this.args.allRows.length + 1;
|
||||
|
||||
this.args.addRow(columnId, rowId);
|
||||
}
|
||||
|
||||
@action
|
||||
removeRow() {
|
||||
this.args.removeRow(this.args.columnId, this.args.row);
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
import GlimmerComponent from "discourse/components/glimmer";
|
||||
import { action } from "@ember/object";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
export default class HeaderColumn extends GlimmerComponent {
|
||||
@tracked alignment;
|
||||
|
||||
get disableRemoveColumn() {
|
||||
if (this.args.tableItems.length > 1) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
addColumn() {
|
||||
const newColumnId = this.args.tableItems.length + 1;
|
||||
this.args.addColumn(newColumnId);
|
||||
}
|
||||
|
||||
@action
|
||||
removeColumn() {
|
||||
this.args.removeColumn(this.args.column);
|
||||
}
|
||||
|
||||
@action
|
||||
addColumnHeader() {
|
||||
const index = this.args.columnId - 1;
|
||||
this.args.setColumnHeader(index, this.columnHeaderValue);
|
||||
}
|
||||
|
||||
@action
|
||||
addRow(columnId, rowId) {
|
||||
this.args.addRow(columnId, rowId);
|
||||
}
|
||||
|
||||
@action
|
||||
removeRow(columnId, row) {
|
||||
this.args.removeRow(columnId, row);
|
||||
}
|
||||
|
||||
@action
|
||||
setRowValue(columnId, rowId, value) {
|
||||
this.args.setRowValue(columnId, rowId, value);
|
||||
}
|
||||
|
||||
@action
|
||||
alignColumn(alignment) {
|
||||
this.args.alignColumn(this.args.columnId, alignment);
|
||||
this.alignment = alignment;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
// import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { arrayToTable, findTableRegex, tableToObj } from "../lib/utilities";
|
||||
|
@ -6,26 +5,115 @@ import Component from "@ember/component";
|
|||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import I18n from "I18n";
|
||||
import { schedule } from "@ember/runloop";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "",
|
||||
showEditReason: false,
|
||||
spreadsheet: null,
|
||||
|
||||
// Lifecycle Methods:
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.loadLibraries().then(() => {
|
||||
this.buildTable(this.tableHtml);
|
||||
schedule("afterRender", () => {
|
||||
this.loadLibraries().then(() => {
|
||||
if (this.isEditingTable) {
|
||||
this.buildPopulatedTable(this.tableHtml);
|
||||
} else {
|
||||
this.buildNewTable();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
this.spreadsheet?.destroy();
|
||||
},
|
||||
|
||||
// Getters:
|
||||
get isEditingTable() {
|
||||
if (this.tableHtml) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
get modalAttributes() {
|
||||
if (this.isEditingTable) {
|
||||
return {
|
||||
title: themePrefix("discourse_table_builder.edit.modal.title"),
|
||||
insertTable: {
|
||||
title: themePrefix("discourse_table_builder.edit.modal.create"),
|
||||
icon: "pencil-alt",
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
title: themePrefix("discourse_table_builder.modal.title"),
|
||||
insertTable: {
|
||||
title: themePrefix("discourse_table_builder.modal.create"),
|
||||
icon: "plus",
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
// Actions:
|
||||
@action
|
||||
showEditReasonField() {
|
||||
if (this.showEditReason) {
|
||||
return this.set("showEditReason", false);
|
||||
} else {
|
||||
return this.set("showEditReason", true);
|
||||
}
|
||||
},
|
||||
|
||||
@action
|
||||
cancelTableInsertion() {
|
||||
this.triggerModalClose();
|
||||
},
|
||||
|
||||
@action
|
||||
insertTable() {
|
||||
const updatedHeaders = this.spreadsheet.getHeaders().split(","); // keys
|
||||
const updatedData = this.spreadsheet.getData(); // values
|
||||
const markdownTable = this.buildTableMarkdown(updatedHeaders, updatedData);
|
||||
|
||||
if (!this.isEditingTable) {
|
||||
this.toolbarEvent.addText(markdownTable);
|
||||
return this.triggerModalClose();
|
||||
} else {
|
||||
return this.updateTable(markdownTable);
|
||||
}
|
||||
},
|
||||
|
||||
// Helper Methods:
|
||||
loadLibraries() {
|
||||
return loadScript(settings.theme_uploads.jsuites).then(() => {
|
||||
return loadScript(settings.theme_uploads.jspreadsheet);
|
||||
});
|
||||
},
|
||||
|
||||
buildTable(table) {
|
||||
buildNewTable() {
|
||||
const data = [
|
||||
["", "", ""],
|
||||
["", "", ""],
|
||||
["", "", ""],
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{ title: "Column 1", width: 150 },
|
||||
{ title: "Column 2", width: 150 },
|
||||
{ title: "Column 3", width: 150 },
|
||||
];
|
||||
|
||||
return this.buildSpreadsheet(data, columns);
|
||||
},
|
||||
|
||||
buildPopulatedTable(table) {
|
||||
const tableObject = tableToObj(table);
|
||||
const headings = [];
|
||||
const tableData = [];
|
||||
|
@ -47,47 +135,20 @@ export default Component.extend({
|
|||
};
|
||||
});
|
||||
|
||||
return this.buildSpreadsheet(tableData, columns);
|
||||
},
|
||||
|
||||
buildSpreadsheet(data, columns, opts = {}) {
|
||||
const spreadsheetContainer = document.querySelector("#spreadsheet");
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
this.spreadsheet = jspreadsheet(spreadsheetContainer, {
|
||||
data: tableData,
|
||||
data,
|
||||
columns,
|
||||
...opts,
|
||||
});
|
||||
},
|
||||
|
||||
@action
|
||||
showEditReasonField() {
|
||||
if (this.showEditReason) {
|
||||
return this.set("showEditReason", false);
|
||||
} else {
|
||||
return this.set("showEditReason", true);
|
||||
}
|
||||
},
|
||||
|
||||
@action
|
||||
cancelTableEdit() {
|
||||
this.triggerModalClose();
|
||||
},
|
||||
|
||||
@action
|
||||
editTable() {
|
||||
const updatedHeaders = this.spreadsheet.getHeaders().split(","); // keys
|
||||
const updatedData = this.spreadsheet.getData(); // values
|
||||
|
||||
const markdownTable = this.buildTableMarkdown(updatedHeaders, updatedData);
|
||||
const tableId = this.get("tableId");
|
||||
const postId = this.model.id;
|
||||
const newRaw = markdownTable;
|
||||
const editReason =
|
||||
this.get("editReason") ||
|
||||
I18n.t(themePrefix("discourse_table_builder.edit.default_edit_reason"));
|
||||
const raw = this.model.raw;
|
||||
const newPostRaw = this.buildUpdatedPost(tableId, raw, newRaw);
|
||||
|
||||
this.updateTable(postId, newPostRaw, editReason);
|
||||
},
|
||||
|
||||
buildUpdatedPost(tableId, raw, newRaw) {
|
||||
const tableToEdit = raw.match(findTableRegex());
|
||||
let editedTable;
|
||||
|
@ -101,7 +162,20 @@ export default Component.extend({
|
|||
return editedTable;
|
||||
},
|
||||
|
||||
updateTable(postId, raw, edit_reason) {
|
||||
updateTable(markdownTable) {
|
||||
const tableId = this.get("tableId");
|
||||
const postId = this.model.id;
|
||||
const newRaw = markdownTable;
|
||||
const editReason =
|
||||
this.get("editReason") ||
|
||||
I18n.t(themePrefix("discourse_table_builder.edit.default_edit_reason"));
|
||||
const raw = this.model.raw;
|
||||
const newPostRaw = this.buildUpdatedPost(tableId, raw, newRaw);
|
||||
|
||||
return this.sendTableUpdate(postId, newPostRaw, editReason);
|
||||
},
|
||||
|
||||
sendTableUpdate(postId, raw, edit_reason) {
|
||||
return ajax(`/posts/${postId}.json`, {
|
||||
type: "PUT",
|
||||
data: {
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { A } from "@ember/array";
|
||||
|
||||
export default class extends Controller {
|
||||
@tracked tableItems = A([
|
||||
{ column: 1, rows: A([{ id: 1 }]) },
|
||||
{ column: 2, rows: A([{ id: 1 }]) },
|
||||
]);
|
||||
|
||||
resetData() {
|
||||
this.tableItems = A([
|
||||
{ column: 1, rows: A([{ id: 1 }]) },
|
||||
{ column: 2, rows: A([{ id: 1 }]) },
|
||||
]);
|
||||
}
|
||||
|
||||
@action
|
||||
cancelTableCreation() {
|
||||
this.send("closeModal");
|
||||
}
|
||||
|
||||
createDivider(alignment) {
|
||||
switch (alignment) {
|
||||
case "left":
|
||||
return ":--";
|
||||
break;
|
||||
case "right":
|
||||
return "--:";
|
||||
break;
|
||||
case "center":
|
||||
return ":--:";
|
||||
break;
|
||||
default:
|
||||
return "--";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buildTable(table) {
|
||||
const headings = [];
|
||||
const divider = [];
|
||||
const rows = [];
|
||||
|
||||
table.forEach((item) => {
|
||||
headings.push(item.header);
|
||||
divider.push(this.createDivider(item.alignment));
|
||||
item.rows.forEach((r) => rows.push(r));
|
||||
});
|
||||
|
||||
// Make an object for each row rather than by column
|
||||
const rowItems = rows.reduce((row, { id, content }) => {
|
||||
row[id] ??= { id, content: [] };
|
||||
if (Array.isArray(content)) {
|
||||
row[id].content = row[id].value.concat(content);
|
||||
} else {
|
||||
row[id].content.push(content);
|
||||
}
|
||||
return row;
|
||||
}, {});
|
||||
|
||||
const header = `|${headings.join("|")}|\n`;
|
||||
const tableDivider = `|${divider.join("|")}|\n`;
|
||||
|
||||
let rowValues;
|
||||
Object.values(rowItems).forEach((item) => {
|
||||
item.content.forEach((line) => {
|
||||
if (line === undefined) {
|
||||
line = "";
|
||||
}
|
||||
|
||||
if (rowValues) {
|
||||
rowValues += `${line}|`;
|
||||
} else {
|
||||
rowValues = `|${line}|`;
|
||||
}
|
||||
});
|
||||
rowValues += "\n";
|
||||
});
|
||||
|
||||
let tableMarkdown = header + tableDivider + rowValues;
|
||||
|
||||
this.toolbarEvent.addText(tableMarkdown);
|
||||
}
|
||||
|
||||
@action
|
||||
createTable() {
|
||||
this.buildTable(this.tableItems);
|
||||
this.resetData();
|
||||
this.send("closeModal");
|
||||
}
|
||||
|
||||
@action
|
||||
removeColumn(column) {
|
||||
this.tableItems.removeObject(column);
|
||||
}
|
||||
|
||||
@action
|
||||
addColumn(columnId) {
|
||||
this.tableItems.pushObject({
|
||||
column: columnId,
|
||||
rows: A([{ id: 1 }]),
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
setColumnHeader(index, value) {
|
||||
this.tableItems[index].header = value;
|
||||
}
|
||||
|
||||
@action
|
||||
addRow(columnId, rowId) {
|
||||
this.tableItems.find((item) => {
|
||||
if (item.column === columnId) {
|
||||
item.rows.pushObject({ id: rowId });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
removeRow(columnId, row) {
|
||||
this.tableItems.find((item) => {
|
||||
if (item.column === columnId) {
|
||||
if (item.rows.length === 1) {
|
||||
// do not allow deleting if only one row left
|
||||
return;
|
||||
} else {
|
||||
item.rows.removeObject(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
setRowValue(columnId, rowId, value) {
|
||||
const index = columnId - 1;
|
||||
this.tableItems[index].rows.find((row) => {
|
||||
if (row.id === rowId) {
|
||||
row.content = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
alignColumn(columnId, alignment) {
|
||||
this.tableItems.find((item) => {
|
||||
if (item.column === columnId) {
|
||||
item.alignment = alignment;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<div class="body-row">
|
||||
<TextField
|
||||
@value={{bodyRowValue}}
|
||||
@class="table-builder-input"
|
||||
@placeholderKey={{theme-prefix "discourse_table_builder.modal.body"}}
|
||||
{{on "change" this.addBodyValue}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="plus"
|
||||
@title={{theme-prefix "discourse_table_builder.modal.buttons.add_row"}}
|
||||
@action={{action "addRow"}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="trash-alt"
|
||||
@class="btn-danger"
|
||||
@title={{theme-prefix "discourse_table_builder.modal.buttons.remove_row"}}
|
||||
@action={{action "removeRow"}}
|
||||
@disabled={{this.disableRemoveRow}}
|
||||
/>
|
||||
</div>
|
|
@ -1,62 +0,0 @@
|
|||
<div class="header-column">
|
||||
<div class="header-row">
|
||||
<TextField
|
||||
@value={{columnHeaderValue}}
|
||||
@class="table-builder-input"
|
||||
@id="header-column-{{@columnId}}"
|
||||
@placeholderKey={{theme-prefix "discourse_table_builder.modal.header"}}
|
||||
{{on "change" this.addColumnHeader}}
|
||||
/>
|
||||
<div class="body-inputs">
|
||||
{{#each @column.rows as |item|}}
|
||||
<BodyRow
|
||||
@addRow={{this.addRow}}
|
||||
@columnId={{@columnId}}
|
||||
@allRows={{@column.rows}}
|
||||
@row={{item}}
|
||||
@removeRow={{this.removeRow}}
|
||||
@setRowValue={{this.setRowValue}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="column-action-buttons column-aligned-{{this.alignment}}">
|
||||
<DButton
|
||||
@icon="align-left"
|
||||
@class="btn-align-left"
|
||||
@title={{theme-prefix "discourse_table_builder.modal.buttons.align_left"}}
|
||||
@action={{action "alignColumn" "left"}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="align-center"
|
||||
@class="btn-align-center"
|
||||
@title={{theme-prefix
|
||||
"discourse_table_builder.modal.buttons.align_center"
|
||||
}}
|
||||
@action={{action "alignColumn" "center"}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="align-right"
|
||||
@class="btn-align-right"
|
||||
@title={{theme-prefix
|
||||
"discourse_table_builder.modal.buttons.align_right"
|
||||
}}
|
||||
@action={{action "alignColumn" "right"}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="trash-alt"
|
||||
@class="btn-danger"
|
||||
@action={{action "removeColumn"}}
|
||||
@title={{theme-prefix
|
||||
"discourse_table_builder.modal.buttons.remove_column"
|
||||
}}
|
||||
@disabled={{this.disableRemoveColumn}}
|
||||
/>
|
||||
<DButton
|
||||
@icon="plus"
|
||||
@action={{action "addColumn"}}
|
||||
@title={{theme-prefix "discourse_table_builder.modal.buttons.add_column"}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
|
@ -1,38 +1,62 @@
|
|||
<DModalBody
|
||||
@title={{theme-prefix "discourse_table_builder.edit.modal.title"}}
|
||||
@class="table-editor-modal"
|
||||
>
|
||||
<div class="edit-reason">
|
||||
<DButton
|
||||
@icon="info-circle"
|
||||
@title={{theme-prefix
|
||||
"discourse_table_builder.edit.modal.trigger_reason"
|
||||
}}
|
||||
@action={{action "showEditReasonField"}}
|
||||
@class="btn btn-icon btn-flat no-text btn-edit-reason"
|
||||
/>
|
||||
{{#if showEditReason}}
|
||||
<TextField
|
||||
@value={{this.editReason}}
|
||||
@placeholderKey={{theme-prefix
|
||||
"discourse_table_builder.edit.modal.reason"
|
||||
<DModalBody @title={{this.modalAttributes.title}} @class="insert-table-modal">
|
||||
{{#if this.isEditingTable}}
|
||||
<div class="edit-reason">
|
||||
<DButton
|
||||
@icon="info-circle"
|
||||
@title={{theme-prefix
|
||||
"discourse_table_builder.edit.modal.trigger_reason"
|
||||
}}
|
||||
@action={{action "showEditReasonField"}}
|
||||
@class="btn btn-icon btn-flat no-text btn-edit-reason"
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if showEditReason}}
|
||||
<TextField
|
||||
@value={{this.editReason}}
|
||||
@placeholderKey={{theme-prefix
|
||||
"discourse_table_builder.edit.modal.reason"
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div id="spreadsheet" tabindex="1" class="jexcel_container"></div>
|
||||
</DModalBody>
|
||||
|
||||
<div class="modal-footer">
|
||||
<DButton
|
||||
@class="btn-edit-table"
|
||||
@label={{theme-prefix "discourse_table_builder.edit.modal.create"}}
|
||||
@icon="pencil-alt"
|
||||
@action={{action "editTable"}}
|
||||
/>
|
||||
<DButton
|
||||
@class="btn-flat"
|
||||
@label={{theme-prefix "discourse_table_builder.edit.modal.cancel"}}
|
||||
@action={{action "cancelTableEdit"}}
|
||||
/>
|
||||
<div class="primary-actions">
|
||||
<DButton
|
||||
@class="btn-insert-table"
|
||||
@label={{this.modalAttributes.insertTable.title}}
|
||||
@icon={{this.modalAttributes.insertTable.icon}}
|
||||
@action={{action "insertTable"}}
|
||||
/>
|
||||
<DButton
|
||||
@class="btn-flat"
|
||||
@label={{theme-prefix "discourse_table_builder.edit.modal.cancel"}}
|
||||
@action={{action "cancelTableInsertion"}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="secondary-actions">
|
||||
<DPopover>
|
||||
<DButton class="trigger" @icon="question" />
|
||||
<ul>
|
||||
<h4>{{theme-i18n "discourse_table_builder.modal.help.title"}}</h4>
|
||||
<li>
|
||||
<kbd>
|
||||
{{theme-i18n "discourse_table_builder.modal.help.enter_key"}}
|
||||
</kbd>
|
||||
{{theme-i18n "discourse_table_builder.modal.help.new_row"}}
|
||||
</li>
|
||||
<li>
|
||||
<kbd>
|
||||
{{theme-i18n "discourse_table_builder.modal.help.tab_key"}}
|
||||
</kbd>
|
||||
{{theme-i18n "discourse_table_builder.modal.help.new_col"}}
|
||||
</li>
|
||||
<li>{{theme-i18n "discourse_table_builder.modal.help.options"}}</li>
|
||||
</ul>
|
||||
</DPopover>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
@tableHtml={{this.tableHtml}}
|
||||
@tableId={{this.tableId}}
|
||||
@triggerModalClose={{action "closeEditModal"}}
|
||||
@toolbarEvent={{this.toolbarEvent}}
|
||||
/>
|
|
@ -1,40 +0,0 @@
|
|||
<DModalBody
|
||||
@title={{theme-prefix "discourse_table_builder.modal.title"}}
|
||||
@class="table-builder-modal"
|
||||
>
|
||||
<form id="insert-markdown-table-form" {{action "createTable" on="submit"}}>
|
||||
<section class="header-section">
|
||||
<div class="table-header-fields">
|
||||
{{#each this.tableItems as |item|}}
|
||||
<HeaderColumn
|
||||
@column={{item}}
|
||||
@columnId={{item.column}}
|
||||
@tableItems={{this.tableItems}}
|
||||
@addColumn={{this.addColumn}}
|
||||
@removeColumn={{this.removeColumn}}
|
||||
@setColumnHeader={{this.setColumnHeader}}
|
||||
@addRow={{this.addRow}}
|
||||
@removeRow={{this.removeRow}}
|
||||
@setRowValue={{this.setRowValue}}
|
||||
@alignColumn={{this.alignColumn}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</DModalBody>
|
||||
|
||||
<div class="modal-footer">
|
||||
<DButton
|
||||
@class="btn-primary btn-build-table"
|
||||
@label={{theme-prefix "discourse_table_builder.modal.create"}}
|
||||
@icon="plus"
|
||||
@action={{action "createTable"}}
|
||||
/>
|
||||
|
||||
<DButton
|
||||
@class="btn-flat"
|
||||
@label={{theme-prefix "discourse_table_builder.modal.cancel"}}
|
||||
@action={{action "cancelTableCreation"}}
|
||||
/>
|
||||
</div>
|
|
@ -7,16 +7,13 @@ en:
|
|||
title: "Table Builder"
|
||||
create: "Build Table"
|
||||
cancel: "cancel"
|
||||
header: "Header"
|
||||
body: "Body"
|
||||
buttons:
|
||||
add_column: "Add Column"
|
||||
remove_column: "Remove Column"
|
||||
add_row: "Add Row"
|
||||
remove_row: "Remove Row"
|
||||
align_left: "Align Left"
|
||||
align_center: "Align Center"
|
||||
align_right: "Align Right"
|
||||
help:
|
||||
title: "Using the Spreadsheet Editor"
|
||||
enter_key: "Enter"
|
||||
tab_key: "Tab"
|
||||
new_row: "at the end of a row to insert a new row."
|
||||
new_col: "at the end of a column to insert a new column."
|
||||
options: "Right-click on cells to access more options in a dropdown menu."
|
||||
edit:
|
||||
btn_edit: "Edit Table"
|
||||
modal:
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
.open-popup-link {
|
||||
display: inline;
|
||||
margin-inline: 0.25em;
|
||||
}
|
||||
|
||||
.btn-edit-table {
|
||||
.btn-insert-table {
|
||||
background: var(--tertiary);
|
||||
color: var(--secondary);
|
||||
|
||||
|
@ -23,7 +18,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.table-editor-modal {
|
||||
.insert-table-modal-modal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
@ -34,4 +29,20 @@
|
|||
color: var(--primary-high);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.secondary-actions .tippy-content {
|
||||
h4 {
|
||||
color: var(--primary);
|
||||
}
|
||||
li {
|
||||
margin-block: 0.25rem;
|
||||
color: var(--primary-high);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.open-popup-link {
|
||||
display: inline;
|
||||
margin-inline: 0.25em;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
.table-builder-modal-modal {
|
||||
.modal-inner-container {
|
||||
--modal-max-width: 90vw;
|
||||
}
|
||||
}
|
||||
|
||||
.table-header-fields {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
.table-builder-input {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-column {
|
||||
border: 1px solid var(--primary-low-mid);
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.column-action-buttons {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
margin-top: auto;
|
||||
border-top: 1px solid var(--primary-low-mid);
|
||||
padding-top: 1rem;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&.column-aligned {
|
||||
&-right .btn-align-right {
|
||||
background: var(--primary-high);
|
||||
.d-icon {
|
||||
color: var(--primary-very-low);
|
||||
}
|
||||
}
|
||||
&-left .btn-align-left {
|
||||
background: var(--primary-high);
|
||||
.d-icon {
|
||||
color: var(--primary-very-low);
|
||||
}
|
||||
}
|
||||
&-center .btn-align-center {
|
||||
background: var(--primary-high);
|
||||
.d-icon {
|
||||
color: var(--primary-very-low);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body-inputs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.table-builder-input {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.body-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
gap: 0.5rem;
|
||||
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue