aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-06-07 19:36:59 -0400
committerNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-06-07 19:36:59 -0400
commit97977e7156eb852c20422fa995bbf96529dfb4e5 (patch)
treec177a7375f0dbab033f46cceb3e7fe64b4624326 /src
parentc8dc7104f8a4923bcfc70dcc5ff5f492666487bd (diff)
sort overhaul for columnheader menu cleanup (sort is now a single action, not a persistent toggle; more like google sheets now)
Diffstat (limited to 'src')
-rw-r--r--src/client/views/EditableView.scss3
-rw-r--r--src/client/views/EditableView.tsx5
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx106
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx16
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx7
6 files changed, 69 insertions, 71 deletions
diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss
index e492068c8..d2f11f5e1 100644
--- a/src/client/views/EditableView.scss
+++ b/src/client/views/EditableView.scss
@@ -34,9 +34,8 @@
pointer-events: all;
}
-
-
.editableView-input:focus {
border: none;
outline: none;
}
+
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 5b690bf33..1652e6cd7 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -10,6 +10,7 @@ import { DocumentIconContainer } from './nodes/DocumentIcon';
import { FieldView, FieldViewProps } from './nodes/FieldView';
import { ObservableReactComponent } from './ObservableReactComponent';
import { OverlayView } from './OverlayView';
+import { Padding } from 'browndash-components';
export interface EditableProps {
/**
@@ -293,10 +294,10 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
// eslint-disable-next-line jsx-a11y/no-autofocus
/>
} else {
- toDisplay = (<span
+ toDisplay = (<span className='editableView-static'
style={{
fontStyle: this._props.fontStyle,
- fontSize: this._props.fontSize,
+ fontSize: this._props.fontSize
}}>
{
// eslint-disable-next-line react/jsx-props-no-spreading
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 31d88fb87..5fe9332f4 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -278,6 +278,9 @@ export class MainView extends ObservableReactComponent<{}> {
library.add(
...[
+ fa.faSort,
+ fa.faArrowUpZA,
+ fa.faArrowDownAZ,
fa.faExclamationCircle,
fa.faEdit,
fa.faArrowDownShortWide,
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 03e7ed5f3..a2f88eb80 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -37,6 +37,7 @@ import { Func } from 'mocha';
import { CollectionView } from '../CollectionView';
import { listSpec } from '../../../../fields/Schema';
import { GetEffectiveAcl } from '../../../../fields/util';
+import { ContextMenuProps } from '../../ContextMenuItem';
const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
@@ -96,6 +97,7 @@ export class CollectionSchemaView extends CollectionSubView() {
@observable _colKeysFiltered: boolean = false;
@observable _cellTags: ObservableMap = new ObservableMap<Doc, Array<string>>();
@observable _lentDocs: Doc[] = [];
+ @observable _docs: Doc[] = this.childDocs;
// target HTMLelement portal for showing a popup menu to edit cell values.
public get MenuTarget() {
@@ -195,7 +197,7 @@ export class CollectionSchemaView extends CollectionSubView() {
// ViewBoxInterface overrides
override isUnstyledView = returnTrue; // used by style provider : turns off opacity, animation effects, scaling
- rowIndex = (doc: Doc) => this.sortedDocs.docs.indexOf(doc);
+ rowIndex = (doc: Doc) => this.displayedDocs.docs.indexOf(doc);
@action
onKeyDown = (e: KeyboardEvent) => {
@@ -205,9 +207,9 @@ export class CollectionSchemaView extends CollectionSubView() {
{
const lastDoc = this._selectedDocs.lastElement();
const lastIndex = this.rowIndex(lastDoc);
- const curDoc = this.sortedDocs.docs[lastIndex];
+ const curDoc = this.displayedDocs.docs[lastIndex];
if (lastIndex >= 0 && lastIndex < this.childDocs.length - 1) {
- const newDoc = this.sortedDocs.docs[lastIndex + 1];
+ const newDoc = this.displayedDocs.docs[lastIndex + 1];
if (this._selectedDocs.includes(newDoc)) {
DocumentView.DeselectView(DocumentView.getFirstDocumentView(curDoc));
this.deselectCell(curDoc);
@@ -224,9 +226,9 @@ export class CollectionSchemaView extends CollectionSubView() {
{
const firstDoc = this._selectedDocs.lastElement();
const firstIndex = this.rowIndex(firstDoc);
- const curDoc = this.sortedDocs.docs[firstIndex];
+ const curDoc = this.displayedDocs.docs[firstIndex];
if (firstIndex > 0 && firstIndex < this.childDocs.length) {
- const newDoc = this.sortedDocs.docs[firstIndex - 1];
+ const newDoc = this.displayedDocs.docs[firstIndex - 1];
if (this._selectedDocs.includes(newDoc)) {
DocumentView.DeselectView(DocumentView.getFirstDocumentView(curDoc));
this.deselectCell(curDoc);
@@ -269,12 +271,6 @@ export class CollectionSchemaView extends CollectionSubView() {
@action
changeSelectedCellColumn = () => {};
- @undoBatch
- setColumnSort = (field: string | undefined, desc: boolean = false) => {
- this.layoutDoc.sortField = field;
- this.layoutDoc.sortDesc = desc;
- };
-
addRow = (doc: Doc | Doc[]) => this.addDocument(doc);
@undoBatch
@@ -512,7 +508,7 @@ export class CollectionSchemaView extends CollectionSubView() {
const startRow = Math.min(lastSelectedRow, index);
const endRow = Math.max(lastSelectedRow, index);
for (let i = startRow; i <= endRow; i++) {
- const currDoc = this.sortedDocs.docs[i];
+ const currDoc = this.displayedDocs.docs[i];
if (!this._selectedDocs.includes(currDoc)) {
this.selectCell(currDoc, this._selectedCol, false, true);
}
@@ -552,7 +548,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this._lowestSelectedIndex = -1;
};
- sortedSelectedDocs = () => this.sortedDocs.docs.filter(doc => this._selectedDocs.includes(doc));
+ sortedSelectedDocs = () => this.displayedDocs.docs.filter(doc => this._selectedDocs.includes(doc));
@computed
get rowDropIndex() {
@@ -584,9 +580,8 @@ export class CollectionSchemaView extends CollectionSubView() {
const draggedDocs = de.complete.docDragData?.draggedDocuments;
if (draggedDocs && super.onInternalDrop(e, de) && !this.sortField) {
- const sortedDocs = this.sortedDocs.docs.slice();
-const filteredChildDocs = sortedDocs.filter((doc: Doc) => !this._lentDocs.includes(doc));
- this.dataDoc[this.fieldKey ?? 'data'] = new List<Doc>([...this.sortedDocs.docs]);
+ const docs = this.displayedDocs.docs.slice();
+ this._docs = docs;
this.clearSelection();
draggedDocs.forEach(doc => {
DocumentView.addViewRenderedCb(doc, dv => dv.select(true));
@@ -639,16 +634,13 @@ const filteredChildDocs = sortedDocs.filter((doc: Doc) => !this._lentDocs.
return undefined;
};
- addDocsFromChildCollection = (collection: Doc) => {
- const childDocs = DocListCast(collection[Doc.LayoutFieldKey(collection)]);
- childDocs.forEach((doc: Doc) => {!this.displayedDocsFunc().includes(doc) && this._lentDocs.push(doc)});
+ addDocsFromOtherCollection = (docs: Doc[]) => {
+ docs.forEach((doc: Doc) => {!this.displayedDocsFunc().includes(doc) && this._lentDocs.push(doc)});
+ this._docs = this.childDocs.slice().concat(this._lentDocs);
}
-
- removeChildCollectionDocs = (collection: Doc) => {
- const children = DocListCast(collection[Doc.LayoutFieldKey(collection)]);
- console.log('before: ' + this._lentDocs)
- this._lentDocs.filter((doc: Doc) => !children.includes(doc));
- console.log('after: ' + this._lentDocs)
+ removeDocsFromOtherCollection = (docs: Doc[]) => {
+ this._lentDocs.filter((doc: Doc) => !docs.includes(doc));
+ this._docs = this.childDocs.slice().concat(this._lentDocs);
}
@computed get fieldDefaultInput() {
@@ -784,27 +776,46 @@ const filteredChildDocs = sortedDocs.filter((doc: Doc) => !this._lentDocs.
this._filterColumnIndex = undefined;
};
+ @undoBatch
+ setColumnSort = (field: string | undefined, desc: boolean = false) => {
+ this.layoutDoc.sortField = field;
+ this.layoutDoc.sortDesc = desc;
+ };
+
openContextMenu = (x: number, y: number, index: number) => {
this.closeColumnMenu();
this.closeFilterMenu();
+ const cm = ContextMenu.Instance;
+ cm.clearItems();
- ContextMenu.Instance.clearItems();
- ContextMenu.Instance.addItem({
+ const revealOptions = cm.findByDescription('Sort column')
+ const sortOptions: ContextMenuProps[] = revealOptions && revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
+ sortOptions.push({description: 'Sort A-Z', event: () => this.sortDocs(this._docs, this.columnKeys[index], false), icon: 'arrow-down-a-z',}); // prettier-ignore
+ sortOptions.push({description: 'Sort Z-A', event: () => this.sortDocs(this._docs, this.columnKeys[index], true), icon: 'arrow-up-z-a'}); // prettier-ignore
+
+ cm.addItem({
description: `Change field`,
event: () => this.openColumnMenu(index, false),
icon: 'pencil-alt',
});
- ContextMenu.Instance.addItem({
+ cm.addItem({
description: 'Filter field',
event: () => this.openFilterMenu(index),
icon: 'filter',
});
- ContextMenu.Instance.addItem({
+ cm.addItem({
+ description: 'Sort column',
+ addDivider: false,
+ noexpand: true,
+ subitems: sortOptions,
+ icon: 'sort'
+ });
+ cm.addItem({
description: 'Delete column',
event: () => this.removeColumn(index),
icon: 'trash',
});
- ContextMenu.Instance.displayMenu(x, y, undefined, false);
+ cm.displayMenu(x, y, undefined, false);
};
@action
@@ -1014,34 +1025,33 @@ const filteredChildDocs = sortedDocs.filter((doc: Doc) => !this._lentDocs.
}
};
- @computed get sortedDocs() {
+ @computed get displayedDocs() {
const draggedDocs = this.isContentActive() ? DragManager.docsBeingDragged : [];
- const field = StrCast(this.layoutDoc.sortField);
- const desc = BoolCast(this.layoutDoc.sortDesc); // is this an ascending or descending sort
- const staticDocs = this.childDocs.filter(d => !draggedDocs.includes(d)).concat(this._lentDocs.filter(d => !draggedDocs.includes(d)));
- const docs = !field
- ? staticDocs
- : [...staticDocs].sort((docA, docB) => {
- // this sorts the documents based on the selected field. returning -1 for a before b, 0 for a = b, 1 for a > b
- const aStr = Field.toString(docA[field] as FieldType);
- const bStr = Field.toString(docB[field] as FieldType);
- let out = 0;
- if (aStr < bStr) out = -1;
- if (aStr > bStr) out = 1;
- if (desc) out *= -1;
- return out;
- });
-
+ const docs = this._docs.filter(d => !draggedDocs.includes(d));
docs.splice(this.rowDropIndex, 0, ...draggedDocs);
return { docs };
}
+ @action
+ sortDocs = (docs: Doc[], field: string, desc: boolean) => {
+ docs = docs.sort((docA, docB) => {
+ // this sorts the documents based on the selected field. returning -1 for a before b, 0 for a = b, 1 for a > b
+ const aStr = Field.toString(docA[field] as FieldType);
+ const bStr = Field.toString(docB[field] as FieldType);
+ let out = 0;
+ if (aStr < bStr) out = -1;
+ if (aStr > bStr) out = 1;
+ if (desc) out *= -1;
+ return out;
+ });
+ }
+
rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight);
isContentActive = () => this._props.isSelected() || this._props.isContentActive();
screenToLocal = () => this.ScreenToLocalBoxXf().translate(-this.tableWidth, 0);
previewWidthFunc = () => this.previewWidth;
onPassiveWheel = (e: WheelEvent) => e.stopPropagation();
- displayedDocsFunc = () => this.sortedDocs.docs;
+ displayedDocsFunc = () => this.displayedDocs.docs;
_oldWheel: any;
render() {
return (
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index bda9fc9b7..dd4a13776 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -68,19 +68,6 @@ export class SchemaColumnHeader extends ObservableReactComponent<SchemaColumnHea
@action updateAlt = (newAlt: string) => {this._altTitle = newAlt;}
@action updateKeyDropdown = (value: string) => {this._props.schemaView.updateKeySearch(value)}
- @action
- sortClicked = (e: React.PointerEvent) => {
- e.stopPropagation();
- e.preventDefault();
- if (this._props.sortField === this.fieldKey && this._props.sortDesc) {
- this._props.setSort(undefined);
- } else if (this._props.sortField === this.fieldKey) {
- this._props.setSort(this.fieldKey, true);
- } else {
- this._props.setSort(this.fieldKey, false);
- }
- };
-
openKeyDropdown = () => {
this._props.schemaView.openColumnMenu(this._props.columnIndex, false)
}
@@ -190,9 +177,6 @@ export class SchemaColumnHeader extends ObservableReactComponent<SchemaColumnHea
<div className="schema-header-button" onPointerDown={e => this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex)}>
<FontAwesomeIcon icon="ellipsis-h" />
</div>
- <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this._props.sortField === this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
- <FontAwesomeIcon icon="caret-right" style={this._props.sortField === this.fieldKey ? { transform: `rotate(${this._props.sortDesc ? '270deg' : '90deg'})` } : {}} />
- </div>
</div>
</div>
);
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 099670022..665704de1 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -7,7 +7,7 @@ import { CgClose, CgLock, CgLockUnlock, CgMenu } from 'react-icons/cg';
import { FaExternalLinkAlt } from 'react-icons/fa';
import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
import { emptyFunction } from '../../../../Utils';
-import { Doc } from '../../../../fields/Doc';
+import { Doc, DocListCast } from '../../../../fields/Doc';
import { BoolCast } from '../../../../fields/Types';
import { Transform } from '../../../util/Transform';
import { undoable } from '../../../util/UndoManager';
@@ -73,13 +73,14 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
event: () => this._props.addDocTab(this.Document, OpenWhere.addRight),
icon: 'magnifying-glass',
});
- if (this.Document['type'] === 'collection') {
+ const childDocs = DocListCast(this.Document[Doc.LayoutFieldKey(this.Document)])
+ if (this.Document['type'] === 'collection' && childDocs.length) {
ContextMenu.Instance.addItem({
description: this.Document._childrenSharedWithSchema ? 'Remove children from schema' : 'Add children to schema',
event: () => {
this.Document._childrenSharedWithSchema = !this.Document._childrenSharedWithSchema;
this.Document._childrenSharedWithSchema ?
- this.schemaView.addDocsFromChildCollection(this.Document) : this.schemaView.removeChildCollectionDocs(this.Document);
+ this.schemaView.addDocsFromOtherCollection(childDocs) : this.schemaView.removeDocsFromOtherCollection(childDocs);
},
icon: this.Document._childrenSharedWithSchema ? 'minus' : 'plus',
});