mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Allow docs to be permanently deleted in icon view
Summary: Previously, soft-deleted docs in icon view were still accessible from the Trash and couldn't be permanently deleted. Test Plan: Improved the nbrowser test for deleting docs to verify that it can be done in both view modes. Reviewers: dsagal, paulfitz Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2862
This commit is contained in:
parent
30bbb6fa94
commit
3af6dd46ea
@ -200,7 +200,7 @@ function buildWorkspaceDocBlock(home: HomeModel, workspace: Workspace, flashDocI
|
|||||||
return dom.forEach(docs, doc => {
|
return dom.forEach(docs, doc => {
|
||||||
if (view === 'icons') {
|
if (view === 'icons') {
|
||||||
return dom.update(
|
return dom.update(
|
||||||
buildPinnedDoc(home, doc),
|
buildPinnedDoc(home, doc, workspace),
|
||||||
testId('doc'),
|
testId('doc'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -347,7 +347,7 @@ export function makeDocOptionsMenu(home: HomeModel, doc: Document, renaming: Obs
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeRemovedDocOptionsMenu(home: HomeModel, doc: Document, workspace: Workspace) {
|
export function makeRemovedDocOptionsMenu(home: HomeModel, doc: Document, workspace: Workspace) {
|
||||||
function hardDeleteDoc() {
|
function hardDeleteDoc() {
|
||||||
confirmModal(`Permanently Delete "${doc.name}"?`, 'Delete Forever',
|
confirmModal(`Permanently Delete "${doc.name}"?`, 'Delete Forever',
|
||||||
() => home.deleteDoc(doc.id, true).catch(reportError),
|
() => home.deleteDoc(doc.id, true).catch(reportError),
|
||||||
|
@ -103,15 +103,15 @@ function _buildExampleListDocs(home: HomeModel, workspace: Workspace, viewSettin
|
|||||||
testId('examples-desc'),
|
testId('examples-desc'),
|
||||||
),
|
),
|
||||||
dom.domComputed(viewSettings.currentView, (view) =>
|
dom.domComputed(viewSettings.currentView, (view) =>
|
||||||
dom.forEach(workspace.docs, doc => buildExampleItem(doc, home, view))
|
dom.forEach(workspace.docs, doc => buildExampleItem(doc, home, workspace, view))
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildExampleItem(doc: Document, home: HomeModel, view: 'list'|'icons') {
|
function buildExampleItem(doc: Document, home: HomeModel, workspace: Workspace, view: 'list'|'icons') {
|
||||||
const ex = examples.find((e) => e.matcher.test(doc.name));
|
const ex = examples.find((e) => e.matcher.test(doc.name));
|
||||||
if (view === 'icons') {
|
if (view === 'icons') {
|
||||||
return buildPinnedDoc(home, doc, ex);
|
return buildPinnedDoc(home, doc, workspace, ex);
|
||||||
} else {
|
} else {
|
||||||
return css.docRowWrapper(
|
return css.docRowWrapper(
|
||||||
cssDocRowLink(
|
cssDocRowLink(
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import {docUrl, urlState} from 'app/client/models/gristUrlState';
|
import {docUrl, urlState} from 'app/client/models/gristUrlState';
|
||||||
import {getTimeFromNow, HomeModel} from 'app/client/models/HomeModel';
|
import {getTimeFromNow, HomeModel} from 'app/client/models/HomeModel';
|
||||||
import {makeDocOptionsMenu} from 'app/client/ui/DocMenu';
|
import {makeDocOptionsMenu, makeRemovedDocOptionsMenu} from 'app/client/ui/DocMenu';
|
||||||
import {IExampleInfo} from 'app/client/ui/ExampleInfo';
|
import {IExampleInfo} from 'app/client/ui/ExampleInfo';
|
||||||
import {transientInput} from 'app/client/ui/transientInput';
|
import {transientInput} from 'app/client/ui/transientInput';
|
||||||
import {colors, vars} from 'app/client/ui2018/cssVars';
|
import {colors, vars} from 'app/client/ui2018/cssVars';
|
||||||
import {icon} from 'app/client/ui2018/icons';
|
import {icon} from 'app/client/ui2018/icons';
|
||||||
import {menu} from 'app/client/ui2018/menus';
|
import {menu} from 'app/client/ui2018/menus';
|
||||||
import * as roles from 'app/common/roles';
|
import * as roles from 'app/common/roles';
|
||||||
import {Document} from 'app/common/UserAPI';
|
import {Document, Workspace} from 'app/common/UserAPI';
|
||||||
import {computed, dom, makeTestId, observable, styled} from 'grainjs';
|
import {computed, dom, makeTestId, observable, styled} from 'grainjs';
|
||||||
|
|
||||||
const testId = makeTestId('test-dm-');
|
const testId = makeTestId('test-dm-');
|
||||||
@ -20,7 +20,7 @@ const testId = makeTestId('test-dm-');
|
|||||||
*/
|
*/
|
||||||
export function createPinnedDocs(home: HomeModel) {
|
export function createPinnedDocs(home: HomeModel) {
|
||||||
return pinnedDocList(
|
return pinnedDocList(
|
||||||
dom.forEach(home.currentWSPinnedDocs, doc => buildPinnedDoc(home, doc)),
|
dom.forEach(home.currentWSPinnedDocs, doc => buildPinnedDoc(home, doc, doc.workspace)),
|
||||||
testId('pinned-doc-list'),
|
testId('pinned-doc-list'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -29,7 +29,8 @@ export function createPinnedDocs(home: HomeModel) {
|
|||||||
* Build a single doc card with a preview and name. A misnomer because it's now used not only for
|
* Build a single doc card with a preview and name. A misnomer because it's now used not only for
|
||||||
* pinned docs, but also for the thumnbails (aka "icons") view mode.
|
* pinned docs, but also for the thumnbails (aka "icons") view mode.
|
||||||
*/
|
*/
|
||||||
export function buildPinnedDoc(home: HomeModel, doc: Document, example?: IExampleInfo): HTMLElement {
|
export function buildPinnedDoc(home: HomeModel, doc: Document, workspace: Workspace,
|
||||||
|
example?: IExampleInfo): HTMLElement {
|
||||||
const renaming = observable<Document|null>(null);
|
const renaming = observable<Document|null>(null);
|
||||||
const isRenamingDoc = computed((use) => use(renaming) === doc);
|
const isRenamingDoc = computed((use) => use(renaming) === doc);
|
||||||
const docTitle = example?.title || doc.name;
|
const docTitle = example?.title || doc.name;
|
||||||
@ -37,7 +38,7 @@ export function buildPinnedDoc(home: HomeModel, doc: Document, example?: IExampl
|
|||||||
dom.autoDispose(isRenamingDoc),
|
dom.autoDispose(isRenamingDoc),
|
||||||
dom.domComputed(isRenamingDoc, (isRenaming) =>
|
dom.domComputed(isRenamingDoc, (isRenaming) =>
|
||||||
pinnedDoc(
|
pinnedDoc(
|
||||||
isRenaming ? null : urlState().setLinkUrl(docUrl(doc)),
|
isRenaming || doc.removedAt ? null : urlState().setLinkUrl(docUrl(doc)),
|
||||||
pinnedDoc.cls('-no-access', !roles.canView(doc.access)),
|
pinnedDoc.cls('-no-access', !roles.canView(doc.access)),
|
||||||
pinnedDocPreview(
|
pinnedDocPreview(
|
||||||
example?.bgColor ? dom.style('background-color', example.bgColor) : null,
|
example?.bgColor ? dom.style('background-color', example.bgColor) : null,
|
||||||
@ -64,17 +65,27 @@ export function buildPinnedDoc(home: HomeModel, doc: Document, example?: IExampl
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
cssPinnedDocDesc(
|
cssPinnedDocDesc(
|
||||||
example?.desc || capitalizeFirst(getTimeFromNow(doc.updatedAt)),
|
example?.desc || capitalizeFirst(getTimeFromNow(doc.removedAt || doc.updatedAt)),
|
||||||
testId('pinned-doc-desc')
|
testId('pinned-doc-desc')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
example ? null : pinnedDocOptions(icon('Dots'),
|
example ? null : (doc.removedAt ?
|
||||||
menu(() => makeDocOptionsMenu(home, doc, renaming), {placement: 'bottom-start'}),
|
[
|
||||||
|
// For deleted documents, attach the menu to the entire doc icon, and include the
|
||||||
|
// "Dots" icon just to clarify that there are options.
|
||||||
|
menu(() => makeRemovedDocOptionsMenu(home, doc, workspace),
|
||||||
|
{placement: 'right-start'}),
|
||||||
|
pinnedDocOptions(icon('Dots'), testId('pinned-doc-options')),
|
||||||
|
] :
|
||||||
|
pinnedDocOptions(icon('Dots'),
|
||||||
|
menu(() => makeDocOptionsMenu(home, doc, renaming),
|
||||||
|
{placement: 'bottom-start'}),
|
||||||
// Clicks on the menu trigger shouldn't follow the link that it's contained in.
|
// Clicks on the menu trigger shouldn't follow the link that it's contained in.
|
||||||
dom.on('click', (ev) => { ev.stopPropagation(); ev.preventDefault(); }),
|
dom.on('click', (ev) => { ev.stopPropagation(); ev.preventDefault(); }),
|
||||||
testId('pinned-doc-options')
|
testId('pinned-doc-options'),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
testId('pinned-doc')
|
testId('pinned-doc')
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user