mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Initial data tables page
Summary:
- Added a new special page for viewing raw data widgets:
- Implemented in DataTables.ts
- Accessible only via the special URL path `/p/data`
- Future diffs should make this page prettier and easily accessible
- Shows a list of user tables
- Clicking on a table name shows its `rawViewSection` by setting `GristDoc.viewModel.activeSectionId`. Note that in this case `GristDoc.viewModel` is an empty record, so this is a bit of a hack, but it works well and causes no known issues.
- Added `ViewSectionRec.isRaw` to know if the record represents a raw data widget.
- Added various restrictions in the UI for raw data widgets:
- 'Delete widget' is disabled in the 3-dot widget menu.
- Prevent hiding columns:
- "Hide column" in the column context menu is disabled
- The "VISIBLE/HIDDEN COLUMNS" section of the right panel > Table > Widget is hidden
- The toggle bar isn't configurable to ensure that users know when raw data is filtered:
- The filter bar always shows if and only if some filters are present
- "Toggle Filter Bar" is hidden in:
- Right panel > Table > Sort & Filter
- The sort/filter menu next to the three-dot menu for widgets.
- Other restrictions in the right panel:
- In the Column tab:
- 'Use separate settings' is disabled
- In the Table tab:
- In the Widget subtab:
- 'Change Widget' is hidden
- In the Data subtab:
- 'Edit Data Selection' is hidden
- 'SELECT BY' is hidden
Test Plan: Tested manually. The behaviour of raw data widgets may still change and they aren't easily visible to users yet.
Reviewers: georgegevoian
Reviewed By: georgegevoian
Differential Revision: https://phab.getgrist.com/D3248
This commit is contained in:
@@ -43,7 +43,7 @@ function getInstanceConstructor(parentKey: string) {
|
||||
return Cons || viewSectionTypes.record;
|
||||
}
|
||||
|
||||
class ViewSectionHelper extends Disposable {
|
||||
export class ViewSectionHelper extends Disposable {
|
||||
private _instance = Holder.create<BaseView>(this);
|
||||
|
||||
constructor(gristDoc: GristDoc, vs: ViewSectionRec) {
|
||||
@@ -183,49 +183,7 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent {
|
||||
}
|
||||
|
||||
private _buildLeafContent(sectionRowId: number) {
|
||||
// Creating normal section dom
|
||||
const vs: ViewSectionRec = this.docModel.viewSections.getRowModel(sectionRowId);
|
||||
return dom('div.view_leaf.viewsection_content.flexvbox.flexauto',
|
||||
testId(`viewlayout-section-${sectionRowId}`),
|
||||
|
||||
cssViewLeaf.cls(''),
|
||||
cssViewLeafInactive.cls('', (use) => !vs.isDisposed() && !use(vs.hasFocus)),
|
||||
dom.cls('active_section', vs.hasFocus),
|
||||
|
||||
dom.maybe<BaseView|null>((use) => use(vs.viewInstance), (viewInstance) => dom('div.viewsection_title.flexhbox',
|
||||
dom('span.viewsection_drag_indicator.glyphicon.glyphicon-option-vertical',
|
||||
// Makes element grabbable only if grist is not readonly.
|
||||
dom.cls('layout_grabbable', (use) => !use(this.gristDoc.isReadonlyKo))),
|
||||
dom.maybe((use) => use(use(viewInstance.viewSection.table).summarySourceTable), () =>
|
||||
cssSigmaIcon('Pivot', testId('sigma'))),
|
||||
dom('div.viewsection_titletext_container.flexitem.flexhbox',
|
||||
dom('span.viewsection_titletext', editableLabel(
|
||||
fromKo(vs.titleDef),
|
||||
(val) => vs.titleDef.saveOnly(val),
|
||||
testId('viewsection-title'),
|
||||
)),
|
||||
),
|
||||
viewInstance.buildTitleControls(),
|
||||
dom('span.viewsection_buttons',
|
||||
dom.create(viewSectionMenu, this.docModel, vs, this.viewModel, this.gristDoc.isReadonly)
|
||||
)
|
||||
)),
|
||||
dom.maybe(vs.activeFilterBar, () => dom.create(filterBar, vs)),
|
||||
dom.maybe<BaseView|null>(vs.viewInstance, (viewInstance) =>
|
||||
dom('div.view_data_pane_container.flexvbox',
|
||||
cssResizing.cls('', this._isResizing),
|
||||
dom.maybe(viewInstance.disableEditing, () =>
|
||||
dom('div.disable_viewpane.flexvbox', 'No data')
|
||||
),
|
||||
dom.maybe(viewInstance.isTruncated, () =>
|
||||
dom('div.viewsection_truncated', 'Not all data is shown')
|
||||
),
|
||||
dom.cls((use) => 'viewsection_type_' + use(vs.parentKey)),
|
||||
viewInstance.viewPane
|
||||
)
|
||||
),
|
||||
dom.on('mousedown', () => { this.viewModel.activeSectionId(sectionRowId); }),
|
||||
);
|
||||
return buildViewSectionDom(this.gristDoc, sectionRowId, this._isResizing, this.viewModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,3 +354,56 @@ const cssLayoutBox = styled('div', `
|
||||
const cssResizing = styled('div', `
|
||||
pointer-events: none;
|
||||
`);
|
||||
|
||||
|
||||
export function buildViewSectionDom(
|
||||
gristDoc: GristDoc,
|
||||
sectionRowId: number,
|
||||
isResizing: Observable<boolean> = Observable.create(null, false),
|
||||
viewModel?: ViewRec,
|
||||
) {
|
||||
// Creating normal section dom
|
||||
const vs: ViewSectionRec = gristDoc.docModel.viewSections.getRowModel(sectionRowId);
|
||||
return dom('div.view_leaf.viewsection_content.flexvbox.flexauto',
|
||||
testId(`viewlayout-section-${sectionRowId}`),
|
||||
|
||||
cssViewLeaf.cls(''),
|
||||
cssViewLeafInactive.cls('', (use) => !vs.isDisposed() && !use(vs.hasFocus)),
|
||||
dom.cls('active_section', vs.hasFocus),
|
||||
|
||||
dom.maybe<BaseView|null>((use) => use(vs.viewInstance), (viewInstance) => dom('div.viewsection_title.flexhbox',
|
||||
dom('span.viewsection_drag_indicator.glyphicon.glyphicon-option-vertical',
|
||||
// Makes element grabbable only if grist is not readonly.
|
||||
dom.cls('layout_grabbable', (use) => !use(gristDoc.isReadonlyKo))),
|
||||
dom.maybe((use) => use(use(viewInstance.viewSection.table).summarySourceTable), () =>
|
||||
cssSigmaIcon('Pivot', testId('sigma'))),
|
||||
dom('div.viewsection_titletext_container.flexitem.flexhbox',
|
||||
dom('span.viewsection_titletext', editableLabel(
|
||||
fromKo(vs.titleDef),
|
||||
(val) => vs.titleDef.saveOnly(val),
|
||||
testId('viewsection-title'),
|
||||
)),
|
||||
),
|
||||
viewInstance.buildTitleControls(),
|
||||
dom('span.viewsection_buttons',
|
||||
dom.create(viewSectionMenu, gristDoc.docModel, vs, gristDoc.isReadonly)
|
||||
)
|
||||
)),
|
||||
dom.maybe((use) => use(vs.activeFilterBar) || use(vs.isRaw) && use(vs.activeFilters).length,
|
||||
() => dom.create(filterBar, vs)),
|
||||
dom.maybe<BaseView|null>(vs.viewInstance, (viewInstance) =>
|
||||
dom('div.view_data_pane_container.flexvbox',
|
||||
cssResizing.cls('', isResizing),
|
||||
dom.maybe(viewInstance.disableEditing, () =>
|
||||
dom('div.disable_viewpane.flexvbox', 'No data')
|
||||
),
|
||||
dom.maybe(viewInstance.isTruncated, () =>
|
||||
dom('div.viewsection_truncated', 'Not all data is shown')
|
||||
),
|
||||
dom.cls((use) => 'viewsection_type_' + use(vs.parentKey)),
|
||||
viewInstance.viewPane
|
||||
)
|
||||
),
|
||||
dom.on('mousedown', () => { viewModel?.activeSectionId(sectionRowId); }),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user